1 /*
2 ettercap -- send the the wire functions
3
4 Copyright (C) ALoR & NaGA
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19
20 */
21
22 #include <ec.h>
23
24 #if defined(OS_DARWIN) || defined(OS_BSD)
25 #include <sys/ioctl.h>
26 #endif
27
28 #include <ec_packet.h>
29 #include <ec_send.h>
30 #include <ec_network.h>
31
32 #include <pthread.h>
33 #include <pcap.h>
34
35 #include <libnet.h>
36
37 #define PCAP_TIMEOUT 10
38
39
40 /* globals */
41
42 u_int8 MEDIA_BROADCAST[MEDIA_ADDR_LEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
43 u_int8 ARP_BROADCAST[MEDIA_ADDR_LEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
44
45 static SLIST_HEAD (, build_entry) builders_table;
46
47 struct build_entry {
48 u_int8 dlt;
49 FUNC_BUILDER_PTR(builder);
50 SLIST_ENTRY (build_entry) next;
51 };
52
53 /* protos */
54
55 libnet_ptag_t ec_build_link_layer(u_int8 dlt, u_int8 *dst, u_int16 proto, libnet_t* l);
56
57 static pthread_mutex_t send_mutex = PTHREAD_MUTEX_INITIALIZER;
58 #define SEND_LOCK do{ pthread_mutex_lock(&send_mutex); } while(0)
59 #define SEND_UNLOCK do{ pthread_mutex_unlock(&send_mutex); } while(0)
60
61
62 /*******************************************/
63
64 /*
65 * send the packet at layer 3
66 * the eth header will be handled by the kernel
67 */
send_to_L3(struct packet_object * po)68 int send_to_L3(struct packet_object *po)
69 {
70 libnet_ptag_t t;
71 libnet_t *l;
72 char tmp[MAX_ASCII_ADDR_LEN];
73 int c;
74
75 switch(ntohs(po->L3.src.addr_type)) {
76 case AF_INET: l = EC_GBL_LNET->lnet_IP4;
77 break;
78 #ifdef WITH_IPV6
79 case AF_INET6: l = EC_GBL_LNET->lnet_IP6;
80 break;
81 #endif
82 default: l = NULL;
83 break;
84 }
85
86 /* Do not send the packet if corresponding
87 * libnet handler is not initialized
88 */
89 if(l == NULL)
90 return -E_NOTHANDLED;
91
92 SEND_LOCK;
93
94
95 t = libnet_build_data(po->fwd_packet, po->fwd_len, l, 0);
96 ON_ERROR(t, -1, "libnet_build_data: %s", libnet_geterror(l));
97 c = libnet_write(l);
98 //ON_ERROR(c, -1, "libnet_write %d (%d): %s", po->fwd_len, c, libnet_geterror(l));
99 if (c == -1)
100 USER_MSG("SEND L3 ERROR: %d byte packet (%04x:%02x) destined to %s was not forwarded (%s)\n",
101 po->fwd_len, ntohs(po->L3.proto), po->L4.proto, ip_addr_ntoa(&po->L3.dst, tmp),
102 libnet_geterror(l));
103
104 /* clear the pblock */
105 libnet_clear_packet(l);
106
107 SEND_UNLOCK;
108
109 return c;
110 }
111
112
113 /*
114 * send the packet at layer 2
115 * this can be used to send ARP messages
116 */
117
send_to_L2(struct packet_object * po)118 int send_to_L2(struct packet_object *po)
119 {
120 return send_to_iface(po, EC_GBL_IFACE);
121 }
122
123 /*
124 * send the packet to the bridge
125 */
126
send_to_bridge(struct packet_object * po)127 int send_to_bridge(struct packet_object *po)
128 {
129 return send_to_iface(po, EC_GBL_BRIDGE);
130 }
131
send_to_iface(struct packet_object * po,struct iface_env * iface)132 int send_to_iface(struct packet_object *po, struct iface_env *iface)
133 {
134 libnet_ptag_t t;
135 int c;
136 libnet_t *l;
137
138 if(iface->unoffensive)
139 return -E_INVALID;
140
141 /* if not lnet warn the developer ;) */
142 BUG_IF(iface->lnet == NULL);
143 l = iface->lnet;
144 SEND_LOCK;
145
146 t = libnet_build_data(po->packet, po->len, l, 0);
147
148 ON_ERROR(t, -1, "libnet_build_data: %s", libnet_geterror(l));
149
150 c = libnet_write(l);
151 ON_ERROR(c, -1, "libnet_write %d (%d): %s", po->len, c, libnet_geterror(l));
152
153 /* clear the pblock */
154 libnet_clear_packet(l);
155
156 SEND_UNLOCK;
157
158 return c;
159 }
160
161 /*
162 * we MUST not sniff packets sent by us at link layer.
163 * expecially useful in bridged sniffing.
164 *
165 * so we have to find a solution...
166 */
capture_only_incoming(pcap_t * p,libnet_t * l)167 void capture_only_incoming(pcap_t *p, libnet_t *l)
168 {
169 (void)p;
170 (void)l;
171 #ifdef OS_LINUX
172 /*
173 * a dirty hack to use the same socket for pcap and libnet.
174 * both the structures contains a "int fd" field representing the socket.
175 * we can close the fd opened by libnet and use the one already in use by pcap.
176 */
177
178 DEBUG_MSG("hack_pcap_lnet (before) pcap %d | lnet %d", pcap_fileno(p), l->fd);
179
180 /* needed to avoid double execution (for portstealing) */
181 if (pcap_fileno(p) == l->fd)
182 return;
183
184 /* close the lnet socket */
185 close(libnet_getfd(l));
186 /* use the socket opened by pcap */
187 l->fd = pcap_fileno(p);
188
189 DEBUG_MSG("hack_pcap_lnet (after) pcap %d | lnet %d", pcap_fileno(p), l->fd);
190 #endif
191
192 #ifdef OS_BSD
193 /*
194 * under BSD we cannot hack the fd as in linux...
195 * pcap opens the /dev/bpf in O_RDONLY and lnet needs O_RDWR
196 *
197 * so (if supported: only FreeBSD) we can set the BIOCSSEESENT to 0 to
198 * see only incoming packets
199 * but this is unconfortable, because we will not able to sniff ourself.
200 */
201 #ifdef OS_BSD_FREE
202 int val = 0;
203
204 DEBUG_MSG("hack_pcap_lnet: setting BIOCSSEESENT on pcap handler");
205
206 /* set it to 0 to capture only incoming traffic */
207 ioctl(pcap_fileno(p), BIOCSSEESENT, &val);
208 #else
209 DEBUG_MSG("hack_pcap_lnet: not applicable on this OS");
210 #endif
211 #endif
212
213 #ifdef OS_DARWIN
214 int val = 0;
215
216 DEBUG_MSG("hack_pcap_lnet: setting BIOCSSEESENT on pcap handler");
217
218 /* not all darwin versions support BIOCSSEESENT */
219 #ifdef BIOCSSEESENT
220 ioctl(pcap_fileno(p), BIOCSSEESENT, &val);
221 #endif
222 #endif
223
224 #ifdef OS_SOLARIS
225 DEBUG_MSG("hack_pcap_lnet: not applicable on this OS");
226 #endif
227
228 #ifdef OS_CYGWIN
229 DEBUG_MSG("hack_pcap_lnet: not applicable on this OS");
230 #endif
231
232 }
233
234 /*
235 * register a builder in the table
236 * a builder is a function to create a link layer header.
237 */
add_builder(u_int8 dlt,FUNC_BUILDER_PTR (builder))238 void add_builder(u_int8 dlt, FUNC_BUILDER_PTR(builder))
239 {
240 struct build_entry *e;
241
242 SAFE_CALLOC(e, 1, sizeof(struct build_entry));
243
244 e->dlt = dlt;
245 e->builder = builder;
246
247 SLIST_INSERT_HEAD(&builders_table, e, next);
248
249 return;
250
251 }
252
253 /*
254 * build the header calling the registered
255 * function for the current media
256 */
ec_build_link_layer(u_int8 dlt,u_int8 * dst,u_int16 proto,libnet_t * l)257 libnet_ptag_t ec_build_link_layer(u_int8 dlt, u_int8 *dst, u_int16 proto, libnet_t* l)
258 {
259 struct build_entry *e;
260
261 SLIST_FOREACH (e, &builders_table, next) {
262 if (e->dlt == dlt) {
263 return e->builder(dst, proto, l);
264 }
265 }
266
267 /* on error return -1 */
268 return -1;
269 }
270
271
272 /*
273 * helper function to send out an ARP packet
274 */
send_arp(u_char type,struct ip_addr * sip,u_int8 * smac,struct ip_addr * tip,u_int8 * tmac)275 int send_arp(u_char type, struct ip_addr *sip, u_int8 *smac, struct ip_addr *tip, u_int8 *tmac)
276 {
277 libnet_ptag_t t;
278 libnet_t *l;
279 int c;
280
281 /* if not lnet warn the developer ;) */
282 BUG_IF(EC_GBL_IFACE->lnet == NULL);
283 l = EC_GBL_IFACE->lnet;
284
285 SEND_LOCK;
286
287 /* ARP uses 00:00:00:00:00:00 broadcast */
288 if (type == ARPOP_REQUEST && tmac == MEDIA_BROADCAST)
289 tmac = ARP_BROADCAST;
290
291 /* create the ARP header */
292 t = libnet_build_arp(
293 ARPHRD_ETHER, /* hardware addr */
294 ETHERTYPE_IP, /* protocol addr */
295 MEDIA_ADDR_LEN, /* hardware addr size */
296 IP_ADDR_LEN, /* protocol addr size */
297 type, /* operation type */
298 smac, /* sender hardware addr */
299 (u_char *)&(sip->addr), /* sender protocol addr */
300 tmac, /* target hardware addr */
301 (u_char *)&(tip->addr), /* target protocol addr */
302 NULL, /* payload */
303 0, /* payload size */
304 l, /* libnet handle */
305 0); /* pblock id */
306 ON_ERROR(t, -1, "libnet_build_arp: %s", libnet_geterror(l));
307
308 /* MEDIA uses ff:ff:ff:ff:ff:ff broadcast */
309 if (type == ARPOP_REQUEST && tmac == ARP_BROADCAST)
310 tmac = MEDIA_BROADCAST;
311
312 /* add the media header */
313 t = ec_build_link_layer(EC_GBL_PCAP->dlt, tmac, ETHERTYPE_ARP, l);
314 if (t == -1)
315 FATAL_ERROR("Interface not suitable for layer2 sending");
316
317 /* send the packet */
318 c = libnet_write(l);
319 ON_ERROR(c, -1, "libnet_write (%d): %s", c, libnet_geterror(l));
320
321 /* clear the pblock */
322 libnet_clear_packet(l);
323
324 SEND_UNLOCK;
325
326 return c;
327 }
328
329 /*
330 * helper function to send out an ICMP PORT UNREACH packet at layer 3
331 */
send_L3_icmp_unreach(struct packet_object * po)332 int send_L3_icmp_unreach(struct packet_object *po)
333 {
334 libnet_ptag_t t;
335 int c;
336 libnet_t *l;
337
338 /* if not lnet warn the developer ;) */
339 BUG_IF(EC_GBL_LNET->lnet_IP4 == 0);
340 l = EC_GBL_LNET->lnet_IP4;
341 SEND_LOCK;
342
343
344 /* create the ICMP header */
345 t = libnet_build_icmpv4_echo(
346 3, /* type */
347 3, /* code */
348 0, /* checksum */
349 htons(EC_MAGIC_16), /* identification number */
350 htons(EC_MAGIC_16), /* sequence number */
351 po->L3.header, /* payload */
352 po->L3.len + 8, /* payload size */
353 l, /* libnet handle */
354 0); /* pblock id */
355 ON_ERROR(t, -1, "libnet_build_icmpv4_echo: %s", libnet_geterror(l));
356
357 /* auto calculate the checksum */
358 libnet_toggle_checksum(l, t, LIBNET_ON);
359
360 /* create the IP header */
361 t = libnet_build_ipv4(
362 LIBNET_IPV4_H + LIBNET_ICMPV4_ECHO_H, /* length */
363 0, /* TOS */
364 htons(EC_MAGIC_16), /* IP ID */
365 0, /* IP Frag */
366 64, /* TTL */
367 IPPROTO_ICMP, /* protocol */
368 0, /* checksum */
369 *po->L3.dst.addr32, /* source IP */
370 *po->L3.src.addr32, /* destination IP */
371 NULL, /* payload */
372 0, /* payload size */
373 l, /* libnet handle */
374 0);
375 ON_ERROR(t, -1, "libnet_build_ipv4: %s", libnet_geterror(l));
376
377 /* auto calculate the checksum */
378 libnet_toggle_checksum(l, t, LIBNET_ON);
379
380 /* send the packet to Layer 3 */
381 c = libnet_write(l);
382 ON_ERROR(c, -1, "libnet_write (%d): %s", c, libnet_geterror(l));
383
384 /* clear the pblock */
385 libnet_clear_packet(l);
386
387 SEND_UNLOCK;
388
389 return c;
390 }
391
392
393 /*
394 * helper function to send out an ICMP ECHO packet at layer 3
395 */
send_L3_icmp(u_char type,struct ip_addr * sip,struct ip_addr * tip)396 int send_L3_icmp(u_char type, struct ip_addr *sip, struct ip_addr *tip)
397 {
398 libnet_ptag_t t;
399 int c;
400 libnet_t *l;
401
402 /* if not lnet warn the developer ;) */
403 BUG_IF(EC_GBL_LNET->lnet_IP4 == 0);
404 l = EC_GBL_LNET->lnet_IP4;
405
406 SEND_LOCK;
407
408
409 /* create the ICMP header */
410 t = libnet_build_icmpv4_echo(
411 type, /* type */
412 0, /* code */
413 0, /* checksum */
414 htons(EC_MAGIC_16), /* identification number */
415 htons(EC_MAGIC_16), /* sequence number */
416 NULL, /* payload */
417 0, /* payload size */
418 l, /* libnet handle */
419 0); /* pblock id */
420 ON_ERROR(t, -1, "libnet_build_icmpv4_echo: %s", libnet_geterror(l));
421
422 /* auto calculate the checksum */
423 libnet_toggle_checksum(l, t, LIBNET_ON);
424
425 /* create the IP header */
426 t = libnet_build_ipv4(
427 LIBNET_IPV4_H + LIBNET_ICMPV4_ECHO_H, /* length */
428 0, /* TOS */
429 htons(EC_MAGIC_16), /* IP ID */
430 0, /* IP Frag */
431 64, /* TTL */
432 IPPROTO_ICMP, /* protocol */
433 0, /* checksum */
434 *sip->addr32, /* source IP */
435 *tip->addr32, /* destination IP */
436 NULL, /* payload */
437 0, /* payload size */
438 l, /* libnet handle */
439 0);
440 ON_ERROR(t, -1, "libnet_build_ipv4: %s", libnet_geterror(l));
441 /* auto calculate the checksum */
442 libnet_toggle_checksum(l, t, LIBNET_ON);
443
444 /* send the packet to Layer 3 */
445 c = libnet_write(l);
446 ON_ERROR(c, -1, "libnet_write (%d): %s", c, libnet_geterror(l));
447
448 /* clear the pblock */
449 libnet_clear_packet(l);
450
451 SEND_UNLOCK;
452
453 return c;
454 }
455
send_L3_icmp_echo(struct ip_addr * src,struct ip_addr * tgt)456 int send_L3_icmp_echo(struct ip_addr *src, struct ip_addr *tgt)
457 {
458 return send_L3_icmp(ICMP_ECHO, src, tgt);
459 }
460
461 /*
462 * helper function to send out an ICMP ECHO packet at layer 2
463 */
send_L2_icmp_echo(u_char type,struct ip_addr * sip,struct ip_addr * tip,u_int8 * tmac)464 int send_L2_icmp_echo(u_char type, struct ip_addr *sip, struct ip_addr *tip, u_int8 *tmac)
465 {
466 libnet_ptag_t t;
467 int c;
468 libnet_t *l;
469 /* if not lnet warn the developer ;) */
470 BUG_IF(EC_GBL_IFACE->lnet == 0);
471 l = EC_GBL_IFACE->lnet;
472
473 SEND_LOCK;
474
475 /* create the ICMP header */
476 t = libnet_build_icmpv4_echo(
477 type, /* type */
478 0, /* code */
479 0, /* checksum */
480 htons(EC_MAGIC_16), /* identification number */
481 htons(EC_MAGIC_16), /* sequence number */
482 NULL, /* payload */
483 0, /* payload size */
484 l, /* libnet handle */
485 0); /* pblock id */
486 ON_ERROR(t, -1, "libnet_build_icmpv4_echo: %s", libnet_geterror(l));
487
488 /* auto calculate the checksum */
489 libnet_toggle_checksum(l, t, LIBNET_ON);
490
491 /* create the IP header */
492 t = libnet_build_ipv4(
493 LIBNET_IPV4_H + LIBNET_ICMPV4_ECHO_H, /* length */
494 0, /* TOS */
495 htons(EC_MAGIC_16), /* IP ID */
496 0, /* IP Frag */
497 64, /* TTL */
498 IPPROTO_ICMP, /* protocol */
499 0, /* checksum */
500 *sip->addr32, /* source IP */
501 *tip->addr32, /* destination IP */
502 NULL, /* payload */
503 0, /* payload size */
504 l, /* libnet handle */
505 0);
506 ON_ERROR(t, -1, "libnet_build_ipv4: %s", libnet_geterror(l));
507
508 /* auto calculate the checksum */
509 libnet_toggle_checksum(l, t, LIBNET_ON);
510
511 /* add the media header */
512 t = ec_build_link_layer(EC_GBL_PCAP->dlt, tmac, ETHERTYPE_IP, l);
513 if (t == -1)
514 FATAL_ERROR("Interface not suitable for layer2 sending");
515
516 /* send the packet to Layer 2 */
517 c = libnet_write(l);
518 ON_ERROR(c, -1, "libnet_write (%d): %s", c, libnet_geterror(l));
519
520 /* clear the pblock */
521 libnet_clear_packet(l);
522
523 SEND_UNLOCK;
524
525 return c;
526 }
527
528
529 /*
530 * helper function to send out an ICMP REDIRECT packet
531 * the header are created on the source packet PO.
532 */
send_icmp_redir(u_char type,struct ip_addr * sip,struct ip_addr * gw,struct packet_object * po)533 int send_icmp_redir(u_char type, struct ip_addr *sip, struct ip_addr *gw, struct packet_object *po)
534 {
535 libnet_ptag_t t;
536 libnet_t *l;
537 struct libnet_ipv4_hdr *ip;
538 int c;
539
540 /* if not lnet warn the developer ;) */
541 BUG_IF(EC_GBL_IFACE->lnet == 0);
542 l = EC_GBL_IFACE->lnet;
543
544 /* retrieve the old ip header */
545 ip = (struct libnet_ipv4_hdr *)po->L3.header;
546
547 SEND_LOCK;
548
549 /* create the fake ip header for the icmp payload */
550 t = libnet_build_ipv4(
551 LIBNET_IPV4_H + 8,
552 //ntohs(ip->ip_len), /* original len */
553 ip->ip_tos, /* original tos */
554 ntohs(ip->ip_id), /* original id */
555 ntohs(ip->ip_off), /* original fragments */
556 ip->ip_ttl, /* original ttl */
557 ip->ip_p, /* original proto */
558 ip->ip_sum, /* original checksum */
559 ip->ip_src.s_addr, /* original source */
560 ip->ip_dst.s_addr, /* original dest */
561 po->L4.header, /* the 64 bit of the original datagram */
562 8, /* payload size */
563 l,
564 0);
565 ON_ERROR(t, -1, "libnet_build_ipv4: %s", libnet_geterror(l));
566 /* create the ICMP header */
567 t = libnet_build_icmpv4_redirect(
568 ICMP_REDIRECT, /* type */
569 type, /* code */
570 0, /* checksum */
571 *gw->addr32, /* gateway ip */
572 NULL, /* payload */
573 0, /* payload len */
574 l, /* libnet handle */
575 0); /* pblock id */
576 ON_ERROR(t, -1, "libnet_build_icmpv4_redirect: %s", libnet_geterror(l));
577 /* auto calculate the checksum */
578 libnet_toggle_checksum(l, t, LIBNET_ON);
579
580 /* create the IP header */
581 t = libnet_build_ipv4(
582 LIBNET_IPV4_H + LIBNET_ICMPV4_REDIRECT_H +
583 LIBNET_IPV4_H + 8, /* length */
584 0, /* TOS */
585 htons(EC_MAGIC_16), /* IP ID */
586 0, /* IP Frag */
587 64, /* TTL */
588 IPPROTO_ICMP, /* protocol */
589 0, /* checksum */
590 *sip->addr32, /* source IP */
591 *po->L3.src.addr32, /* destination IP */
592 NULL, /* payload */
593 0, /* payload size */
594 l, /* libnet handle */
595 0);
596 ON_ERROR(t, -1, "libnet_build_ipv4: %s", libnet_geterror(l));
597 /* auto calculate the checksum */
598 libnet_toggle_checksum(l, t, LIBNET_ON);
599
600 /* add the media header */
601 t = ec_build_link_layer(EC_GBL_PCAP->dlt, po->L2.src, ETHERTYPE_IP, l);
602 if (t == -1)
603 FATAL_ERROR("Interface not suitable for layer2 sending");
604
605 /*
606 * send the packet to Layer 2
607 * (sending icmp redirect is not permitted at layer 3)
608 */
609 c = libnet_write(l);
610 ON_ERROR(c, -1, "libnet_write (%d): %s", c, libnet_geterror(l));
611
612 /* clear the pblock */
613 libnet_clear_packet(l);
614
615 SEND_UNLOCK;
616
617 return c;
618 }
619
620 #ifdef WITH_IPV6
send_L3_icmp6_echo(struct ip_addr * sip,struct ip_addr * tip)621 int send_L3_icmp6_echo(struct ip_addr *sip, struct ip_addr *tip)
622 {
623 libnet_ptag_t t;
624 struct libnet_in6_addr src, dst;
625 int c;
626 libnet_t *l;
627
628 BUG_IF(EC_GBL_LNET->lnet_IP6 == 0);
629 l = EC_GBL_LNET->lnet_IP6;
630
631 SEND_LOCK;
632
633 memcpy(&src, sip->addr, sizeof(src));
634 memcpy(&dst, tip->addr, sizeof(dst));
635
636 t = libnet_build_icmpv6_echo(ICMP6_ECHO_REQUEST, /* type */
637 0, /* code */
638 0, /* checksum */
639 EC_MAGIC_16, /* id */
640 0, /* sequence number */
641 NULL, /* data */
642 0, /* its size */
643 l, /* handle */
644 0);
645 ON_ERROR(t, -1, "libnet_build_icmpv6_echo: %s", libnet_geterror(l));
646 libnet_toggle_checksum(l, t, LIBNET_ON);
647
648 t = libnet_build_ipv6(0, /* tc */
649 0, /* flow label */
650 LIBNET_ICMPV6_H, /* next header size */
651 IPPROTO_ICMPV6, /* next header */
652 255, /* hop limit */
653 src, /* source */
654 dst, /* destination */
655 NULL, /* payload and size */
656 0,
657 l, /* handle */
658 0); /* ptag */
659 ON_ERROR(t, -1, "libnet_build_ipv6: %s", libnet_geterror(l));
660
661 c = libnet_write(l);
662 ON_ERROR(c, -1, "libnet_write: %s", libnet_geterror(l));
663
664 libnet_clear_packet(l);
665
666 SEND_UNLOCK;
667
668 return c;
669 }
670
send_L2_icmp6_echo(struct ip_addr * sip,struct ip_addr * tip,u_int8 * tmac)671 int send_L2_icmp6_echo(struct ip_addr *sip, struct ip_addr *tip, u_int8 *tmac)
672 {
673 libnet_ptag_t t;
674 struct libnet_in6_addr src, dst;
675 int c;
676 libnet_t *l;
677
678 BUG_IF(EC_GBL_IFACE->lnet == NULL);
679 l = EC_GBL_IFACE->lnet;
680
681 SEND_LOCK;
682
683
684 memcpy(&src, sip->addr, sizeof(src));
685 memcpy(&dst, tip->addr, sizeof(dst));
686
687 t = libnet_build_icmpv6_echo(ICMP6_ECHO_REQUEST, /* type */
688 0, /* code */
689 0, /* checksum */
690 EC_MAGIC_16, /* id */
691 0, /* sequence number */
692 NULL, /* data */
693 0, /* its size */
694 l, /* handle */
695 0);
696 ON_ERROR(t, -1, "libnet_build_icmpv6_echo: %s", libnet_geterror(l));
697 libnet_toggle_checksum(l, t, LIBNET_ON);
698
699 t = libnet_build_ipv6(0, /* tc */
700 0, /* flow label */
701 LIBNET_ICMPV6_H, /* next header size */
702 IPPROTO_ICMPV6, /* next header */
703 255, /* hop limit */
704 src, /* source */
705 dst, /* destination */
706 NULL, /* payload and size */
707 0,
708 l, /* handle */
709 0); /* ptag */
710 ON_ERROR(t, -1, "libnet_build_ipv6: %s", libnet_geterror(l));
711
712 /* add the media header */
713 t = ec_build_link_layer(EC_GBL_PCAP->dlt, tmac, ETHERTYPE_IPV6, l);
714 if (t == -1)
715 FATAL_ERROR("Interface not suitable for layer2 sending");
716
717 c = libnet_write(l);
718 ON_ERROR(c, -1, "libnet_write: %s", libnet_geterror(l));
719
720 libnet_clear_packet(l);
721
722 SEND_UNLOCK;
723
724 return c;
725 }
726
727 /*
728 * send IP packet with an unknown header option
729 * RFC2460 conforming hosts, respond with a ICMPv6 parameter problem
730 * message even those not intended to respond to ICMP echos
731 */
send_L2_icmp6_echo_opt(struct ip_addr * sip,struct ip_addr * tip,u_int8 * o_data,u_int32 o_len,u_int8 * tmac)732 int send_L2_icmp6_echo_opt(struct ip_addr *sip, struct ip_addr *tip, u_int8* o_data, u_int32 o_len, u_int8 *tmac)
733 {
734 libnet_ptag_t t;
735 struct libnet_in6_addr src, dst;
736 int c, h = 0;
737 libnet_t *l;
738
739 BUG_IF(EC_GBL_IFACE->lnet == NULL);
740
741 l = EC_GBL_IFACE->lnet;
742
743 SEND_LOCK;
744
745 memcpy(&src, sip->addr, sizeof(src));
746 memcpy(&dst, tip->addr, sizeof(dst));
747
748 t = libnet_build_icmpv6_echo(ICMP6_ECHO_REQUEST, /* type */
749 0, /* code */
750 0, /* checksum */
751 EC_MAGIC_16, /* id */
752 0, /* sequence number */
753 NULL, /* data */
754 0, /* its size */
755 l, /* handle */
756 0);
757 ON_ERROR(t, -1, "libnet_build_icmpv6_echo: %s", libnet_geterror(l));
758 libnet_toggle_checksum(l, t, LIBNET_ON);
759
760 t = libnet_build_ipv6_destopts(IPPROTO_ICMPV6, /* next header */
761 LIBNET_IPV6_DESTOPTS_H / 8, /* lenth */
762 o_data, /* payload */
763 o_len, /* payload length */
764 l, /* handle */
765 0);
766 ON_ERROR(t, -1, "libnet_build_ipv6_destopts: %s", libnet_geterror(l));
767
768 h = LIBNET_IPV6_DESTOPTS_H + o_len + LIBNET_ICMPV6_H;
769 t = libnet_build_ipv6(0, /* tc */
770 0, /* flow label */
771 h, /* next header size */
772 IPPROTO_DSTOPTS, /* next header */
773 255, /* hop limit */
774 src, /* source */
775 dst, /* destination */
776 NULL, /* payload and size */
777 0,
778 l, /* handle */
779 0); /* ptag */
780 ON_ERROR(t, -1, "libnet_build_ipv6: %s", libnet_geterror(l));
781
782 /* add the media header */
783 t = ec_build_link_layer(EC_GBL_PCAP->dlt, tmac, ETHERTYPE_IPV6, l);
784 if (t == -1)
785 FATAL_ERROR("Interface not suitable for layer2 sending");
786
787 c = libnet_write(l);
788 ON_ERROR(c, -1, "libnet_write: %s", libnet_geterror(l));
789
790 libnet_clear_packet(l);
791
792
793 SEND_UNLOCK;
794
795 return c;
796 }
797
798 /*
799 * Sends neighbor solicitation request (like arp request with ipv4)
800 * macaddr parameter allows to add sender's mac address. This is an option for unicast requests.
801 * See RFC4861 for more information.
802 */
send_L2_icmp6_nsol(struct ip_addr * sip,struct ip_addr * tip,struct ip_addr * req,u_int8 * macaddr,u_int8 * tmac)803 int send_L2_icmp6_nsol(struct ip_addr *sip, struct ip_addr *tip, struct ip_addr *req, u_int8 *macaddr, u_int8 *tmac)
804 {
805 libnet_ptag_t t;
806 int c, h = 0;
807 struct libnet_in6_addr src, dst, r;
808 libnet_t *l;
809
810 BUG_IF(EC_GBL_IFACE->lnet == NULL);
811 l = EC_GBL_IFACE->lnet;
812
813 SEND_LOCK;
814
815
816 memcpy(&src, sip->addr, sizeof(src));
817 memcpy(&dst, tip->addr, sizeof(dst));
818 memcpy(&r, req->addr, sizeof(r));
819
820 if(macaddr != NULL) {
821 t = libnet_build_icmpv6_ndp_opt(ND_OPT_SOURCE_LINKADDR, /* Address type */
822 macaddr, /* MAC address */
823 MEDIA_ADDR_LEN, /* Address length */
824 l, /* libnet handle */
825 0); /* ptag */
826 ON_ERROR(t, -1, "libnet_build_icmpv6_ndp_opt: %s", libnet_geterror(l));
827 /* base header size + MAC address size */
828 h += LIBNET_ICMPV6_NDP_OPT_H + 6;
829 }
830
831 t = libnet_build_icmpv6_ndp_nsol(ND_NEIGHBOR_SOLICIT, /* type */
832 0, /* code */
833 0, /* checksum */
834 r, /* target address */
835 NULL, /* payload */
836 0, /* its size */
837 l, /* libnet handler */
838 0); /* ptag */
839 ON_ERROR(t, -1, "libnet_build_icmpv6_ndp_nsol: %s", libnet_geterror(l));
840 libnet_toggle_checksum(l, t, LIBNET_ON);
841 h += LIBNET_ICMPV6_NDP_NSOL_H;
842
843 t = libnet_build_ipv6(0, /* tc */
844 0, /* flow label */
845 h, /* length */
846 IPPROTO_ICMP6, /* proto */
847 255, /* hop limit */
848 src, /* source address */
849 dst, /* target address */
850 NULL, /* payload */
851 0, /* its size */
852 l, /* handle */
853 0); /* ptag */
854 ON_ERROR(t, -1, "libnet_build_ipv6: %s", libnet_geterror(l));
855
856 /* add the media header */
857 t = ec_build_link_layer(EC_GBL_PCAP->dlt, tmac, ETHERTYPE_IPV6, l);
858 if (t == -1)
859 FATAL_ERROR("Interface not suitable for layer2 sending");
860
861 c = libnet_write(l);
862 ON_ERROR(c, -1, "libnet_write: %s", libnet_geterror(l));
863
864 libnet_clear_packet(l);
865
866 SEND_UNLOCK;
867
868 return c;
869 }
870
send_L2_icmp6_nadv(struct ip_addr * sip,struct ip_addr * tip,u_int8 * macaddr,int router,u_int8 * tmac)871 int send_L2_icmp6_nadv(struct ip_addr *sip, struct ip_addr *tip, u_int8 *macaddr, int router, u_int8 *tmac)
872 {
873 libnet_ptag_t t;
874 int c, h = 0;
875 struct libnet_in6_addr src, dst;
876 int flags;
877 libnet_t *l;
878
879 BUG_IF(EC_GBL_IFACE->lnet == NULL);
880 l = EC_GBL_IFACE->lnet;
881
882 SEND_LOCK;
883
884
885 memcpy(&src, sip->addr, sizeof(src));
886 memcpy(&dst, tip->addr, sizeof(dst));
887
888 t = libnet_build_icmpv6_ndp_opt(ND_OPT_TARGET_LINKADDR, /* Address type */
889 macaddr, /* MAC address */
890 MEDIA_ADDR_LEN, /* Address length */
891 l, /* libnet handle */
892 0); /* ptag */
893 ON_ERROR(t, -1, "libnet_build_icmpv6_ndp_lla: %s", libnet_geterror(l));
894 h += LIBNET_ICMPV6_NDP_OPT_H + 6;
895
896 flags = ND_NA_FLAG_SOLICITED|ND_NA_FLAG_OVERRIDE;
897 if(router)
898 flags |= ND_NA_FLAG_ROUTER;
899 t = libnet_build_icmpv6_ndp_nadv(ND_NEIGHBOR_ADVERT, /* type */
900 0, /* code */
901 0, /* checksum */
902 flags, /* flags */
903 src, /* address */
904 NULL, /* payload */
905 0, /* payload size */
906 l, /* libnet handle */
907 0); /* ptag */
908 ON_ERROR(t, -1, "libnet_build_icmpv6_ndp_nadv: %s", libnet_geterror(l));
909 libnet_toggle_checksum(l, t, LIBNET_ON);
910 h += LIBNET_ICMPV6_NDP_NADV_H;
911
912 t = libnet_build_ipv6(0, /* tc */
913 0, /* flow label */
914 h, /* length */
915 IPPROTO_ICMP6, /* proto */
916 255, /* hop limit */
917 src, /* source address */
918 dst, /* target address */
919 NULL, /* payload */
920 0, /* its size */
921 l, /* handle */
922 0); /* ptag */
923 ON_ERROR(t, -1, "libnet_build_ipv6: %s", libnet_geterror(l));
924
925 /* add the media header */
926 t = ec_build_link_layer(EC_GBL_PCAP->dlt, tmac, ETHERTYPE_IPV6, l);
927 if (t == -1)
928 FATAL_ERROR("Interface not suitable for layer2 sending");
929
930 c = libnet_write(l);
931 ON_ERROR(c, -1, "libnet_write: %s", libnet_geterror(l));
932
933 libnet_clear_packet(l);
934
935 SEND_UNLOCK;
936
937 return c;
938 }
939
940 #endif /* WITH_IPV6 */
941
942 /*
943 * send a dhcp reply to tmac/tip
944 */
send_dhcp_reply(struct ip_addr * sip,struct ip_addr * tip,u_int8 * tmac,u_int8 * dhcp_hdr,u_int8 * options,size_t optlen)945 int send_dhcp_reply(struct ip_addr *sip, struct ip_addr *tip, u_int8 *tmac, u_int8 *dhcp_hdr, u_int8 *options, size_t optlen)
946 {
947 libnet_ptag_t t;
948 int c;
949 libnet_t *l;
950 /* if not lnet warn the developer ;) */
951 BUG_IF(EC_GBL_IFACE->lnet == 0);
952 l = EC_GBL_IFACE->lnet;
953
954 SEND_LOCK;
955
956 /* add the dhcp options */
957 t = libnet_build_data(
958 options, /* the options */
959 optlen, /* options len */
960 l, /* libnet handle */
961 0); /* libnet ptag */
962 ON_ERROR(t, -1, "libnet_build_data: %s", libnet_geterror(l));
963 /* create the dhcp header */
964 t = libnet_build_data(
965 dhcp_hdr, /* the header */
966 LIBNET_DHCPV4_H, /* dhcp len */
967 l, /* libnet handle */
968 0); /* libnet ptag */
969 ON_ERROR(t, -1, "libnet_build_data: %s", libnet_geterror(l));
970 /* create the udp header */
971 t = libnet_build_udp(
972 67, /* source port */
973 68, /* destination port */
974 LIBNET_UDP_H + LIBNET_DHCPV4_H + optlen, /* packet size */
975 0, /* checksum */
976 NULL, /* payload */
977 0, /* payload size */
978 l, /* libnet handle */
979 0); /* libnet id */
980 ON_ERROR(t, -1, "libnet_build_udp: %s", libnet_geterror(l));
981 /* auto calculate the checksum */
982 libnet_toggle_checksum(l, t, LIBNET_ON);
983
984 /* create the IP header */
985 t = libnet_build_ipv4(
986 LIBNET_IPV4_H + LIBNET_UDP_H + LIBNET_DHCPV4_H + optlen, /* length */
987 0, /* TOS */
988 htons(EC_MAGIC_16), /* IP ID */
989 0, /* IP Frag */
990 64, /* TTL */
991 IPPROTO_UDP, /* protocol */
992 0, /* checksum */
993 *sip->addr32, /* source IP */
994 *tip->addr32, /* destination IP */
995 NULL, /* payload */
996 0, /* payload size */
997 l, /* libnet handle */
998 0);
999 ON_ERROR(t, -1, "libnet_build_ipv4: %s", libnet_geterror(l));
1000 /* auto calculate the checksum */
1001 libnet_toggle_checksum(l, t, LIBNET_ON);
1002
1003 /* add the media header */
1004 t = ec_build_link_layer(EC_GBL_PCAP->dlt, tmac, ETHERTYPE_IP, l);
1005 if (t == -1)
1006 FATAL_ERROR("Interface not suitable for layer2 sending");
1007
1008 /*
1009 * send the packet to Layer 2
1010 * (sending icmp redirect is not permitted at layer 3)
1011 */
1012 c = libnet_write(l);
1013 ON_ERROR(c, -1, "libnet_write (%d): %s", c, libnet_geterror(l));
1014
1015 /* clear the pblock */
1016 libnet_clear_packet(l);
1017
1018 SEND_UNLOCK;
1019
1020 return c;
1021 }
1022
1023 /*
1024 * send a mdns reply
1025 */
send_mdns_reply(struct iface_env * iface,u_int16 dport,struct ip_addr * sip,struct ip_addr * tip,u_int8 * tmac,u_int16 id,u_int8 * data,size_t datalen,u_int16 anws_rr,u_int16 auth_rr,u_int16 addi_rr)1026 int send_mdns_reply(struct iface_env *iface, u_int16 dport, struct ip_addr *sip, struct ip_addr *tip, u_int8 *tmac, u_int16 id, u_int8 *data, size_t datalen, u_int16 anws_rr, u_int16 auth_rr, u_int16 addi_rr)
1027 {
1028 libnet_ptag_t t;
1029 int c, proto, ethertype;
1030 libnet_t *l;
1031 proto = ntohs(sip->addr_type);
1032
1033 /* if not lnet warn the developer ;) */
1034 BUG_IF(iface->lnet == 0);
1035 l = iface->lnet;
1036
1037 SEND_LOCK;
1038
1039 /* create the dns packet */
1040 t = libnet_build_dnsv4(
1041 LIBNET_UDP_DNSV4_H, /* TCP or UDP */
1042 id, /* id */
1043 0x8400, /* standard reply, no error */
1044 0, /* num_q */
1045 anws_rr, /* num_anws_rr */
1046 auth_rr, /* num_auth_rr */
1047 addi_rr, /* num_addi_rr */
1048 data,
1049 datalen,
1050 l, /* libnet handle */
1051 0); /* libnet id */
1052 ON_ERROR(t, -1, "libnet_build_dns: %s", libnet_geterror(l));
1053
1054 /* create the udp header */
1055 t = libnet_build_udp(
1056 5353, /* source port */
1057 htons(dport), /* destination port */
1058 LIBNET_UDP_H + LIBNET_UDP_DNSV4_H + datalen, /* packet size */
1059 0, /* checksum */
1060 NULL, /* payload */
1061 0, /* payload size */
1062 l, /* libnet handle */
1063 0); /* libnet id */
1064 ON_ERROR(t, -1, "libnet_build_udp: %s", libnet_geterror(l));
1065 /* auto calculate the checksum */
1066 libnet_toggle_checksum(l, t, LIBNET_ON);
1067
1068 /* create the IP header */
1069 switch (proto) {
1070 case AF_INET: {
1071 t = libnet_build_ipv4(
1072 LIBNET_IPV4_H + LIBNET_UDP_H + LIBNET_UDP_DNSV4_H + datalen, /* length */
1073 0, /* TOS */
1074 htons(EC_MAGIC_16), /* IP ID */
1075 0, /* IP Frag */
1076 255, /* TTL */
1077 IPPROTO_UDP, /* protocol */
1078 0, /* checksum */
1079 *sip->addr32, /* source IP */
1080 *tip->addr32, /* destination IP */
1081 NULL, /* payload */
1082 0, /* payload size */
1083 l, /* libnet handle */
1084 0);
1085 ON_ERROR(t, -1, "libnet_build_ipv4: %s", libnet_geterror(l));
1086 /* auto calculate the checksum */
1087 libnet_toggle_checksum(l, t, LIBNET_ON);
1088
1089 /* set Ethertype to IPv4 */
1090 ethertype = ETHERTYPE_IP;
1091
1092 break;
1093 }
1094 #ifdef WITH_IPV6
1095 case AF_INET6: {
1096 struct libnet_in6_addr src, dst;
1097 memcpy(&src, sip->addr, sizeof(src));
1098 memcpy(&dst, tip->addr, sizeof(dst));
1099 t = libnet_build_ipv6(
1100 0, /* traffic class */
1101 0, /* flow label */
1102 LIBNET_UDP_H + LIBNET_UDP_DNSV4_H + datalen, /* payload length */
1103 IPPROTO_UDP, /* next header */
1104 255, /* hop limit */
1105 src, /* source IP */
1106 dst, /* destination IP */
1107 NULL, /* payload */
1108 0, /* payload size */
1109 l, /* libnet handle */
1110 0);
1111 ON_ERROR(t, -1, "libnet_build_ipv6: %s", libnet_geterror(l));
1112
1113 /* set Ethertype to IPv6 */
1114 ethertype = ETHERTYPE_IPV6;
1115
1116 break;
1117 }
1118 #endif
1119 };
1120
1121 /* add the media header */
1122 t = ec_build_link_layer(EC_GBL_PCAP->dlt, tmac, ethertype, l);
1123 if (t == -1)
1124 FATAL_ERROR("Interface not suitable for layer2 sending");
1125
1126 /* send the packet to Layer 2 */
1127 c = libnet_write(l);
1128 ON_ERROR(c, -1, "libnet_write (%d): %s", c, libnet_geterror(l));
1129
1130 /* clear the pblock */
1131 libnet_clear_packet(l);
1132
1133 SEND_UNLOCK;
1134
1135 return c;
1136 }
1137
1138 /*
1139 * send a dns reply
1140 */
send_dns_reply(struct iface_env * iface,u_int16 dport,struct ip_addr * sip,struct ip_addr * tip,u_int8 * tmac,u_int16 id,u_int8 * data,size_t datalen,u_int16 anws_rr,u_int16 auth_rr,u_int16 addi_rr)1141 int send_dns_reply(struct iface_env *iface, u_int16 dport, struct ip_addr *sip, struct ip_addr *tip, u_int8 *tmac, u_int16 id, u_int8 *data, size_t datalen, u_int16 anws_rr, u_int16 auth_rr, u_int16 addi_rr)
1142 {
1143 libnet_ptag_t t;
1144 int c, proto, ethertype;
1145 libnet_t *l;
1146
1147 proto = ntohs(sip->addr_type);
1148
1149 /* if not lnet warn the developer ;) */
1150 BUG_IF(iface->lnet == 0);
1151 l = iface->lnet;
1152
1153 SEND_LOCK;
1154
1155 /* create the dns packet */
1156 t = libnet_build_dnsv4(
1157 LIBNET_UDP_DNSV4_H, /* TCP or UDP */
1158 id, /* id */
1159 0x8400, /* standard reply, no error */
1160 1, /* num_q */
1161 anws_rr, /* num_anws_rr */
1162 auth_rr, /* num_auth_rr */
1163 addi_rr, /* num_addi_rr */
1164 data,
1165 datalen,
1166 l, /* libnet handle */
1167 0); /* libnet id */
1168 ON_ERROR(t, -1, "libnet_build_dns: %s", libnet_geterror(l));
1169 /* create the udp header */
1170 t = libnet_build_udp(
1171 53, /* source port */
1172 htons(dport), /* destination port */
1173 LIBNET_UDP_H + LIBNET_UDP_DNSV4_H + datalen, /* packet size */
1174 0, /* checksum */
1175 NULL, /* payload */
1176 0, /* payload size */
1177 l, /* libnet handle */
1178 0); /* libnet id */
1179 ON_ERROR(t, -1, "libnet_build_udp: %s", libnet_geterror(l));
1180 /* auto calculate the checksum */
1181 libnet_toggle_checksum(l, t, LIBNET_ON);
1182
1183 /* create the IP header */
1184 switch (proto) {
1185 case AF_INET: {
1186 t = libnet_build_ipv4(
1187 LIBNET_IPV4_H + LIBNET_UDP_H + LIBNET_UDP_DNSV4_H + datalen, /* length */
1188 0, /* TOS */
1189 htons(EC_MAGIC_16), /* IP ID */
1190 0, /* IP Frag */
1191 64, /* TTL */
1192 IPPROTO_UDP, /* protocol */
1193 0, /* checksum */
1194 *sip->addr32, /* source IP */
1195 *tip->addr32, /* destination IP */
1196 NULL, /* payload */
1197 0, /* payload size */
1198 l, /* libnet handle */
1199 0);
1200 ON_ERROR(t, -1, "libnet_build_ipv4: %s", libnet_geterror(l));
1201 /* auto calculate the checksum */
1202 libnet_toggle_checksum(l, t, LIBNET_ON);
1203
1204 /* set Ethertype to IPv4 */
1205 ethertype = ETHERTYPE_IP;
1206
1207 break;
1208 }
1209 #ifdef WITH_IPV6
1210 case AF_INET6: {
1211 struct libnet_in6_addr src, dst;
1212 memcpy(&src, sip->addr, sizeof(src));
1213 memcpy(&dst, tip->addr, sizeof(dst));
1214 t = libnet_build_ipv6(
1215 0, /* traffic class */
1216 0, /* flow label */
1217 LIBNET_UDP_H + LIBNET_UDP_DNSV4_H + datalen, /* payload length */
1218 IPPROTO_UDP, /* next header */
1219 255, /* hop limit */
1220 src, /* source IP */
1221 dst, /* destination IP */
1222 NULL, /* payload */
1223 0, /* payload size */
1224 l, /* libnet handle */
1225 0);
1226 ON_ERROR(t, -1, "libnet_build_ipv6: %s", libnet_geterror(l));
1227
1228 /* set Ethertype to IPv6 */
1229 ethertype = ETHERTYPE_IPV6;
1230
1231 break;
1232 }
1233 #endif
1234 };
1235
1236 /* add the media header */
1237 t = ec_build_link_layer(EC_GBL_PCAP->dlt, tmac, ethertype, l);
1238 if (t == -1)
1239 FATAL_ERROR("Interface not suitable for layer2 sending");
1240
1241 /* send the packet to Layer 2 */
1242 c = libnet_write(l);
1243 ON_ERROR(c, -1, "libnet_write (%d): %s", c, libnet_geterror(l));
1244
1245 /* clear the pblock */
1246 libnet_clear_packet(l);
1247
1248 SEND_UNLOCK;
1249
1250 return c;
1251 }
1252
1253 /*
1254 * send an udp packet
1255 */
send_udp(struct ip_addr * sip,struct ip_addr * tip,u_int8 * tmac,u_int16 sport,u_int16 dport,u_int8 * payload,size_t length)1256 int send_udp(struct ip_addr *sip, struct ip_addr *tip, u_int8 *tmac, u_int16 sport, u_int16 dport, u_int8 *payload, size_t length)
1257 {
1258 libnet_ptag_t t;
1259 libnet_t *l;
1260
1261 int c, proto, ethertype;
1262
1263 proto = ntohs(sip->addr_type);
1264
1265 l = EC_GBL_IFACE->lnet;
1266 BUG_IF(EC_GBL_IFACE->lnet == 0);
1267
1268 SEND_LOCK;
1269
1270
1271 /*
1272 * libnet_build_udp(uint16_t sp, uint16_t dp, uint16_t len, uint16_t sum,
1273 const uint8_t *payload, uint32_t payload_s, libnet_t *l, libnet_ptag_t ptag)
1274 */
1275 t = libnet_build_udp(
1276 htons(sport),
1277 htons(dport),
1278 LIBNET_UDP_H + length,
1279 0,
1280 payload,
1281 length,
1282 l,
1283 0);
1284 ON_ERROR(t, -1, "libnet_build_udp: %s", libnet_geterror(l));
1285
1286 /* auto calculate checksum */
1287 libnet_toggle_checksum(l, t, LIBNET_ON);
1288
1289 /* create IP header */
1290 switch(proto) {
1291 case AF_INET: {
1292 t = libnet_build_ipv4(
1293 LIBNET_IPV4_H + LIBNET_UDP_H + length, /* length */
1294 0, /* TOS */
1295 htons(EC_MAGIC_16), /* IP ID */
1296 0, /* IP FRAG */
1297 64, /* TTL */
1298 IPPROTO_UDP, /* protocol */
1299 0, /* checksum */
1300 *sip->addr32, /* source IP */
1301 *tip->addr32, /* destination IP */
1302 NULL,
1303 0, /* payload size */
1304 l,
1305 0);
1306
1307 libnet_toggle_checksum(l, t, LIBNET_ON);
1308
1309 /* set Ethertype to IPv4 */
1310 ethertype = ETHERTYPE_IP;
1311
1312 break;
1313 }
1314
1315 #ifdef WITH_IPV6
1316 case AF_INET6: {
1317 struct libnet_in6_addr src, dst;
1318 memcpy(&src, sip->addr, sizeof(src));
1319 memcpy(&dst, tip->addr, sizeof(dst));
1320 t = libnet_build_ipv6(
1321 0, /* tc */
1322 0, /* flow label */
1323 LIBNET_UDP_H + length, /* payload length */
1324 IPPROTO_UDP, /* protocol */
1325 255, /* hop limit */
1326 src, /* source */
1327 dst, /* destination */
1328 NULL, /* payload */
1329 0, /* its length */
1330 l, /* handle */
1331 0); /* ptag */
1332
1333 /* set Ethertype to IPv6 */
1334 ethertype = ETHERTYPE_IPV6;
1335
1336 break;
1337 }
1338 #endif
1339 };
1340
1341 ON_ERROR(t, -1, "libnet_build_ipvX: %s", libnet_geterror(l));
1342
1343 /* add the media header */
1344 t = ec_build_link_layer(EC_GBL_PCAP->dlt, tmac, ethertype, l);
1345 if (t == -1)
1346 FATAL_ERROR("Interface not suitable for layer2 sending");
1347
1348 /* send the packet to Layer 3 */
1349
1350 c = libnet_write(l);
1351 ON_ERROR(c, -1, "libnet_write (%d): %s", c, libnet_geterror(l));
1352
1353 /* clear the block */
1354 libnet_clear_packet(l);
1355 SEND_UNLOCK;
1356
1357 return c;
1358 }
1359 /*
1360 * send a tcp packet
1361 */
send_tcp(struct ip_addr * sip,struct ip_addr * tip,u_int16 sport,u_int16 dport,u_int32 seq,u_int32 ack,u_int8 flags,u_int8 * payload,size_t length)1362 int send_tcp(struct ip_addr *sip, struct ip_addr *tip, u_int16 sport, u_int16 dport, u_int32 seq, u_int32 ack, u_int8 flags, u_int8 *payload, size_t length)
1363 {
1364 libnet_ptag_t t;
1365 libnet_t *l;
1366 int proto;
1367 int c;
1368
1369 proto = ntohs(sip->addr_type);
1370 l = (proto == AF_INET) ? EC_GBL_LNET->lnet_IP4 : EC_GBL_LNET->lnet_IP6;
1371 /* if not lnet warn the developer ;) */
1372 BUG_IF(l == NULL);
1373
1374 SEND_LOCK;
1375
1376
1377 t = libnet_build_tcp(
1378 ntohs(sport), /* source port */
1379 ntohs(dport), /* destination port */
1380 ntohl(seq), /* sequence number */
1381 ntohl(ack), /* acknowledgement num */
1382 flags, /* control flags */
1383 32767, /* window size */
1384 0, /* checksum */
1385 0, /* urgent pointer */
1386 LIBNET_TCP_H + length, /* TCP packet size */
1387 payload, /* payload */
1388 length, /* payload size */
1389 l, /* libnet handle */
1390 0); /* libnet id */
1391 ON_ERROR(t, -1, "libnet_build_tcp: %s", libnet_geterror(l));
1392
1393 /* auto calculate the checksum */
1394 libnet_toggle_checksum(l, t, LIBNET_ON);
1395
1396 /* create the IP header */
1397 switch(proto) {
1398 case AF_INET: {
1399 t = libnet_build_ipv4(
1400 LIBNET_IPV4_H + LIBNET_TCP_H, /* length */
1401 0, /* TOS */
1402 htons(EC_MAGIC_16), /* IP ID */
1403 0, /* IP Frag */
1404 64, /* TTL */
1405 IPPROTO_TCP, /* protocol */
1406 0, /* checksum */
1407 *sip->addr32, /* source IP */
1408 *tip->addr32, /* destination IP */
1409 NULL, /* payload */
1410 0, /* payload size */
1411 l, /* libnet handle */
1412 0);
1413 libnet_toggle_checksum(l, t, LIBNET_ON);
1414 break;
1415 }
1416 #ifdef WITH_IPV6
1417 case AF_INET6: {
1418 struct libnet_in6_addr src, dst;
1419 memcpy(&src, sip->addr, sizeof(src));
1420 memcpy(&dst, tip->addr, sizeof(dst));
1421 t = libnet_build_ipv6(
1422 0, /* tc */
1423 0, /* flow label */
1424 LIBNET_TCP_H, /* payload length */
1425 IPPROTO_TCP, /* protocol */
1426 255, /* hop limit */
1427 src, /* source address */
1428 dst, /* destination address */
1429 NULL, /* payload */
1430 0, /* its length */
1431 l, /* handle */
1432 0); /* ptag */
1433 break;
1434 }
1435 #endif
1436 };
1437 ON_ERROR(t, -1, "libnet_build_ipvX: %s", libnet_geterror(l));
1438
1439 /* send the packet to Layer 3 */
1440 c = libnet_write(l);
1441 ON_ERROR(c, -1, "libnet_write (%d): %s", c, libnet_geterror(l));
1442
1443 /* clear the pblock */
1444 libnet_clear_packet(l);
1445
1446 SEND_UNLOCK;
1447
1448 return c;
1449 }
1450
1451 /*
1452 * similar to send_tcp but the user can specify the destination mac addresses
1453 */
send_tcp_ether(u_int8 * dmac,struct ip_addr * sip,struct ip_addr * tip,u_int16 sport,u_int16 dport,u_int32 seq,u_int32 ack,u_int8 flags)1454 int send_tcp_ether(u_int8 *dmac, struct ip_addr *sip, struct ip_addr *tip, u_int16 sport, u_int16 dport, u_int32 seq, u_int32 ack, u_int8 flags)
1455 {
1456 libnet_ptag_t t;
1457 int c, proto, ethertype;
1458 libnet_t *l;
1459
1460 proto = ntohs(sip->addr_type);
1461
1462 /* if not lnet warn the developer ;) */
1463 BUG_IF(EC_GBL_IFACE->lnet == 0);
1464 l = EC_GBL_IFACE->lnet;
1465
1466 SEND_LOCK;
1467
1468 t = libnet_build_tcp(
1469 ntohs(sport), /* source port */
1470 ntohs(dport), /* destination port */
1471 ntohl(seq), /* sequence number */
1472 ntohl(ack), /* acknowledgement num */
1473 flags, /* control flags */
1474 32767, /* window size */
1475 0, /* checksum */
1476 0, /* urgent pointer */
1477 LIBNET_TCP_H, /* TCP packet size */
1478 NULL, /* payload */
1479 0, /* payload size */
1480 l, /* libnet handle */
1481 0); /* libnet id */
1482 ON_ERROR(t, -1, "libnet_build_tcp: %s", libnet_geterror(l));
1483 /* auto calculate the checksum */
1484 libnet_toggle_checksum(l, t, LIBNET_ON);
1485
1486 switch (proto) {
1487 case AF_INET: {
1488 /* create the IP header */
1489 t = libnet_build_ipv4(
1490 LIBNET_IPV4_H + LIBNET_TCP_H, /* length */
1491 0, /* TOS */
1492 htons(EC_MAGIC_16), /* IP ID */
1493 0, /* IP Frag */
1494 64, /* TTL */
1495 IPPROTO_TCP, /* protocol */
1496 0, /* checksum */
1497 *sip->addr32, /* source IP */
1498 *tip->addr32, /* destination IP */
1499 NULL, /* payload */
1500 0, /* payload size */
1501 l, /* libnet handle */
1502 0);
1503 ON_ERROR(t, -1, "libnet_build_ipv4: %s", libnet_geterror(l));
1504
1505 /* auto calculate the checksum */
1506 libnet_toggle_checksum(l, t, LIBNET_ON);
1507
1508 /* set Ethertype to IPv4 */
1509 ethertype = ETHERTYPE_IP;
1510
1511 break;
1512 }
1513 #ifdef WITH_IPV6
1514 case AF_INET6: {
1515 struct libnet_in6_addr src, dst;
1516 memcpy(&src, sip->addr, sizeof(src));
1517 memcpy(&dst, tip->addr, sizeof(dst));
1518 t = libnet_build_ipv6(
1519 0, /* traffic class */
1520 0, /* flow label */
1521 LIBNET_TCP_H, /* payload length */
1522 IPPROTO_TCP, /* next header */
1523 255, /* hop limit */
1524 src, /* source IP */
1525 dst, /* destination IP */
1526 NULL, /* payload */
1527 0, /* payload size */
1528 l, /* libnet handle */
1529 0);
1530 ON_ERROR(t, -1, "libnet_build_ipv6: %s", libnet_geterror(l));
1531
1532 /* set Ethertype to IPv6 */
1533 ethertype = ETHERTYPE_IPV6;
1534
1535 break;
1536 }
1537 #endif
1538
1539 }
1540
1541 /* add the media header */
1542 t = ec_build_link_layer(EC_GBL_PCAP->dlt, dmac, ethertype, l);
1543 if (t == -1)
1544 FATAL_ERROR("Interface not suitable for layer2 sending");
1545
1546 /* send the packet to Layer 3 */
1547 c = libnet_write(l);
1548 ON_ERROR(c, -1, "libnet_write (%d): %s", c, libnet_geterror(l));
1549
1550 /* clear the pblock */
1551 libnet_clear_packet(l);
1552
1553 SEND_UNLOCK;
1554
1555 return c;
1556 }
1557
1558
1559 /* EOF */
1560
1561 // vim:ts=3:expandtab
1562
1563