2929#include <netinet/ip.h>
3030#include <netinet/tcp.h>
3131#include <sys/socket.h>
32+ #include <linux/if_packet.h>
3233#include <linux/netfilter.h>
3334#include <linux/netfilter/nfnetlink_queue.h>
3435#include <libnetfilter_queue/libnetfilter_queue.h>
@@ -71,17 +72,15 @@ static void ipaddr_to_str(struct sockaddr *addr, char ipstr[INET6_ADDRSTRLEN])
7172}
7273
7374
74- static int send_ack (struct sockaddr * saddr , struct sockaddr * daddr ,
75- uint16_t sport_be , uint16_t dport_be , uint32_t seq_be ,
76- uint32_t ackseq_be )
75+ static int send_ack (struct sockaddr_ll * sll , struct sockaddr * saddr ,
76+ struct sockaddr * daddr , uint16_t sport_be ,
77+ uint16_t dport_be , uint32_t seq_be , uint32_t ackseq_be )
7778{
78- int pkt_len , addr_len , sock_fd ;
79+ int pkt_len ;
7980 ssize_t nbytes ;
8081 char pkt_buff [1024 ];
8182
8283 if (daddr -> sa_family == AF_INET ) {
83- sock_fd = g_ctx .sock4fd ;
84- addr_len = sizeof (struct sockaddr_in );
8584 pkt_len = fh_pkt4_make (pkt_buff , sizeof (pkt_buff ), saddr , daddr ,
8685 sport_be , dport_be , seq_be , ackseq_be , 0 , NULL ,
8786 0 );
@@ -90,8 +89,6 @@ static int send_ack(struct sockaddr *saddr, struct sockaddr *daddr,
9089 return -1 ;
9190 }
9291 } else if (daddr -> sa_family == AF_INET6 ) {
93- sock_fd = g_ctx .sock6fd ;
94- addr_len = sizeof (struct sockaddr_in6 );
9592 pkt_len = fh_pkt6_make (pkt_buff , sizeof (pkt_buff ), saddr , daddr ,
9693 sport_be , dport_be , seq_be , ackseq_be , 0 , NULL ,
9794 0 );
@@ -104,7 +101,8 @@ static int send_ack(struct sockaddr *saddr, struct sockaddr *daddr,
104101 return -1 ;
105102 }
106103
107- nbytes = sendto (sock_fd , pkt_buff , pkt_len , 0 , daddr , addr_len );
104+ nbytes = sendto (g_ctx .sockfd , pkt_buff , pkt_len , 0 ,
105+ (struct sockaddr * ) sll , sizeof (* sll ));
108106 if (nbytes < 0 ) {
109107 E ("ERROR: sendto(): %s" , strerror (errno ));
110108 return -1 ;
@@ -114,16 +112,16 @@ static int send_ack(struct sockaddr *saddr, struct sockaddr *daddr,
114112}
115113
116114
117- static int send_http (struct sockaddr * saddr , struct sockaddr * daddr ,
118- uint16_t sport_be , uint16_t dport_be , uint32_t seq_be ,
119- uint32_t ackseq_be )
115+ static int send_http (struct sockaddr_ll * sll , struct sockaddr * saddr ,
116+ struct sockaddr * daddr , uint16_t sport_be ,
117+ uint16_t dport_be , uint32_t seq_be , uint32_t ackseq_be )
120118{
121119 static const char * http_fmt = "GET / HTTP/1.1\r\n"
122120 "Host: %s\r\n"
123121 "Accept: */*\r\n"
124122 "\r\n" ;
125123
126- int http_len , pkt_len , addr_len , sock_fd ;
124+ int http_len , pkt_len ;
127125 ssize_t nbytes ;
128126 char http_buff [512 ], pkt_buff [1024 ];
129127
@@ -135,8 +133,6 @@ static int send_http(struct sockaddr *saddr, struct sockaddr *daddr,
135133 }
136134
137135 if (daddr -> sa_family == AF_INET ) {
138- sock_fd = g_ctx .sock4fd ;
139- addr_len = sizeof (struct sockaddr_in );
140136 pkt_len = fh_pkt4_make (pkt_buff , sizeof (pkt_buff ), saddr , daddr ,
141137 sport_be , dport_be , seq_be , ackseq_be , 1 ,
142138 http_buff , http_len );
@@ -145,8 +141,6 @@ static int send_http(struct sockaddr *saddr, struct sockaddr *daddr,
145141 return -1 ;
146142 }
147143 } else if (daddr -> sa_family == AF_INET6 ) {
148- sock_fd = g_ctx .sock6fd ;
149- addr_len = sizeof (struct sockaddr_in6 );
150144 pkt_len = fh_pkt6_make (pkt_buff , sizeof (pkt_buff ), saddr , daddr ,
151145 sport_be , dport_be , seq_be , ackseq_be , 1 ,
152146 http_buff , http_len );
@@ -159,7 +153,8 @@ static int send_http(struct sockaddr *saddr, struct sockaddr *daddr,
159153 return -1 ;
160154 }
161155
162- nbytes = sendto (sock_fd , pkt_buff , pkt_len , 0 , daddr , addr_len );
156+ nbytes = sendto (g_ctx .sockfd , pkt_buff , pkt_len , 0 ,
157+ (struct sockaddr * ) sll , sizeof (* sll ));
163158 if (nbytes < 0 ) {
164159 E ("ERROR: sendto(): %s" , strerror (errno ));
165160 return -1 ;
@@ -172,7 +167,7 @@ static int send_http(struct sockaddr *saddr, struct sockaddr *daddr,
172167static int callback (struct nfq_q_handle * qh , struct nfgenmsg * nfmsg ,
173168 struct nfq_data * nfa , void * data )
174169{
175- uint32_t pkt_id , ack_new ;
170+ uint32_t pkt_id , ifindex , ack_new ;
176171 uint16_t ethertype ;
177172 int res , i , pkt_len , tcp_payload_len ;
178173 struct nfqnl_msg_packet_hdr * ph ;
@@ -181,6 +176,8 @@ static int callback(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg,
181176 char src_ip [INET6_ADDRSTRLEN ], dst_ip [INET6_ADDRSTRLEN ];
182177 struct sockaddr_storage saddr_store , daddr_store ;
183178 struct sockaddr * saddr , * daddr ;
179+ struct nfqnl_msg_packet_hw * hwph ;
180+ struct sockaddr_ll sll ;
184181
185182 (void ) nfmsg ;
186183 (void ) data ;
@@ -195,14 +192,27 @@ static int callback(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg,
195192 }
196193
197194 pkt_id = ntohl (ph -> packet_id );
198- ethertype = ntohs (ph -> hw_protocol );
195+
196+ hwph = nfq_get_packet_hw (nfa );
197+ if (!hwph ) {
198+ EE ("ERROR: nfq_get_packet_hw(): %s" , "failure" );
199+ goto ret_accept ;
200+ }
201+
202+ ifindex = nfq_get_indev (nfa );
203+ if (!ifindex ) {
204+ EE ("ERROR: nfq_get_indev(): %s" , "failure" );
205+ goto ret_accept ;
206+ }
207+
199208 pkt_data = NULL ;
200209 pkt_len = nfq_get_payload (nfa , & pkt_data );
201210 if (pkt_len < 0 || !pkt_data ) {
202211 EE ("ERROR: nfq_get_payload(): %s" , "failure" );
203212 goto ret_accept ;
204213 }
205214
215+ ethertype = ntohs (ph -> hw_protocol );
206216 if (ethertype == ETHERTYPE_IP ) {
207217 res = fh_pkt4_parse (pkt_data , pkt_len , saddr , daddr , & tcph ,
208218 & tcp_payload_len );
@@ -222,6 +232,13 @@ static int callback(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg,
222232 goto ret_accept ;
223233 }
224234
235+ memset (& sll , 0 , sizeof (sll ));
236+ sll .sll_family = AF_PACKET ;
237+ sll .sll_protocol = ph -> hw_protocol ;
238+ sll .sll_ifindex = ifindex ;
239+ sll .sll_halen = sizeof (hwph -> hw_addr );
240+ memcpy (sll .sll_addr , hwph -> hw_addr , sizeof (hwph -> hw_addr ));
241+
225242 if (!g_ctx .silent ) {
226243 ipaddr_to_str (saddr , src_ip );
227244 ipaddr_to_str (daddr , dst_ip );
@@ -240,7 +257,7 @@ static int callback(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg,
240257 ack_new = htonl (ack_new );
241258
242259 for (i = 0 ; i < g_ctx .repeat ; i ++ ) {
243- res = send_ack (daddr , saddr , tcph -> dest , tcph -> source ,
260+ res = send_ack (& sll , daddr , saddr , tcph -> dest , tcph -> source ,
244261 tcph -> ack_seq , ack_new );
245262 if (res < 0 ) {
246263 EE (T (send_ack ));
@@ -251,7 +268,7 @@ static int callback(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg,
251268 dst_ip , ntohs (tcph -> dest ));
252269
253270 for (i = 0 ; i < g_ctx .repeat ; i ++ ) {
254- res = send_http (daddr , saddr , tcph -> dest , tcph -> source ,
271+ res = send_http (& sll , daddr , saddr , tcph -> dest , tcph -> source ,
255272 tcph -> ack_seq , ack_new );
256273 if (res < 0 ) {
257274 EE (T (send_http ));
@@ -267,7 +284,7 @@ static int callback(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg,
267284 ntohs (tcph -> dest ));
268285
269286 for (i = 0 ; i < g_ctx .repeat ; i ++ ) {
270- res = send_http (daddr , saddr , tcph -> dest , tcph -> source ,
287+ res = send_http (& sll , daddr , saddr , tcph -> dest , tcph -> source ,
271288 tcph -> ack_seq , tcph -> seq );
272289 if (res < 0 ) {
273290 EE (T (send_http ));
0 commit comments