aboutsummaryrefslogtreecommitdiffstats
path: root/package/libpcap/patches/202-protocol_api.patch
blob: 892aeb7e0de34227f2c03e733bb6106e5635864a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
--- a/pcap-int.h
+++ b/pcap-int.h
@@ -209,6 +209,7 @@ struct pcap_opt {
 	char	*source;
 	int	promisc;
 	int	rfmon;
+	int proto;	/* protocol for packet socket (linux) */
 };
 
 /*
--- a/pcap-linux.c
+++ b/pcap-linux.c
@@ -335,7 +335,7 @@ static int	iface_get_id(int fd, const ch
 static int	iface_get_mtu(int fd, const char *device, char *ebuf);
 static int 	iface_get_arptype(int fd, const char *device, char *ebuf);
 #ifdef HAVE_PF_PACKET_SOCKETS
-static int 	iface_bind(int fd, int ifindex, char *ebuf);
+static int 	iface_bind(int fd, int ifindex, char *ebuf, unsigned short proto);
 #ifdef IW_MODE_MONITOR
 static int	has_wext(int sock_fd, const char *device, char *ebuf);
 #endif /* IW_MODE_MONITOR */
@@ -881,7 +881,7 @@ pcap_can_set_rfmon_linux(pcap_t *handle)
 	 * (We assume that if we have Wireless Extensions support
 	 * we also have PF_PACKET support.)
 	 */
-	sock_fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
+	sock_fd = socket(PF_PACKET, SOCK_RAW, p->opt.proto);
 	if (sock_fd == -1) {
 		(void)snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
 		    "socket: %s", pcap_strerror(errno));
@@ -1128,6 +1128,9 @@ pcap_activate_linux(pcap_t *handle)
 	handle->read_op = pcap_read_linux;
 	handle->stats_op = pcap_stats_linux;
 
+	if (handle->opt.proto < 0)
+		handle->opt.proto = (int) htons(ETH_P_ALL);
+
 	/*
 	 * The "any" device is a special device which causes us not
 	 * to bind to a particular device and thus to look at all
@@ -2684,8 +2687,8 @@ activate_new(pcap_t *handle)
 	 * try a SOCK_RAW socket for the raw interface.
 	 */
 	sock_fd = is_any_device ?
-		socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_ALL)) :
-		socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
+		socket(PF_PACKET, SOCK_DGRAM, handle->opt.proto) :
+		socket(PF_PACKET, SOCK_RAW, handle->opt.proto);
 
 	if (sock_fd == -1) {
 		snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "socket: %s",
@@ -2783,7 +2786,7 @@ activate_new(pcap_t *handle)
 				return PCAP_ERROR;
 			}
 			sock_fd = socket(PF_PACKET, SOCK_DGRAM,
-			    htons(ETH_P_ALL));
+			    handle->opt.proto);
 			if (sock_fd == -1) {
 				snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
 				    "socket: %s", pcap_strerror(errno));
@@ -2835,7 +2838,7 @@ activate_new(pcap_t *handle)
 		}
 
 		if ((err = iface_bind(sock_fd, handle->md.ifindex,
-		    handle->errbuf)) != 1) {
+		    handle->errbuf, handle->opt.proto)) != 1) {
 		    	close(sock_fd);
 			if (err < 0)
 				return err;
@@ -3640,7 +3643,7 @@ iface_get_id(int fd, const char *device,
  *  or a PCAP_ERROR_ value on a hard error.
  */
 static int
-iface_bind(int fd, int ifindex, char *ebuf)
+iface_bind(int fd, int ifindex, char *ebuf, unsigned short proto)
 {
 	struct sockaddr_ll	sll;
 	int			err;
@@ -3649,7 +3652,7 @@ iface_bind(int fd, int ifindex, char *eb
 	memset(&sll, 0, sizeof(sll));
 	sll.sll_family		= AF_PACKET;
 	sll.sll_ifindex		= ifindex;
-	sll.sll_protocol	= htons(ETH_P_ALL);
+	sll.sll_protocol	= proto;
 
 	if (bind(fd, (struct sockaddr *) &sll, sizeof(sll)) == -1) {
 		if (errno == ENETDOWN) {
@@ -4359,7 +4362,7 @@ activate_old(pcap_t *handle)
 
 	/* Open the socket */
 
-	handle->fd = socket(PF_INET, SOCK_PACKET, htons(ETH_P_ALL));
+	handle->fd = socket(PF_INET, SOCK_PACKET, handle->opt.proto);
 	if (handle->fd == -1) {
 		snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
 			 "socket: %s", pcap_strerror(errno));
--- a/pcap.c
+++ b/pcap.c
@@ -258,6 +258,8 @@ pcap_create_common(const char *source, c
 	pcap_set_snaplen(p, 65535);	/* max packet size */
 	p->opt.promisc = 0;
 	p->opt.buffer_size = 0;
+	p->opt.proto = -1;
+
 	return (p);
 }
 
@@ -317,6 +319,15 @@ pcap_set_buffer_size(pcap_t *p, int buff
 	return 0;
 }
 
+int
+pcap_set_protocol(pcap_t *p, unsigned short proto)
+{
+	if (pcap_check_activated(p))
+		return PCAP_ERROR_ACTIVATED;
+	p->opt.proto = proto;
+	return 0;
+}
+
 int
 pcap_activate(pcap_t *p)
 {
--- a/pcap/pcap.h
+++ b/pcap/pcap.h
@@ -68,6 +68,7 @@ extern "C" {
 #define PCAP_VERSION_MINOR 4
 
 #define PCAP_ERRBUF_SIZE 256
+#define HAS_PROTO_EXTENSION
 
 /*
  * Compatibility for systems that have a bpf.h that
@@ -276,6 +277,7 @@ int	pcap_can_set_rfmon(pcap_t *);
 int	pcap_set_rfmon(pcap_t *, int);
 int	pcap_set_timeout(pcap_t *, int);
 int	pcap_set_buffer_size(pcap_t *, int);
+int	pcap_set_protocol(pcap_t *, unsigned short);
 int	pcap_activate(pcap_t *);
 
 pcap_t	*pcap_open_live(const char *, int, int, int, char *);