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