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