]> The Tcpdump Group git mirrors - libpcap/blob - pcap-linux.c
d5e4f53d31df14ec8c37e5232916bd0a885b7ba4
[libpcap] / pcap-linux.c
1 /*
2 * pcap-linux.c: Packet capture interface to the Linux kernel
3 *
4 * Copyright (c) 2000 Torsten Landschoff <torsten@debian.org>
5 * Sebastian Krahmer <krahmer@cs.uni-potsdam.de>
6 *
7 * License: BSD
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 * 3. The names of the authors may not be used to endorse or promote
20 * products derived from this software without specific prior
21 * written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
24 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
25 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
26 */
27 #ifndef lint
28 static const char rcsid[] =
29 "@(#) $Header: /tcpdump/master/libpcap/pcap-linux.c,v 1.38 2000-10-25 07:46:50 guy Exp $ (LBL)";
30 #endif
31
32 /*
33 * Known problems with 2.0[.x] kernels:
34 *
35 * - The loopback device gives every packet twice; on 2.2[.x] kernels,
36 * if we use PF_PACKET, we can filter out the transmitted version
37 * of the packet by using data in the "sockaddr_ll" returned by
38 * "recvfrom()", but, on 2.0[.x] kernels, we have to use
39 * PF_INET/SOCK_PACKET, which means "recvfrom()" supplies a
40 * "sockaddr_pkt" which doesn't give us enough information to let
41 * us do that.
42 *
43 * - We have to set the interface's IFF_PROMISC flag ourselves, if
44 * we're to run in promiscuous mode, which means we have to turn
45 * it off ourselves when we're done; the kernel doesn't keep track
46 * of how many sockets are listening promiscuously, which means
47 * it won't get turned off automatically when no sockets are
48 * listening promiscuously. We'd have to catch "pcap_close()"
49 * and restore the value the promiscuous flag had when we opened
50 * the device - which may not be the value it should have, if
51 * another socket also requested promiscuous mode between the time
52 * when we opened the socket and the time when we close the socket.
53 * We currently just punt, printing a warning and hinting that the
54 * user should upgrade to a 2.2 or later kernel.
55 */
56
57
58 #ifdef HAVE_CONFIG_H
59 #include "config.h"
60 #endif
61
62 #include "pcap-int.h"
63
64 #include <errno.h>
65 #include <stdlib.h>
66 #include <unistd.h>
67 #include <fcntl.h>
68 #include <string.h>
69 #include <sys/socket.h>
70 #include <sys/ioctl.h>
71 #include <net/if.h>
72 #include <netinet/in.h>
73 #include <linux/if_ether.h>
74 #include <netinet/if_ether.h>
75
76 #ifdef HAVE_NETPACKET_PACKET_H
77 #include <netpacket/packet.h>
78 #endif
79 #ifdef SO_ATTACH_FILTER
80 #include <linux/types.h>
81 #include <linux/filter.h>
82 #endif
83
84 #ifndef __GLIBC__
85 typedef int socklen_t;
86 #endif
87
88 #ifndef MSG_TRUNC
89 #define MSG_TRUNC 0
90 #endif
91
92 #define MAX_LINKHEADER_SIZE 256
93
94 /*
95 * When capturing on all interfaces we use this as the buffer size.
96 * Should be bigger then all MTUs that occur in real life.
97 * 64kB should be enough for now.
98 */
99 #define BIGGER_THAN_ALL_MTUS (64*1024)
100
101 /*
102 * Prototypes for internal functions
103 */
104 static int map_arphrd_to_dlt(int arptype );
105 static int live_open_old(pcap_t *, char *, int, int, char *);
106 static int live_open_new(pcap_t *, char *, int, int, char *);
107 static int pcap_read_packet(pcap_t *, pcap_handler, u_char *);
108
109 /*
110 * Wrap some ioctl calls
111 */
112 #ifdef HAVE_NETPACKET_PACKET_H
113 static int iface_get_id(int fd, const char *device, char *ebuf);
114 #endif
115 static int iface_get_mtu(int fd, const char *device, char *ebuf);
116 static int iface_get_arptype(int fd, const char *device, char *ebuf);
117 #ifdef HAVE_NETPACKET_PACKET_H
118 static int iface_bind(int fd, int ifindex, char *ebuf);
119 #endif
120 static int iface_bind_old(int fd, const char *device, char *ebuf);
121
122 /*
123 * Get a handle for a live capture from the given device. You can
124 * pass NULL as device to get all packages (without link level
125 * information of course). If you pass 1 as promisc the interface
126 * will be set to promiscous mode (XXX: I think this usage should
127 * be deprecated and functions be added to select that later allow
128 * modification of that values -- Torsten).
129 *
130 * See also pcap(3).
131 */
132 pcap_t *
133 pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
134 {
135 /* Allocate a handle for this session. */
136
137 pcap_t *handle = malloc(sizeof(*handle));
138 if (handle == NULL) {
139 snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
140 pcap_strerror(errno));
141 return NULL;
142 }
143
144 /* Initialize some components of the pcap structure. */
145
146 memset(handle, 0, sizeof(*handle));
147 handle->snapshot = snaplen;
148 handle->md.timeout = to_ms;
149 handle->md.promisc = promisc;
150
151 /*
152 * NULL and "any" are special devices which give us the hint to
153 * monitor all devices.
154 */
155 if (!device || strcmp(device, "any") == 0) {
156 device = NULL;
157 handle->md.device = strdup("any");
158 } else
159 handle->md.device = strdup(device);
160
161 if (handle->md.device == NULL) {
162 snprintf(ebuf, PCAP_ERRBUF_SIZE, "strdup: %s",
163 pcap_strerror(errno) );
164 free(handle);
165 return NULL;
166 }
167
168 /*
169 * Current Linux kernels use the protocol family PF_PACKET to
170 * allow direct access to all packets on the network while
171 * older kernels had a special socket type SOCK_PACKET to
172 * implement this feature.
173 * While this old implementation is kind of obsolete we need
174 * to be compatible with older kernels for a while so we are
175 * trying both methods with the newer method preferred.
176 */
177
178 if (! (live_open_new(handle, device, promisc, to_ms, ebuf) ||
179 live_open_old(handle, device, promisc, to_ms, ebuf)) )
180 {
181 /*
182 * Both methods to open the packet socket failed. Tidy
183 * up and report our failure (ebuf is expected to be
184 * set by the functions above).
185 */
186
187 free(handle->md.device);
188 free(handle);
189 return NULL;
190 }
191
192 /*
193 * Okay, now we have a packet stream open. Maybe we need to handle
194 * a timeout? In that case we set the filehandle to nonblocking
195 * so pcap_read can try reading the fd and call select if no data
196 * is available at first.
197 */
198
199 if (to_ms > 0) {
200 int flags = fcntl(handle->fd, F_GETFL);
201 if (flags != -1) {
202 flags |= O_NONBLOCK;
203 flags = fcntl(handle->fd, F_SETFL, flags);
204 }
205 if (flags == -1) {
206 snprintf(ebuf, PCAP_ERRBUF_SIZE, "fcntl: %s",
207 pcap_strerror(errno));
208 pcap_close(handle);
209 return NULL;
210 }
211 }
212
213 return handle;
214 }
215
216 /*
217 * Read at most max_packets from the capture stream and call the callback
218 * for each of them. Returns the number of packets handled or -1 if an
219 * error occured.
220 *
221 * XXX: Can I rely on the Linux-specified behaviour of select (returning
222 * the time left in the timeval structure)? I really don't want to query
223 * the system time before each select call...
224 *
225 * pcap_read currently gets not only a packet from the kernel but also
226 * the sockaddr_ll returned as source of the packet. This way we can at
227 * some time extend tcpdump and libpcap to sniff on all devices at a time
228 * and find the right printing routine by using the information in the
229 * sockaddr_ll structure.
230 */
231 int
232 pcap_read(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user)
233 {
234 int status, packets;
235 fd_set read_fds;
236 struct timeval tv;
237
238 /*
239 * Fill in a timeval structure for select if we need to obeye a
240 * timeout.
241 */
242 if (handle->md.timeout > 0) {
243 tv.tv_usec = (handle->md.timeout % 1000) * 1000;
244 tv.tv_sec = (handle->md.timeout / 1000);
245 }
246
247 /*
248 * Read packets until the packet limit has been reached or
249 * an error occured while reading. Call the user function
250 * for each received packet.
251 */
252 for (packets = 0; max_packets == -1 || packets < max_packets;)
253 {
254 status = pcap_read_packet(handle, callback, user);
255
256 if (status > 0) {
257 packets += status;
258 continue;
259 } else if (status == -1)
260 return -1;
261
262 /*
263 * If no packet is available we go to sleep. FIXME: This
264 * might be better implemented using poll(?)
265 */
266 FD_ZERO(&read_fds);
267 FD_SET(handle->fd, &read_fds);
268 status = select(handle->fd + 1,
269 &read_fds, NULL, NULL, &tv);
270
271 if (status == -1) {
272 if (errno == EINTR)
273 return packets;
274 snprintf(handle->errbuf, sizeof(handle->errbuf),
275 "select: %s", pcap_strerror(errno));
276 return -1;
277 }
278 else if (status == 0 ||
279 (tv.tv_usec == 0 && tv.tv_sec == 0))
280 return packets;
281 }
282
283 return packets;
284 }
285
286 /*
287 * Read a packet from the socket calling the handler provided by
288 * the user. Returns the number of packets received or -1 if an
289 * error occured.
290 */
291 static int
292 pcap_read_packet(pcap_t *handle, pcap_handler callback, u_char *userdata)
293 {
294 #ifdef HAVE_NETPACKET_PACKET_H
295 struct sockaddr_ll from;
296 #else
297 struct sockaddr from;
298 #endif
299 socklen_t fromlen;
300 int packet_len, caplen;
301 struct pcap_pkthdr pcap_header;
302
303 /*
304 * We don't currently use the from return value of recvfrom but
305 * this will probably be implemented in the future.
306 */
307
308 /* Receive a single packet from the kernel */
309
310 do {
311 fromlen = sizeof(from);
312 packet_len = recvfrom(
313 handle->fd, handle->buffer + handle->offset,
314 handle->snapshot, MSG_TRUNC,
315 (struct sockaddr *) &from, &fromlen);
316 } while (packet_len == -1 && errno == EINTR);
317
318 /* Check if an error occured */
319
320 if (packet_len == -1) {
321 if (errno == EAGAIN)
322 return 0; /* no packet there */
323 else {
324 snprintf(handle->errbuf, sizeof(handle->errbuf),
325 "recvfrom: %s", pcap_strerror(errno));
326 return -1;
327 }
328 }
329
330 #ifdef HAVE_NETPACKET_PACKET_H
331 /*
332 * If this is from the loopback device, reject outgoing packets;
333 * we'll see the packet as an incoming packet as well, and
334 * we don't want to see it twice.
335 *
336 * We can only do this if we're using PF_PACKET; the address
337 * returned for SOCK_PACKET is a "sockaddr_pkt" which lacks
338 * the relevant packet type information.
339 */
340 if (!handle->md.sock_packet &&
341 from.sll_ifindex == handle->md.lo_ifindex &&
342 from.sll_pkttype == PACKET_OUTGOING)
343 return 0;
344 #endif
345
346 /*
347 * XXX: According to the kernel source we should get the real
348 * packet len if calling recvfrom with MSG_TRUNC set. It does
349 * not seem to work here :(, but it is supported by this code
350 * anyway.
351 * To be honest the code RELIES on that feature so this is really
352 * broken with 2.2.x kernels.
353 * I spend a day to figure out what's going on and I found out
354 * that the following is happening:
355 *
356 * The packet comes from a random interface and the packet_rcv
357 * hook is called with a clone of the packet. That code inserts
358 * the packet into the receive queue of the packet socket.
359 * If a filter is attached to that socket that filter is run
360 * first - and there lies the problem. The default filter always
361 * cuts the packet at the snaplen:
362 *
363 * # tcpdump -d
364 * (000) ret #68
365 *
366 * So the packet filter cuts down the packet. The recvfrom call
367 * says "hey, it's only 68 bytes, it fits into the buffer" with
368 * the result that we don't get the real packet length. This
369 * is valid at least until kernel 2.2.17pre6.
370 *
371 * tcpdump is currently fixed by changing the BPF code generator
372 * to not truncate the received packet.
373 */
374
375 caplen = packet_len;
376 if (caplen > handle->snapshot)
377 caplen = handle->snapshot;
378
379 /* Run the packet filter if not using kernel filter */
380 if (!handle->md.use_bpf && handle->fcode.bf_insns) {
381 if (bpf_filter(handle->fcode.bf_insns, handle->buffer,
382 packet_len, caplen) == 0)
383 {
384 /* rejected by filter */
385 return 0;
386 }
387 }
388
389 /* Fill in our own header data */
390
391 if (ioctl(handle->fd, SIOCGSTAMP, &pcap_header.ts) == -1) {
392 snprintf(handle->errbuf, sizeof(handle->errbuf),
393 "ioctl: %s", pcap_strerror(errno));
394 return -1;
395 }
396 pcap_header.caplen = caplen;
397 pcap_header.len = packet_len;
398
399 /* Call the user supplied callback function */
400 handle->md.stat.ps_recv++;
401 callback(userdata, &pcap_header, handle->buffer + handle->offset);
402
403 return 1;
404 }
405
406 /*
407 * Get the statistics for the given packet capture handle.
408 * FIXME: Currently does not report the number of dropped packets.
409 */
410 int
411 pcap_stats(pcap_t *handle, struct pcap_stat *stats)
412 {
413 *stats = handle->md.stat;
414 return 0;
415 }
416
417 /*
418 * Attach the given BPF code to the packet capture device.
419 */
420 int
421 pcap_setfilter(pcap_t *handle, struct bpf_program *filter)
422 {
423 #ifdef SO_ATTACH_FILTER
424 struct sock_fprog fcode;
425 #endif
426
427 if (!handle)
428 return -1;
429 if (!filter) {
430 strncpy(handle->errbuf, "setfilter: No filter specified",
431 sizeof(handle->errbuf));
432 return -1;
433 }
434
435 /* Free old filter code if existing */
436
437 pcap_freecode(handle, &handle->fcode);
438
439 /* Make our private copy of the filter */
440
441 handle->fcode.bf_len = filter->bf_len;
442 handle->fcode.bf_insns =
443 malloc(filter->bf_len * sizeof(*filter->bf_insns));
444 if (handle->fcode.bf_insns == NULL) {
445 snprintf(handle->errbuf, sizeof(handle->errbuf),
446 "malloc: %s", pcap_strerror(errno));
447 return -1;
448 }
449 memcpy(handle->fcode.bf_insns, filter->bf_insns,
450 filter->bf_len * sizeof(*filter->bf_insns));
451
452 /*
453 * Run user level packet filter by default. Will be overriden if
454 * installing a kernel filter succeeds.
455 */
456 handle->md.use_bpf = 0;
457
458 /*
459 * If we're reading from a savefile, don't try to install
460 * a kernel filter.
461 */
462 if (handle->sf.rfile != NULL)
463 return 0;
464
465 /* Install kernel level filter if possible */
466
467 #ifdef SO_ATTACH_FILTER
468 /*
469 * Oh joy, the Linux kernel uses struct sock_fprog instead of
470 * struct bpf_program and of course the length field is of
471 * different size. Pointed out by Sebastian
472 */
473
474 fcode.filter = (struct sock_filter *) handle->fcode.bf_insns;
475 fcode.len = filter->bf_len;
476 #ifdef USHRT_MAX
477 if (filter->bf_len > USHRT_MAX) {
478 /*
479 * fcode.len is an unsigned short for current kernel.
480 * I have yet to see BPF-Code with that much instructions
481 * but still it is possible. So for the sake of
482 * correctness I added this check.
483 */
484 fprintf(stderr, "Warning: Filter to complex for kernel\n");
485 }
486 else
487 #endif
488 if (setsockopt(handle->fd, SOL_SOCKET, SO_ATTACH_FILTER,
489 &fcode, sizeof(fcode)) == 0)
490 {
491 /* Installation succeded - using kernel filter. */
492 handle->md.use_bpf = 1;
493 }
494 else
495 {
496 /*
497 * Print a warning if kernel filter available but a problem
498 * occured using it.
499 */
500 if (errno != ENOPROTOOPT && errno != EOPNOTSUPP) {
501 fprintf(stderr, "Warning: Kernel filter failed: %s\n",
502 pcap_strerror(errno));
503 }
504 }
505 #endif
506
507 return 0;
508 }
509
510 /*
511 * Linux uses the ARP hardware type to identify the type of an
512 * interface. pcap uses the DLT_xxx constants for this. This
513 * function maps the ARPHRD_xxx constant to an appropriate
514 * DLT_xxx constant.
515 *
516 * Returns -1 if unable to map the type.
517 */
518 static int map_arphrd_to_dlt(int arptype)
519 {
520 switch (arptype) {
521 case ARPHRD_ETHER:
522 case ARPHRD_METRICOM:
523 case ARPHRD_LOOPBACK: return DLT_EN10MB;
524 case ARPHRD_EETHER: return DLT_EN3MB;
525 case ARPHRD_AX25: return DLT_AX25;
526 case ARPHRD_PRONET: return DLT_PRONET;
527 case ARPHRD_CHAOS: return DLT_CHAOS;
528 case ARPHRD_IEEE802: return DLT_IEEE802;
529 case ARPHRD_ARCNET: return DLT_ARCNET;
530 case ARPHRD_FDDI: return DLT_FDDI;
531
532 #ifndef ARPHRD_ATM /* FIXME: How to #include this? */
533 #define ARPHRD_ATM 19
534 #endif
535 case ARPHRD_ATM: return DLT_ATM_CLIP;
536
537 case ARPHRD_PPP:
538 case ARPHRD_CSLIP:
539 case ARPHRD_SLIP6:
540 case ARPHRD_CSLIP6:
541 case ARPHRD_SLIP: return DLT_RAW;
542 }
543
544 return -1;
545 }
546
547 /* ===== Functions to interface to the newer kernels ================== */
548
549 /*
550 * Try to open a packet socket using the new kernel interface.
551 * Returns 0 on failure.
552 * FIXME: 0 uses to mean success (Sebastian)
553 */
554 static int
555 live_open_new(pcap_t *handle, char *device, int promisc,
556 int to_ms, char *ebuf)
557 {
558 #ifdef HAVE_NETPACKET_PACKET_H
559 int sock_fd = -1, device_id, mtu, arptype;
560 struct packet_mreq mr;
561
562 /* One shot loop used for error handling - bail out with break */
563
564 do {
565 /*
566 * Open a socket with protocol family packet. If a device is
567 * given we try to open it in raw mode otherwise we use
568 * the cooked interface.
569 */
570 sock_fd = device ?
571 socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))
572 : socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_ALL));
573
574 if (sock_fd == -1) {
575 snprintf(ebuf, PCAP_ERRBUF_SIZE, "socket: %s",
576 pcap_strerror(errno) );
577 break;
578 }
579
580 /* It seems the kernel supports the new interface. */
581 handle->md.sock_packet = 0;
582
583 /*
584 * Get the interface index of the loopback device.
585 * If the attempt fails, don't fail, just set the
586 * "md.lo_ifindex" to -1.
587 *
588 * XXX - can there be more than one device that loops
589 * packets back, i.e. devices other than "lo"? If so,
590 * we'd need to find them all, and have an array of
591 * indices for them, and check all of them in
592 * "pcap_read_packet()".
593 */
594 handle->md.lo_ifindex = iface_get_id(sock_fd, "lo", ebuf);
595
596 /*
597 * What kind of frames do we have to deal with? Fall back
598 * to cooked mode if we have an unknown interface type.
599 */
600
601 if (device) {
602 arptype = iface_get_arptype(sock_fd, device, ebuf);
603 if (arptype == -1)
604 break;
605 handle->linktype = map_arphrd_to_dlt(arptype);
606 if (handle->linktype == -1) {
607 /*
608 * Unknown interface type - reopen in cooked
609 * mode.
610 */
611 if (close(sock_fd) == -1) {
612 snprintf(ebuf, PCAP_ERRBUF_SIZE,
613 "close: %s", pcap_strerror(errno));
614 break;
615 }
616 sock_fd = socket(PF_PACKET, SOCK_DGRAM,
617 htons(ETH_P_ALL));
618 if (sock_fd == -1) {
619 snprintf(ebuf, PCAP_ERRBUF_SIZE,
620 "socket: %s", pcap_strerror(errno));
621 break;
622 }
623
624 fprintf(stderr,
625 "Warning: arptype %d not supported by "
626 "libpcap - falling back to cooked "
627 "socket\n",
628 arptype);
629 handle->linktype = DLT_RAW;
630 }
631
632 device_id = iface_get_id(sock_fd, device, ebuf);
633 if (device_id == -1)
634 break;
635
636 if (iface_bind(sock_fd, device_id, ebuf) == -1)
637 break;
638 } else {
639 handle->linktype = DLT_RAW;
640
641 /*
642 * XXX - squelch GCC complaints about
643 * uninitialized variables; if we can't
644 * select promiscuous mode on all interfaces,
645 * we should move the code below into the
646 * "if (device)" branch of the "if" and
647 * get rid of the next statement.
648 */
649 device_id = -1;
650 }
651
652 /* Select promiscuous mode on/off */
653
654 #ifdef SOL_PACKET
655 /*
656 * Hmm, how can we set promiscuous mode on all interfaces?
657 * I am not sure if that is possible at all.
658 */
659
660 if (device) {
661 memset(&mr, 0, sizeof(mr));
662 mr.mr_ifindex = device_id;
663 mr.mr_type = promisc ?
664 PACKET_MR_PROMISC : PACKET_MR_ALLMULTI;
665 if (setsockopt(sock_fd, SOL_PACKET,
666 PACKET_ADD_MEMBERSHIP, &mr, sizeof(mr)) == -1)
667 {
668 snprintf(ebuf, PCAP_ERRBUF_SIZE,
669 "setsockopt: %s", pcap_strerror(errno));
670 break;
671 }
672 }
673 #endif
674
675 /* Compute the buffersize */
676
677 mtu = iface_get_mtu(sock_fd, device, ebuf);
678 if (mtu == -1)
679 break;
680 handle->bufsize = MAX_LINKHEADER_SIZE + mtu;
681
682 /* Fill in the pcap structure */
683
684 handle->fd = sock_fd;
685 handle->offset = 0;
686
687 handle->buffer = malloc(handle->bufsize);
688 if (!handle->buffer) {
689 snprintf(ebuf, PCAP_ERRBUF_SIZE,
690 "malloc: %s", pcap_strerror(errno));
691 break;
692 }
693
694 return 1;
695
696 } while(0);
697
698 if (sock_fd != -1)
699 close(sock_fd);
700 return 0;
701 #else
702 strncpy(ebuf,
703 "New packet capturing interface not supported by build "
704 "environment", PCAP_ERRBUF_SIZE);
705 return 0;
706 #endif
707 }
708
709 #ifdef HAVE_NETPACKET_PACKET_H
710 /*
711 * Return the index of the given device name. Fill ebuf and return
712 * -1 on failure.
713 */
714 static int
715 iface_get_id(int fd, const char *device, char *ebuf)
716 {
717 struct ifreq ifr;
718
719 memset(&ifr, 0, sizeof(ifr));
720 strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
721
722 if (ioctl(fd, SIOCGIFINDEX, &ifr) == -1) {
723 snprintf(ebuf, PCAP_ERRBUF_SIZE,
724 "ioctl: %s", pcap_strerror(errno));
725 return -1;
726 }
727
728 return ifr.ifr_ifindex;
729 }
730
731 /*
732 * Bind the socket associated with FD to the given device.
733 */
734 static int
735 iface_bind(int fd, int ifindex, char *ebuf)
736 {
737 struct sockaddr_ll sll;
738
739 memset(&sll, 0, sizeof(sll));
740 sll.sll_family = AF_PACKET;
741 sll.sll_ifindex = ifindex;
742 sll.sll_protocol = htons(ETH_P_ALL);
743
744 if (bind(fd, (struct sockaddr *) &sll, sizeof(sll)) == -1) {
745 snprintf(ebuf, PCAP_ERRBUF_SIZE,
746 "bind: %s", pcap_strerror(errno));
747 return -1;
748 }
749
750 return 0;
751 }
752
753 #endif
754
755
756 /* ===== Functions to interface to the older kernels ================== */
757
758 /*
759 * With older kernels promiscuous mode is kind of interesting because we
760 * have to reset the interface before exiting. The problem can't really
761 * be solved without some daemon taking care of managing usage counts.
762 * We save the promiscuous state of the device when opening the capture
763 * stream and arrange for it to be reset on process exit.
764 *
765 * XXX: This solution is still not correct even for this case. The
766 * devices stay in promiscuous mode until the process exits. I need to
767 * modify pcap_close to solve this.
768 */
769
770 /*
771 * The device name and the interface flags to be restored at exit
772 */
773 struct ifreq restore_ifr;
774
775 static void restore_interface( void )
776 {
777 int status = socket(PF_INET, SOCK_PACKET, 0);
778
779 if (status != -1)
780 status = ioctl(status, SIOCSIFFLAGS, &restore_ifr);
781
782 if (status == -1) {
783 fprintf(stderr,
784 "Can't restore interface flags. Please adjust manually. \n"
785 "Hint: This can't happen with Linux >= 2.2.0.\n");
786 }
787 }
788
789 /*
790 * Try to open a packet socket using the old kernel interface.
791 * Returns 0 on failure.
792 * FIXME: 0 uses to mean success (Sebastian)
793 */
794 static int
795 live_open_old(pcap_t *handle, char *device, int promisc,
796 int to_ms, char *ebuf)
797 {
798 int sock_fd = -1, mtu, arptype;
799 struct ifreq ifr;
800
801 do {
802 /* Open the socket */
803
804 sock_fd = socket(PF_INET, SOCK_PACKET, htons(ETH_P_ALL));
805 if (sock_fd == -1) {
806 snprintf(ebuf, PCAP_ERRBUF_SIZE,
807 "socket: %s", pcap_strerror(errno));
808 break;
809 }
810
811 /* It worked - we are using the old interface */
812 handle->md.sock_packet = 1;
813
814 /* Bind to the given device */
815
816 if (!device) {
817 strncpy(ebuf, "pcap_open_live: No interface given",
818 PCAP_ERRBUF_SIZE);
819 break;
820 }
821 if (iface_bind_old(sock_fd, device, ebuf) == -1)
822 break;
823
824 /* Go to promisc mode */
825 if (promisc) {
826 memset(&ifr, 0, sizeof(ifr));
827 strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
828 if (ioctl(sock_fd, SIOCGIFFLAGS, &ifr) == -1) {
829 snprintf(ebuf, PCAP_ERRBUF_SIZE,
830 "ioctl: %s", pcap_strerror(errno));
831 break;
832 }
833 if ((ifr.ifr_flags & IFF_PROMISC) == 0) {
834 restore_ifr = ifr;
835 ifr.ifr_flags |= IFF_PROMISC;
836 if (ioctl(sock_fd, SIOCSIFFLAGS, &ifr) == -1) {
837 snprintf(ebuf, PCAP_ERRBUF_SIZE,
838 "ioctl: %s",
839 pcap_strerror(errno));
840 break;
841 }
842 if (atexit(restore_interface) == -1) {
843 restore_interface();
844 strncpy(ebuf, "atexit failed",
845 PCAP_ERRBUF_SIZE);
846 break;
847 }
848 }
849 }
850
851 /* Compute the buffersize */
852
853 mtu = iface_get_mtu(sock_fd, device, ebuf);
854 if (mtu == -1)
855 break;
856 handle->bufsize = MAX_LINKHEADER_SIZE + mtu;
857 if (handle->bufsize < handle->snapshot)
858 handle->bufsize = handle->snapshot;
859
860 /* All done - fill in the pcap handle */
861
862 arptype = iface_get_arptype(sock_fd, device, ebuf);
863 if (arptype == -1)
864 break;
865
866 handle->fd = sock_fd;
867 handle->offset = 0;
868 handle->linktype = map_arphrd_to_dlt(arptype);
869 if (handle->linktype == -1) {
870 snprintf(ebuf, PCAP_ERRBUF_SIZE,
871 "interface type of %s not supported", device);
872 break;
873 }
874 handle->buffer = malloc(handle->bufsize);
875 if (!handle->buffer) {
876 snprintf(ebuf, PCAP_ERRBUF_SIZE,
877 "malloc: %s", pcap_strerror(errno));
878 break;
879 }
880
881 return 1;
882
883 } while (0);
884
885 if (sock_fd != -1)
886 close(sock_fd);
887 return 0;
888 }
889
890 /*
891 * Bind the socket associated with FD to the given device using the
892 * interface of the old kernels.
893 */
894 static int
895 iface_bind_old(int fd, const char *device, char *ebuf)
896 {
897 struct sockaddr saddr;
898
899 memset(&saddr, 0, sizeof(saddr));
900 strncpy(saddr.sa_data, device, sizeof(saddr.sa_data));
901 if (bind(fd, &saddr, sizeof(saddr)) == -1) {
902 snprintf(ebuf, PCAP_ERRBUF_SIZE,
903 "bind: %s", pcap_strerror(errno));
904 return -1;
905 }
906
907 return 0;
908 }
909
910
911 /* ===== System calls available on all supported kernels ============== */
912
913 /*
914 * Query the kernel for the MTU of the given interface.
915 */
916 static int
917 iface_get_mtu(int fd, const char *device, char *ebuf)
918 {
919 struct ifreq ifr;
920
921 if (!device)
922 return BIGGER_THAN_ALL_MTUS;
923
924 memset(&ifr, 0, sizeof(ifr));
925 strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
926
927 if (ioctl(fd, SIOCGIFMTU, &ifr) == -1) {
928 snprintf(ebuf, PCAP_ERRBUF_SIZE,
929 "ioctl: %s", pcap_strerror(errno));
930 return -1;
931 }
932
933 return ifr.ifr_mtu;
934 }
935
936 /*
937 * Get the hardware type of the given interface as ARPHRD_xxx constant.
938 */
939 static int
940 iface_get_arptype(int fd, const char *device, char *ebuf)
941 {
942 struct ifreq ifr;
943
944 memset(&ifr, 0, sizeof(ifr));
945 strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
946
947 if (ioctl(fd, SIOCGIFHWADDR, &ifr) == -1) {
948 snprintf(ebuf, PCAP_ERRBUF_SIZE,
949 "ioctl: %s", pcap_strerror(errno));
950 return -1;
951 }
952
953 return ifr.ifr_hwaddr.sa_family;
954 }