add chaos_calmer branch
[15.05/openwrt.git] / package / libs / libpcap / patches / 202-protocol_api.patch
1 --- a/pcap-linux.c
2 +++ b/pcap-linux.c
3 @@ -380,7 +380,7 @@ static int  iface_get_id(int fd, const ch
4  static int     iface_get_mtu(int fd, const char *device, char *ebuf);
5  static int     iface_get_arptype(int fd, const char *device, char *ebuf);
6  #ifdef HAVE_PF_PACKET_SOCKETS
7 -static int     iface_bind(int fd, int ifindex, char *ebuf);
8 +static int     iface_bind(int fd, int ifindex, char *ebuf, unsigned short proto);
9  #ifdef IW_MODE_MONITOR
10  static int     has_wext(int sock_fd, const char *device, char *ebuf);
11  #endif /* IW_MODE_MONITOR */
12 @@ -963,7 +963,7 @@ pcap_can_set_rfmon_linux(pcap_t *handle)
13          * (We assume that if we have Wireless Extensions support
14          * we also have PF_PACKET support.)
15          */
16 -       sock_fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
17 +       sock_fd = socket(PF_PACKET, SOCK_RAW, p->opt.proto);
18         if (sock_fd == -1) {
19                 (void)snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
20                     "socket: %s", pcap_strerror(errno));
21 @@ -1251,6 +1251,9 @@ pcap_activate_linux(pcap_t *handle)
22         handle->read_op = pcap_read_linux;
23         handle->stats_op = pcap_stats_linux;
24  
25 +       if (handle->opt.proto < 0)
26 +               handle->opt.proto = (int) htons(ETH_P_ALL);
27 +
28         /*
29          * The "any" device is a special device which causes us not
30          * to bind to a particular device and thus to look at all
31 @@ -3012,8 +3015,8 @@ activate_new(pcap_t *handle)
32          * try a SOCK_RAW socket for the raw interface.
33          */
34         sock_fd = is_any_device ?
35 -               socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_ALL)) :
36 -               socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
37 +               socket(PF_PACKET, SOCK_DGRAM, handle->opt.proto) :
38 +               socket(PF_PACKET, SOCK_RAW, handle->opt.proto);
39  
40         if (sock_fd == -1) {
41                 if (errno == EINVAL || errno == EAFNOSUPPORT) {
42 @@ -3130,7 +3133,7 @@ activate_new(pcap_t *handle)
43                                 return PCAP_ERROR;
44                         }
45                         sock_fd = socket(PF_PACKET, SOCK_DGRAM,
46 -                           htons(ETH_P_ALL));
47 +                           handle->opt.proto);
48                         if (sock_fd == -1) {
49                                 snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
50                                     "socket: %s", pcap_strerror(errno));
51 @@ -3193,7 +3196,7 @@ activate_new(pcap_t *handle)
52                 }
53  
54                 if ((err = iface_bind(sock_fd, handlep->ifindex,
55 -                   handle->errbuf)) != 1) {
56 +                   handle->errbuf, handle->opt.proto)) != 1) {
57                         close(sock_fd);
58                         if (err < 0)
59                                 return err;
60 @@ -4667,7 +4670,7 @@ iface_get_id(int fd, const char *device,
61   *  or a PCAP_ERROR_ value on a hard error.
62   */
63  static int
64 -iface_bind(int fd, int ifindex, char *ebuf)
65 +iface_bind(int fd, int ifindex, char *ebuf, unsigned short proto)
66  {
67         struct sockaddr_ll      sll;
68         int                     err;
69 @@ -4676,7 +4679,7 @@ iface_bind(int fd, int ifindex, char *eb
70         memset(&sll, 0, sizeof(sll));
71         sll.sll_family          = AF_PACKET;
72         sll.sll_ifindex         = ifindex;
73 -       sll.sll_protocol        = htons(ETH_P_ALL);
74 +       sll.sll_protocol        = proto;
75  
76         if (bind(fd, (struct sockaddr *) &sll, sizeof(sll)) == -1) {
77                 if (errno == ENETDOWN) {
78 @@ -5561,7 +5564,7 @@ activate_old(pcap_t *handle)
79  
80         /* Open the socket */
81  
82 -       handle->fd = socket(PF_INET, SOCK_PACKET, htons(ETH_P_ALL));
83 +       handle->fd = socket(PF_INET, SOCK_PACKET, handle->opt.proto);
84         if (handle->fd == -1) {
85                 snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
86                          "socket: %s", pcap_strerror(errno));
87 --- a/pcap.c
88 +++ b/pcap.c
89 @@ -556,6 +556,7 @@ pcap_create_common(const char *source, c
90         p->opt.promisc = 0;
91         p->opt.rfmon = 0;
92         p->opt.immediate = 0;
93 +       p->opt.proto = -1;
94         p->opt.tstamp_type = -1;        /* default to not setting time stamp type */
95         p->opt.tstamp_precision = PCAP_TSTAMP_PRECISION_MICRO;
96         return (p);
97 @@ -713,6 +714,15 @@ pcap_get_tstamp_precision(pcap_t *p)
98  }
99  
100  int
101 +pcap_set_protocol(pcap_t *p, unsigned short proto)
102 +{
103 +       if (pcap_check_activated(p))
104 +               return PCAP_ERROR_ACTIVATED;
105 +       p->opt.proto = proto;
106 +       return 0;
107 +}
108 +
109 +int
110  pcap_activate(pcap_t *p)
111  {
112         int status;
113 --- a/pcap/pcap.h
114 +++ b/pcap/pcap.h
115 @@ -68,6 +68,7 @@ extern "C" {
116  #define PCAP_VERSION_MINOR 4
117  
118  #define PCAP_ERRBUF_SIZE 256
119 +#define HAS_PROTO_EXTENSION
120  
121  /*
122   * Compatibility for systems that have a bpf.h that
123 @@ -283,6 +284,7 @@ int pcap_set_timeout(pcap_t *, int);
124  int    pcap_set_tstamp_type(pcap_t *, int);
125  int    pcap_set_immediate_mode(pcap_t *, int);
126  int    pcap_set_buffer_size(pcap_t *, int);
127 +int    pcap_set_protocol(pcap_t *, unsigned short);
128  int    pcap_set_tstamp_precision(pcap_t *, int);
129  int    pcap_get_tstamp_precision(pcap_t *);
130  int    pcap_activate(pcap_t *);
131 --- a/pcap-int.h
132 +++ b/pcap-int.h
133 @@ -88,6 +88,7 @@ struct pcap_opt {
134         char    *source;
135         int     timeout;        /* timeout for buffering */
136         int     buffer_size;
137 +       int     proto;      /* protocol for packet socket (linux) */
138         int     promisc;
139         int     rfmon;          /* monitor mode */
140         int     immediate;      /* immediate mode - deliver packets as soon as they arrive */