Annotation of embedaddon/libnet/src/libnet_link_snoop.c, revision 1.1.1.2
1.1 misho 1: /*
2: * $Id: libnet_link_snoop.c,v 1.5 2004/01/03 20:31:02 mike 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
1.1.1.2 ! misho 11: * The Regents of the University of California. All rights reserved.
1.1 misho 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>
1.1.1.2 ! misho 32: #include <netinet/in.h>
! 33: #include <netinet/udp.h>
! 34: #include <netinet/tcp.h>
1.1 misho 35:
36: #if (HAVE_CONFIG_H)
37: #include "../include/config.h"
38: #endif
39: #include "../include/libnet.h"
40:
41: #include <net/raw.h>
42: #include <net/if.h>
43:
44: #include <netinet/ip_var.h>
45: #include <netinet/if_ether.h>
46: #include <netinet/udp_var.h>
47: #include <netinet/tcpip.h>
48:
49: #include "../include/gnuc.h"
50: #include "../include/bpf.h"
51: #ifdef HAVE_OS_PROTO_H
52: #include "../include/os-proto.h"
53: #endif
54:
55:
1.1.1.2 ! misho 56: /**
! 57: *
! 58: */
! 59: int
! 60: libnet_open_link(libnet_t *l)
1.1 misho 61: {
62: int fd;
63: struct sockaddr_raw sr;
1.1.1.2 ! misho 64: uint v;
1.1 misho 65:
1.1.1.2 ! misho 66: if (l == NULL) {
! 67: return -1;
1.1 misho 68: }
1.1.1.2 ! misho 69:
1.1 misho 70: l->fd = socket(PF_RAW, SOCK_RAW, RAWPROTO_DRAIN);
1.1.1.2 ! misho 71:
! 72: if (l->fd < 0) {
! 73: sprintf(l->err_buf, "drain socket: %s", strerror(errno));
1.1 misho 74: goto bad;
75: }
76:
77: memset(&sr, 0, sizeof(sr));
78: sr.sr_family = AF_RAW;
1.1.1.2 ! misho 79: strncpy(sr.sr_ifname, l->device, sizeof(sr.sr_ifname) - 1);
! 80: sr.sr_ifname[sizeof(sr.sr_ifname) - 1] = '\0';
1.1 misho 81:
1.1.1.2 ! misho 82: if (bind(l->fd, (struct sockaddr *)&sr, sizeof(sr))) {
! 83: sprintf(l->err_buf, "drain bind: %s", strerror(errno));
1.1 misho 84: goto bad;
85: }
86:
87: /*
88: * XXX hack - map device name to link layer type
89: */
1.1.1.2 ! misho 90: if (strncmp("et", l->device, 2) == 0 || /* Challenge 10 Mbit */
! 91: strncmp("ec", l->device, 2) == 0 || /* Indigo/Indy 10 Mbit, O2 10/100 */
! 92: strncmp("ef", l->device, 2) == 0 || /* O200/2000 10/100 Mbit */
! 93: strncmp("gfe", l->device, 3) == 0 || /* GIO 100 Mbit */
! 94: strncmp("fxp", l->device, 3) == 0 || /* Challenge VME Enet */
! 95: strncmp("ep", l->device, 2) == 0 || /* Challenge 8x10 Mbit EPLEX */
! 96: strncmp("vfe", l->device, 3) == 0 || /* Challenge VME 100Mbit */
! 97: strncmp("fa", l->device, 2) == 0 ||
! 98: strncmp("qaa", l->device, 3) == 0) {
! 99: l->link_type = DLT_EN10MB;
! 100: }
! 101: else if (strncmp("ipg", l->device, 3) == 0 ||
! 102: strncmp("rns", l->device, 3) == 0 || /* O2/200/2000 FDDI */
! 103: strncmp("xpi", l->device, 3) == 0) {
! 104: l->link_type = DLT_FDDI;
! 105: }
! 106: else if (strncmp("ppp", l->device, 3) == 0) {
! 107: l->link_type = DLT_RAW;
! 108: } else if (strncmp("lo", l->device, 2) == 0) {
! 109: l->link_type = DLT_NULL;
! 110: } else {
! 111: sprintf(l->err_buf, "drain: unknown physical layer type");
! 112: goto bad;
1.1 misho 113: }
1.1.1.2 ! misho 114:
! 115: return 1;
! 116: bad:
! 117: close(fd);
! 118: free(l);
! 119: return -1;
1.1 misho 120: }
121:
122:
123: int
1.1.1.2 ! misho 124: libnet_close_link(libnet_t *l)
1.1 misho 125: {
126: if (close(l->fd) == 0)
127: {
128: return (1);
129: }
130: else
131: {
132: return (-1);
133: }
134: }
135:
136:
137: int
1.1.1.2 ! misho 138: libnet_write_link(libnet_t *l, const uint8_t *buf, uint32_t len)
1.1 misho 139: {
140: int c;
141: struct ifreq ifr;
142: struct ether_header *eh = (struct ether_header *)buf;
1.1.1.2 ! misho 143:
1.1 misho 144: memset(&ifr, 0, sizeof(ifr));
1.1.1.2 ! misho 145: strncpy(ifr.ifr_name, l->device, sizeof(ifr.ifr_name));
! 146:
1.1 misho 147: if (ioctl(l->fd, SIOCGIFADDR, &ifr) == -1)
148: {
149: perror("ioctl SIOCGIFADDR");
150: return (-1);
151: }
1.1.1.2 ! misho 152:
1.1 misho 153: memcpy(eh->ether_shost, ifr.ifr_addr.sa_data, sizeof(eh->ether_shost));
1.1.1.2 ! misho 154:
1.1 misho 155: if (write(l->fd, buf, len) == -1)
156: {
157: /* err */
158: return (-1);
159: }
160:
161: return (len);
162: }
1.1.1.2 ! misho 163:
! 164: struct libnet_ether_addr *
! 165: libnet_get_hwaddr(libnet_t *l)
! 166: {
! 167: struct ifreq ifdat;
! 168: int s = -1;
! 169: struct libnet_ether_addr *ea = NULL;
! 170:
! 171: if (-1 == (s = socket(PF_RAW, SOCK_RAW, RAWPROTO_SNOOP))) {
! 172: snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
! 173: "socket(): %s", strerror(errno));
! 174: goto errout;
! 175: }
! 176: memset(&ifdat, 0, sizeof(struct ifreq));
! 177: strncpy(ifdat.ifr_name, l->device, IFNAMSIZ);
! 178: if (ioctl(s, SIOCGIFADDR, &ifdat)) {
! 179: snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
! 180: "SIOCGIFADDR: %s", strerror(errno));
! 181: goto errout;
! 182: }
! 183: if (!(ea = malloc(sizeof(struct libnet_ether_addr)))) {
! 184: snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
! 185: "malloc(): %s", strerror(errno));
! 186: goto errout;
! 187: }
! 188: memcpy(ea, &ifdat.ifr_addr.sa_data, ETHER_ADDR_LEN);
! 189: close(s);
! 190: s = -1;
! 191: return ea;
! 192:
! 193: errout:
! 194: if (s > 0) {
! 195: close(s);
! 196: }
! 197: if (ea) {
! 198: free(ea);
! 199: ea = 0;
! 200: }
! 201: return 0;
! 202: }
! 203: /* ---- Emacs Variables ----
! 204: * Local Variables:
! 205: * c-basic-offset: 4
! 206: * indent-tabs-mode: nil
! 207: * End:
! 208: */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>