base-files: make the MAC address of bridge interfaces sticky to avoid ARP issues...
[openwrt.git] / package / libpcap / patches / 200-debian_fix_any_intf.patch
1 --- a/pcap-linux.c
2 +++ b/pcap-linux.c
3 @@ -297,6 +297,12 @@ pcap_create(const char *device, char *eb
4  {
5         pcap_t *handle;
6  
7 +       /*
8 +        * A null device name is equivalent to the "any" device.
9 +        */
10 +       if (device == NULL)
11 +               device = "any";
12 +
13  #ifdef HAVE_DAG_API
14         if (strstr(device, "dag")) {
15                 return dag_create(device, ebuf);
16 @@ -338,10 +344,9 @@ pcap_can_set_rfmon_linux(pcap_t *p)
17         struct iwreq ireq;
18  #endif
19  
20 -       if (p->opt.source == NULL) {
21 +       if (strcmp(p->opt.source, "any") == 0) {
22                 /*
23 -                * This is equivalent to the "any" device, and we don't
24 -                * support monitor mode on it.
25 +                * Monitor mode makes no sense on the "any" device.
26                  */
27                 return 0;
28         }
29 @@ -518,12 +523,11 @@ pcap_activate_linux(pcap_t *handle)
30         handle->stats_op = pcap_stats_linux;
31  
32         /*
33 -        * NULL and "any" are special devices which give us the hint to
34 -        * monitor all devices.
35 +        * The "any" device is a special device which causes us not
36 +        * to bind to a particular device and thus to look at all
37 +        * devices.
38          */
39 -       if (!device || strcmp(device, "any") == 0) {
40 -               device                  = NULL;
41 -               handle->md.device       = strdup("any");
42 +       if (strcmp(device, "any") == 0) {
43                 if (handle->opt.promisc) {
44                         handle->opt.promisc = 0;
45                         /* Just a warning. */
46 @@ -531,10 +535,9 @@ pcap_activate_linux(pcap_t *handle)
47                             "Promiscuous mode not supported on the \"any\" device");
48                         status = PCAP_WARNING_PROMISC_NOTSUP;
49                 }
50 +       }
51  
52 -       } else
53 -               handle->md.device       = strdup(device);
54 -
55 +       handle->md.device       = strdup(device);
56         if (handle->md.device == NULL) {
57                 snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "strdup: %s",
58                          pcap_strerror(errno) );
59 @@ -1657,19 +1660,21 @@ static int
60  activate_new(pcap_t *handle)
61  {
62  #ifdef HAVE_PF_PACKET_SOCKETS
63 +       const char              *device = handle->opt.source;
64 +       int                     is_any_device = (strcmp(device, "any") == 0);
65         int                     sock_fd = -1, arptype, val;
66         int                     err = 0;
67         struct packet_mreq      mr;
68 -       const char* device = handle->opt.source;
69  
70         /*
71 -        * Open a socket with protocol family packet. If a device is
72 -        * given we try to open it in raw mode otherwise we use
73 -        * the cooked interface.
74 -        */
75 -       sock_fd = device ?
76 -               socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))
77 -             : socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_ALL));
78 +        * Open a socket with protocol family packet. If the
79 +        * "any" device was specified, we open a SOCK_DGRAM
80 +        * socket for the cooked interface, otherwise we first
81 +        * try a SOCK_RAW socket for the raw interface.
82 +        */
83 +       sock_fd = is_any_device ?
84 +               socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_ALL)) :
85 +               socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
86  
87         if (sock_fd == -1) {
88                 snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "socket: %s",
89 @@ -1704,7 +1709,7 @@ activate_new(pcap_t *handle)
90          * to cooked mode if we have an unknown interface type
91          * or a type we know doesn't work well in raw mode.
92          */
93 -       if (device) {
94 +       if (!is_any_device) {
95                 /* Assume for now we don't need cooked mode. */
96                 handle->md.cooked = 0;
97  
98 @@ -1819,15 +1824,23 @@ activate_new(pcap_t *handle)
99                 }
100         } else {
101                 /*
102 -                * This is cooked mode.
103 +                * The "any" device.
104 +                */
105 +               if (handle->opt.rfmon) {
106 +                       /*
107 +                        * It doesn't support monitor mode.
108 +                        */
109 +                       return PCAP_ERROR_RFMON_NOTSUP;
110 +               }
111 +
112 +               /*
113 +                * It uses cooked mode.
114                  */
115                 handle->md.cooked = 1;
116                 handle->linktype = DLT_LINUX_SLL;
117  
118                 /*
119                  * We're not bound to a device.
120 -                * XXX - true?  Or true only if we're using
121 -                * the "any" device?
122                  * For now, we're using this as an indication
123                  * that we can't transmit; stop doing that only
124                  * if we figure out how to transmit in cooked
125 @@ -1852,10 +1865,13 @@ activate_new(pcap_t *handle)
126  
127         /*
128          * Hmm, how can we set promiscuous mode on all interfaces?
129 -        * I am not sure if that is possible at all.
130 +        * I am not sure if that is possible at all.  For now, we
131 +        * silently ignore attempts to turn promiscuous mode on
132 +        * for the "any" device (so you don't have to explicitly
133 +        * disable it in programs such as tcpdump).
134          */
135  
136 -       if (device && handle->opt.promisc) {
137 +       if (!is_any_device && handle->opt.promisc) {
138                 memset(&mr, 0, sizeof(mr));
139                 mr.mr_ifindex = handle->md.ifindex;
140                 mr.mr_type    = PACKET_MR_PROMISC;
141 @@ -3118,7 +3134,7 @@ activate_old(pcap_t *handle)
142  
143         /* Bind to the given device */
144  
145 -       if (!device) {
146 +       if (strcmp(device, "any") == 0) {
147                 strncpy(handle->errbuf, "pcap_activate: The \"any\" device isn't supported on 2.0[.x]-kernel systems",
148                         PCAP_ERRBUF_SIZE);
149                 return PCAP_ERROR;