File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / libnet / src / libnet_link_snoop.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 22:14:23 2012 UTC (12 years, 5 months ago) by misho
Branches: libnet, MAIN
CVS tags: v1_1_2_1, HEAD
libnet

    1: /*
    2:  *  $Id: libnet_link_snoop.c,v 1.1.1.1 2012/02/21 22:14:23 misho Exp $
    3:  *
    4:  *  libnet
    5:  *  libnet_snoop.c - snoop routines
    6:  *
    7:  *  Copyright (c) 1998 - 2004 Mike D. Schiffman <mike@infonexus.com>
    8:  *  All rights reserved.
    9:  *
   10:  * Copyright (c) 1993, 1994, 1995, 1996, 1997
   11:  *	The Regents of the University of California.  All rights reserved.
   12:  *
   13:  * Redistribution and use in source and binary forms, with or without
   14:  * modification, are permitted provided that: (1) source code distributions
   15:  * retain the above copyright notice and this paragraph in its entirety, (2)
   16:  * distributions including binary code include the above copyright notice and
   17:  * this paragraph in its entirety in the documentation or other materials
   18:  * provided with the distribution, and (3) all advertising materials mentioning
   19:  * features or use of this software display the following acknowledgement:
   20:  * ``This product includes software developed by the University of California,
   21:  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
   22:  * the University nor the names of its contributors may be used to endorse
   23:  * or promote products derived from this software without specific prior
   24:  * written permission.
   25:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
   26:  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
   27:  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
   28:  */
   29: 
   30: #include <sys/param.h>
   31: #include <sys/file.h>
   32: 
   33: #if (HAVE_CONFIG_H)
   34: #include "../include/config.h"
   35: #endif
   36: #include "../include/libnet.h"
   37: 
   38: #include <net/raw.h>
   39: #include <net/if.h>
   40: 
   41: #include <netinet/ip_var.h>
   42: #include <netinet/if_ether.h>
   43: #include <netinet/udp_var.h>
   44: #include <netinet/tcpip.h>
   45: 
   46: #include "../include/gnuc.h"
   47: #include "../include/bpf.h"
   48: #ifdef HAVE_OS_PROTO_H
   49: #include "../include/os-proto.h"
   50: #endif
   51: 
   52: 
   53: struct libnet_link_int *
   54: libnet_open_link_interface(int8_t *device, int8_t *ebuf)
   55: {
   56:     int fd;
   57:     struct sockaddr_raw sr;
   58:     u_int v;
   59:     struct libnet_link_int *l;
   60: 
   61:     l = (struct libnet_link_int *)malloc(sizeof(*l));
   62:     if (l == NULL)
   63:     {
   64:         sprintf(ebuf, "malloc: %s", strerror(errno));
   65:         return (NULL);
   66:     }
   67:     memset(l, 0, sizeof(*l));
   68:     l->fd = socket(PF_RAW, SOCK_RAW, RAWPROTO_DRAIN);
   69:     if (l->fd < 0)
   70:     {
   71:         sprintf(ebuf, "drain socket: %s", strerror(errno));
   72:         goto bad;
   73:     }
   74: 
   75:     memset(&sr, 0, sizeof(sr));
   76:     sr.sr_family = AF_RAW;
   77:   	strncpy(sr.sr_ifname, device, sizeof(sr.sr_ifname) - 1);
   78:     sr.sr_name[sizeof(sr.sr_name) - 1] = '\0';
   79: 
   80:     if (bind(l->fd, (struct sockaddr *)&sr, sizeof(sr)))
   81:     {
   82:         sprintf(ebuf, "drain bind: %s", strerror(errno));
   83:         goto bad;
   84:     }
   85: 
   86:     /*
   87:      * XXX hack - map device name to link layer type
   88:      */
   89:     if (strncmp("et", device, 2) == 0      ||    /* Challenge 10 Mbit */
   90: 	    strncmp("ec", device, 2) == 0  ||    /* Indigo/Indy 10 Mbit, O2 10/100 */
   91:             strncmp("ef", device, 2) == 0 ||    /* O200/2000 10/100 Mbit */
   92:             strncmp("gfe", device, 3) == 0 ||   /* GIO 100 Mbit */
   93:             strncmp("fxp", device, 3) == 0 ||   /* Challenge VME Enet */
   94:             strncmp("ep", device, 2) == 0 ||    /* Challenge 8x10 Mbit EPLEX */
   95:             strncmp("vfe", device, 3) == 0 ||   /* Challenge VME 100Mbit */
   96:             strncmp("fa", device, 2) == 0 ||
   97:             strncmp("qaa", device, 3) == 0)
   98:     {
   99:         l->linktype = DLT_EN10MB;
  100:     }
  101:     else if (strncmp("ipg", device, 3) == 0 ||
  102:             strncmp("rns", device, 3) == 0 ||	/* O2/200/2000 FDDI */
  103:             strncmp("xpi", device, 3) == 0)
  104:         {
  105:             l->linktype = DLT_FDDI;
  106: 	}
  107:     else if (strncmp("ppp", device, 3) == 0) {
  108: 		l->linktype = DLT_RAW;
  109: 	} else if (strncmp("lo", device, 2) == 0) {
  110: 		l->linktype = DLT_NULL;
  111: 	} else {
  112: 		sprintf(ebuf, "drain: unknown physical layer type");
  113: 		goto bad;
  114: 	}
  115: 
  116: 	return (l);
  117:  bad:
  118: 	close(fd);
  119: 	free(l);
  120: 	return (NULL);
  121: }
  122: 
  123: 
  124: int
  125: libnet_close_link_interface(struct libnet_link_int *l)
  126: {
  127:     if (close(l->fd) == 0)
  128:     {
  129:         free(l);
  130:         return (1);
  131:     }
  132:     else
  133:     {
  134:         free(l);
  135:         return (-1);
  136:     }
  137: }
  138: 
  139: 
  140: int
  141: libnet_write_link_layer(struct libnet_link_int *l, const int8_t *device,
  142:             u_int8_t *buf, int len)
  143: {
  144:     int c;
  145:     struct ifreq ifr;
  146:     struct ether_header *eh = (struct ether_header *)buf;
  147:   
  148:     memset(&ifr, 0, sizeof(ifr));
  149:     strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
  150:   
  151:     if (ioctl(l->fd, SIOCGIFADDR, &ifr) == -1)
  152:     {
  153:         perror("ioctl SIOCGIFADDR");
  154:         return (-1);
  155:     }
  156:   
  157:     memcpy(eh->ether_shost, ifr.ifr_addr.sa_data, sizeof(eh->ether_shost));
  158:   
  159:     if (write(l->fd, buf, len) == -1)
  160:     {
  161:         /* err */
  162:         return (-1);
  163:     }
  164: 
  165:     return (len);
  166: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>