From e4d1e6bb813a86c32cd6a7657725e04b52893e7e Mon Sep 17 00:00:00 2001 From: Sharad B Date: Fri, 13 Jan 2017 08:10:05 +0530 Subject: [PATCH 1/3] 0. Checking in working IPV6 support with TCP and UDP payloads. 1. A new "-6" argument is added which *must be* specified before the "-t " argument. This seems to be a problem with the argument parser (the way it is used?) and still needs to be fixed. 2. print_injection() needs to understand ipv6 3. Fixed function arguments that got renamed to have "g_" prefix 4. See g_ip6hdr_o's definition in src/inject_defs.h for the command line arguments to specify various IP6 header fields. 5. Documentation needs to be updated --- src/Makefile.am | 3 +- src/define_defaults.c | 3 +- src/globals.h | 1 + src/init.c | 3 + src/inject_defs.h | 18 ++++ src/main.c | 182 +++++++++++++++++++++++++++------------ src/print_injection.c | 5 +- src/shape_arp_hdr.c | 28 +++--- src/shape_defs.h | 2 + src/shape_ethernet_hdr.c | 16 ++-- src/shape_icmpv4_hdr.c | 92 ++++++++++---------- src/shape_ipv4_hdr.c | 16 ++-- src/shape_packet.c | 17 +++- src/shape_tcp_hdr.c | 18 ++-- src/shape_udp_hdr.c | 13 +-- src/usage.c | 1 + src/utils.c | 10 +++ src/utils.h | 1 + 18 files changed, 282 insertions(+), 147 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index 41fc9f8..477739e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -41,7 +41,8 @@ common_SOURCES = init.c \ shape_packet.c \ utils.c \ stats.c \ - contrib/pcap_setnonblock.c + contrib/pcap_setnonblock.c \ + shape_ipv6_hdr.c packit_SOURCES = ${common_SOURCES} \ usage.c \ diff --git a/src/define_defaults.c b/src/define_defaults.c index 1bf70ac..e494d26 100644 --- a/src/define_defaults.c +++ b/src/define_defaults.c @@ -29,6 +29,7 @@ void define_injection_defaults() { + g_ipv6 = 0; g_cnt = (g_p_mode == M_INJECT) ? 1 : 30; g_inj_cnt = 1; g_cap_cnt = 0; @@ -44,7 +45,7 @@ define_injection_defaults() g_rand_d_port = (g_p_mode == M_TRACE) ? 1 : 0; g_r_timeout = 1; g_burst_rate = 1; - g_init_type = 1; + g_init_type = LIBNET_RAW4; g_interval_sec = 1; g_interval_usec = 0; g_payload = NULL; diff --git a/src/globals.h b/src/globals.h index 9121997..f20a469 100644 --- a/src/globals.h +++ b/src/globals.h @@ -119,6 +119,7 @@ #define ETHERTYPE_IP 0x0800 /* internet protocol */ #define ETHERTYPE_ARP 0x0806 /* addr. resolution protocol */ #define ETHERTYPE_REVARP 0x8035 /* reverse addr. resolution protocol */ +#define ETHERTYPE_IP6 0x86DD /* internet IPv6 protocol */ #define OPT_MAXLEN 32 diff --git a/src/init.c b/src/init.c index 3ae3cf0..90f285f 100644 --- a/src/init.c +++ b/src/init.c @@ -93,5 +93,8 @@ injection_struct_init() g_i4hdr_o.rtime = 0; g_i4hdr_o.ttime = 0; + // Reset IPv6 related structure + memset(&g_ip6hdr_o, 0, sizeof(g_ip6hdr_o)); + return; } diff --git a/src/inject_defs.h b/src/inject_defs.h index f4bb02c..09ff32d 100644 --- a/src/inject_defs.h +++ b/src/inject_defs.h @@ -57,6 +57,23 @@ struct ip4hdr_opts u_int16_t rand_d_addr; } g_ip4hdr_o; +struct ip6hdr_opts +{ + u_int8_t traffic_class; // -o : equivalent of type of service + u_int32_t flow_label; // -n : + u_int16_t length; + u_int8_t next_header; // assumed to be TCP today + u_int8_t hop_limit; // -T : equivalent of TTL + + u_int8_t rand_src_addr; // -sR : if set to 1, src is NULL + char * src_str; // -s : string representation of source address + struct libnet_in6_addr src; + + u_int8_t rand_dst_addr; // -dR : if set to 1, dst is NULL + char * dst_str; // -d : string represntation of destination address + struct libnet_in6_addr dst; +} g_ip6hdr_o; + struct tcphdr_opts { u_int16_t s_port; /* tcp source port */ @@ -180,6 +197,7 @@ u_int8_t g_hex_payload; u_int8_t *g_s_d_port; u_int8_t g_hwaddr_p[18]; u_int8_t g_rawip; +u_int8_t g_ipv6; // Injecting IPv6 packets struct timeval g_bf_pcap; struct timeval g_af_pcap; diff --git a/src/main.c b/src/main.c index 7e869aa..22430ca 100644 --- a/src/main.c +++ b/src/main.c @@ -112,42 +112,72 @@ parse_inject_options(int argc, char *argv[], u_int16_t iopt) define_injection_defaults(); injection_struct_init(); - while((opt = getopt(argc, argv, "t:")) != -1) + if((opt=getopt(argc, argv, "6:")) != -1) + { + switch(opt) { + case '6': + g_init_type = LIBNET_RAW6; + g_ipv6 = 1; + optind = 1; + break; + default: + break; + } + } + + while((opt = getopt(argc, argv, "t:6:")) != -1) { switch(opt) { case 't': - if(!strncasecmp(optarg, "TCP", 3)) + if(!strncasecmp(optarg, "TCP", 3)) { #ifdef DEBUG fprintf(stdout, "DEBUG: TCP injection\n"); #endif - g_ip4hdr_o.p = IPPROTO_TCP; - g_injection_type = ETHERTYPE_IP; - opts = "a:b:c:d:D:e:E:fF:hH:i:n:p:q:Rs:S:T:o:u:vw:W:Z:"; + + if(g_ipv6) + { + g_ip6hdr_o.next_header = IPPROTO_TCP; // next_header defines the + // protocol of the + // payload + g_injection_type = ETHERTYPE_IP6; + } + else + { + g_ip4hdr_o.p = IPPROTO_TCP; + g_injection_type = ETHERTYPE_IP; + } + opts = "6:a:b:c:d:D:e:E:fF:hH:i:n:p:q:Rs:S:T:o:u:vw:W:Z:"; } - else - if(!strncasecmp(optarg, "UDP", 3)) + else if(!strncasecmp(optarg, "UDP", 3)) { #ifdef DEBUG fprintf(stdout, "DEBUG: UDP injection\n"); #endif - g_ip4hdr_o.p = IPPROTO_UDP; - g_injection_type = ETHERTYPE_IP; - opts = "b:c:d:D:e:E:fhH:i:n:o:p:Rs:S:T:vw:Z:"; + if(g_ipv6) + { + g_ip6hdr_o.next_header = IPPROTO_UDP; + g_injection_type = ETHERTYPE_IP6; + } + else + { + g_ip4hdr_o.p = IPPROTO_UDP; + g_injection_type = ETHERTYPE_IP; + } + opts = "6:b:c:d:D:e:E:fhH:i:n:o:p:Rs:S:T:vw:Z:"; } - else - if(!strncasecmp(optarg, "ICMP", 4)) + else if(!strncasecmp(optarg, "ICMP", 4)) { #ifdef DEBUG fprintf(stdout, "DEBUG: ICMP injection\n"); #endif + g_ipv6 = 0; g_ip4hdr_o.p = IPPROTO_ICMP; g_injection_type = ETHERTYPE_IP; opts = "b:c:C:d:e:E:fg:G:hH:i:j:J:k:K:l:L:m:M:n:N:o:O:p:P:Q:Rs:t:T:U:vw:z:Z:"; } - else - if(!strncasecmp(optarg, "ARP", 3)) + else if(!strncasecmp(optarg, "ARP", 3)) { if(g_p_mode == M_TRACE) fatal_error("ARP is not supported with trace mode."); @@ -158,12 +188,12 @@ parse_inject_options(int argc, char *argv[], u_int16_t iopt) fprintf(stderr, "\nError: ARP injection is not yet supported on this OS platform.\n"); exit(FAILURE); #endif + g_ipv6 = 0; g_injection_type = ETHERTYPE_ARP; g_init_type = 0; opts = "A:b:c:e:E:i:p:Rs:S:vx:X:y:Y:"; } - else - if(!strncasecmp(optarg, "RARP", 4)) + else if(!strncasecmp(optarg, "RARP", 4)) { if(g_p_mode == M_TRACE) fatal_error("RARP is not supported with trace mode."); @@ -174,19 +204,20 @@ parse_inject_options(int argc, char *argv[], u_int16_t iopt) fprintf(stderr, "\nError: RARP injection is not yet supported on this OS platform.\n"); exit(FAILURE); #endif + g_ipv6 = 0; g_injection_type = ETHERTYPE_REVARP; g_ahdr_o.op_type = ARPOP_REVREQUEST; /* Update init */ g_init_type = 0; opts = "A:b:c:e:E:i:p:Rs:S:vx:X:y:Y:"; } - else - if(!strncasecmp(optarg, "RAWIP", 3)) + else if(!strncasecmp(optarg, "RAWIP", 3)) { if(g_p_mode == M_TRACE) fatal_error("RAW is not supported with trace mode."); #ifdef DEBUG fprintf(stdout, "DEBUG: raw IP injection\n"); #endif + g_ipv6 = 0; g_rawip = g_ip4hdr_o.p = IPPROTO_RAW; g_injection_type = ETHERTYPE_IP; opts = "b:c:d:e:E:f:i:n:o:p:Rs:T:U:vV:w:Z:"; @@ -204,13 +235,23 @@ parse_inject_options(int argc, char *argv[], u_int16_t iopt) if(g_p_mode == M_TRACE) { + g_ipv6 = 0; g_ip4hdr_o.p = IPPROTO_ICMP; opts = "b:c:C:d:e:E:fg:G:hH:i:j:J:k:K:l:L:m:M:n:N:o:O:p:P:Q:Rs:t:T:U:vw:z:Z:"; } else { - g_ip4hdr_o.p = IPPROTO_TCP; - opts = "a:b:c:d:D:e:E:fF:hH:i:n:p:q:Rs:S:T:o:u:vw:W:Z:"; + if(g_ipv6) + { + g_ip6hdr_o.next_header = IPPROTO_TCP; + g_injection_type = ETHERTYPE_IP6; + } + else + { + g_ip4hdr_o.p = IPPROTO_TCP; + g_injection_type = ETHERTYPE_IP; + } + opts = "6:a:b:c:d:D:e:E:fF:hH:i:n:p:q:Rs:S:T:o:u:vw:W:Z:"; } goto parse_inject; @@ -219,7 +260,7 @@ parse_inject_options(int argc, char *argv[], u_int16_t iopt) } } -print_usage(); + print_usage(); parse_inject: #ifdef DEBUG @@ -250,15 +291,26 @@ print_usage(); break; case 'C': + // ICMP code g_i4hdr_o.code = (u_int16_t)atoi(optarg); break; case 'd': - if(strlen(optarg) == 1 && !strncmp(optarg, "R", 1)) - g_ip4hdr_o.rand_d_addr = 1; + if(g_ipv6) + { + if(strlen(optarg) == 1 && !strncmp(optarg, "R", 1)) + g_ip6hdr_o.rand_dst_addr = 1; + else if(!(g_ip6hdr_o.dst_str = strdup(optarg))) + fatal_error("Memory unavailable for: %s", optarg); + } + else + { + if(strlen(optarg) == 1 && !strncmp(optarg, "R", 1)) + g_ip4hdr_o.rand_d_addr = 1; - if(!(g_ip4hdr_o.d_addr = (u_int8_t*)strdup(optarg))) - fatal_error("Memory unavailable for: %s", optarg); + if(!(g_ip4hdr_o.d_addr = (u_int8_t*)strdup(optarg))) + fatal_error("Memory unavailable for: %s", optarg); + } break; @@ -273,14 +325,14 @@ print_usage(); case 'e': #ifdef MACOS - fprintf(stderr, "\nWarning: You cannot specify an ethernet address on this operating system.\n"); - break; + fprintf(stderr, "\nWarning: You cannot specify an ethernet address on this operating system.\n"); + break; #endif - if(strlen(optarg) == 1 && !strncmp(optarg, "R", 1)) + if(strlen(optarg) == 1 && !strncmp(optarg, "R", 1)) g_ehdr_o.rand_s_addr = 1; - if(!(g_ehdr_o.s_addr = (u_int8_t*)strdup(optarg))) - fatal_error("Memory unavailable for: %s", optarg); + if(!(g_ehdr_o.s_addr = (u_int8_t*)strdup(optarg))) + fatal_error("Memory unavailable for: %s", optarg); g_init_type = 0; g_link_layer = 1; @@ -295,15 +347,15 @@ print_usage(); g_ehdr_o.rand_d_addr = 1; if(!(g_ehdr_o.d_addr = (u_int8_t*)strdup(optarg))) - fatal_error("Memory unavailable for: %s", optarg); + fatal_error("Memory unavailable for: %s", optarg); g_init_type = 0; g_link_layer = 1; break; - case 'f': - g_ip4hdr_o.frag = 0x4000; - break; + case 'f': + g_ip4hdr_o.frag = 0x4000; + break; case 'F': if(strrchr(optarg, 'U')) @@ -341,11 +393,11 @@ print_usage(); break; - case 'h': + case 'h': if(g_p_mode == M_INJECT) - g_p_mode = M_INJECT_RESPONSE; + g_p_mode = M_INJECT_RESPONSE; - break; + break; case 'H': g_r_timeout = (u_int8_t)atoi(optarg); @@ -353,7 +405,7 @@ print_usage(); case 'i': if(!(g_device = strdup(optarg))) - fatal_error("Memory unavailable for: %s", optarg); + fatal_error("Memory unavailable for: %s", optarg); break; @@ -411,8 +463,15 @@ print_usage(); break; case 'n': - g_ip4hdr_o.id = (u_int16_t)atoi(optarg); - g_ip4hdr_o.rand_id = 0; + if(g_ipv6) + { + g_ip6hdr_o.flow_label = atoi(optarg); + } + else + { + g_ip4hdr_o.id = (u_int16_t)atoi(optarg); + g_ip4hdr_o.rand_id = 0; + } break; case 'N': @@ -423,7 +482,11 @@ print_usage(); break; case 'o': - g_ip4hdr_o.tos = (u_int8_t)atoi(optarg); + if(g_ipv6) + g_ip6hdr_o.traffic_class = atoi(optarg); + else + g_ip4hdr_o.tos = (u_int8_t)atoi(optarg); + break; case 'O': @@ -435,18 +498,16 @@ print_usage(); g_hex_payload = 1; if(!(g_payload = (u_int8_t*)strdup(optarg))) - fatal_error("Memory unavailable for: %s", optarg); + fatal_error("Memory unavailable for: %s", optarg); break; case 'P': if(!strcasecmp(optarg, "UDP")) g_i4hdr_o.orig_p = 17; - else - if(!strncasecmp(optarg, "TCP", 3)) + else if(!strncasecmp(optarg, "TCP", 3)) g_i4hdr_o.orig_p = 6; - else - if(!strncasecmp(optarg, "ICMP", 4)) + else if(!strncasecmp(optarg, "ICMP", 4)) g_i4hdr_o.orig_p = 1; else fatal_error("Unknown ICMP original protocol: %s", optarg); @@ -470,11 +531,21 @@ print_usage(); break; case 's': - if(strlen(optarg) == 1 && !strncmp(optarg, "R", 1)) - g_ip4hdr_o.rand_s_addr = 1; + if(g_ipv6) + { + if(strlen(optarg) == 1 && !strncmp(optarg, "R", 1)) + g_ip6hdr_o.rand_src_addr = 1; + else if(!(g_ip6hdr_o.src_str = strdup(optarg))) + fatal_error("Memory unavailable for: %s", optarg); + } + else + { + if(strlen(optarg) == 1 && !strncmp(optarg, "R", 1)) + g_ip4hdr_o.rand_s_addr = 1; - if(!(g_ip4hdr_o.s_addr = (u_int8_t*)strdup(optarg))) - fatal_error("Memory unavailable for: %s", optarg); + if(!(g_ip4hdr_o.s_addr = (u_int8_t*)strdup(optarg))) + fatal_error("Memory unavailable for: %s", optarg); + } break; case 'S': @@ -487,10 +558,15 @@ print_usage(); break; case 'T': - if(atoi(optarg) > 0xFF) - fatal_error("Invalid TTL value: %s", optarg); + if(g_ipv6) + g_ip6hdr_o.hop_limit = atoi(optarg); + else + { + if(atoi(optarg) > 0xFF) + fatal_error("Invalid TTL value: %s", optarg); - g_ip4hdr_o.ttl = (u_int16_t)atoi(optarg); + g_ip4hdr_o.ttl = (u_int16_t)atoi(optarg); + } break; diff --git a/src/print_injection.c b/src/print_injection.c index 76c2fc6..5e55013 100644 --- a/src/print_injection.c +++ b/src/print_injection.c @@ -39,7 +39,10 @@ print_injection_details() if(g_injection_type == ETHERTYPE_IP) { #ifdef DEBUG - fprintf(stdout, "DEBUG: ETHERTYPE_IP\n"); + if(g_ipv6) + fprintf(stdout, "DEBUG: ETHERTYPE_IP6\n"); + else + fprintf(stdout, "DEBUG: ETHERTYPE_IP\n"); #endif g_thdr_o.flags[0] = '\0'; diff --git a/src/shape_arp_hdr.c b/src/shape_arp_hdr.c index 5151fc1..c5efae2 100644 --- a/src/shape_arp_hdr.c +++ b/src/shape_arp_hdr.c @@ -26,7 +26,7 @@ #include "shape_arp_hdr.h" libnet_t * -shape_arp_hdr(libnet_t *g_pkt_d) +shape_arp_hdr(libnet_t *pkt_d) { u_int32_t i, s_paddr, r_paddr; u_int8_t s_neaddr[6]; @@ -60,8 +60,8 @@ shape_arp_hdr(libnet_t *g_pkt_d) switch(g_ahdr_o.op_type) { case ARPOP_REQUEST: case ARPOP_REVREQUEST: - if((s_paddr = libnet_get_ipaddr4(g_pkt_d)) == -1) - fatal_error("Unable to retrieve local IP address: %s", libnet_geterror(g_pkt_d)); + if((s_paddr = libnet_get_ipaddr4(pkt_d)) == -1) + fatal_error("Unable to retrieve local IP address: %s", libnet_geterror(pkt_d)); g_ahdr_o.s_paddr = (u_int8_t*)libnet_addr2name4(s_paddr, 0); break; @@ -72,7 +72,7 @@ shape_arp_hdr(libnet_t *g_pkt_d) } } - if((s_paddr = libnet_name2addr4(g_pkt_d, (char*)g_ahdr_o.s_paddr, 0)) == -1) + if((s_paddr = libnet_name2addr4(pkt_d, (char*)g_ahdr_o.s_paddr, 0)) == -1) fatal_error("Invalid sender protocol address: %s", g_ahdr_o.s_paddr); if(g_ahdr_o.s_eaddr == NULL) @@ -80,8 +80,8 @@ shape_arp_hdr(libnet_t *g_pkt_d) switch(g_ahdr_o.op_type) { case ARPOP_REQUEST: case ARPOP_REVREQUEST: - if((hw_addr = libnet_get_hwaddr(g_pkt_d)) == NULL) - fatal_error("Unable to determine ethernet address: %s", libnet_geterror(g_pkt_d)); + if((hw_addr = libnet_get_hwaddr(pkt_d)) == NULL) + fatal_error("Unable to determine ethernet address: %s", libnet_geterror(pkt_d)); for(i = 0; i < 6; i++) s_neaddr[i] = hw_addr->ether_addr_octet[i]; @@ -105,8 +105,8 @@ shape_arp_hdr(libnet_t *g_pkt_d) switch(g_ahdr_o.op_type) { case ARPOP_REPLY: case ARPOP_REQUEST: - if((r_paddr = libnet_get_ipaddr4(g_pkt_d)) == -1) - fatal_error("Unable to retrieve local IP address: %s", libnet_geterror(g_pkt_d)); + if((r_paddr = libnet_get_ipaddr4(pkt_d)) == -1) + fatal_error("Unable to retrieve local IP address: %s", libnet_geterror(pkt_d)); g_ahdr_o.r_paddr = (u_int8_t*)libnet_addr2name4(r_paddr, 0); break; @@ -117,7 +117,7 @@ shape_arp_hdr(libnet_t *g_pkt_d) } } - if((r_paddr = libnet_name2addr4(g_pkt_d, (char*)g_ahdr_o.r_paddr, 0)) == -1) + if((r_paddr = libnet_name2addr4(pkt_d, (char*)g_ahdr_o.r_paddr, 0)) == -1) fatal_error("Invalid receiver protocol address: %s", g_ahdr_o.r_paddr); if(g_ahdr_o.r_eaddr == NULL) @@ -125,8 +125,8 @@ shape_arp_hdr(libnet_t *g_pkt_d) switch(g_ahdr_o.op_type) { case ARPOP_REPLY: case ARPOP_REVREPLY: - if((hw_addr = libnet_get_hwaddr(g_pkt_d)) == NULL) - fatal_error("Unable to determine ethernet address: %s", libnet_geterror(g_pkt_d)); + if((hw_addr = libnet_get_hwaddr(pkt_d)) == NULL) + fatal_error("Unable to determine ethernet address: %s", libnet_geterror(pkt_d)); for(i = 0; i < 6; i++) r_neaddr[i] = hw_addr->ether_addr_octet[i]; @@ -157,11 +157,11 @@ shape_arp_hdr(libnet_t *g_pkt_d) (u_int8_t *)&r_paddr, g_payload, g_payload_len, - g_pkt_d, + pkt_d, 0) == -1) { - fatal_error("Unable to build ARP header: %s", libnet_geterror(g_pkt_d)); + fatal_error("Unable to build ARP header: %s", libnet_geterror(pkt_d)); } - return g_pkt_d; + return pkt_d; } diff --git a/src/shape_defs.h b/src/shape_defs.h index a36fb5f..0e942d4 100644 --- a/src/shape_defs.h +++ b/src/shape_defs.h @@ -33,4 +33,6 @@ #include "shape_tcp_hdr.h" #include "shape_udp_hdr.h" +#include "shape_ipv6_hdr.h" + #endif /* __SHAPE_DEFS_H */ diff --git a/src/shape_ethernet_hdr.c b/src/shape_ethernet_hdr.c index ba3d2b7..a02fe34 100644 --- a/src/shape_ethernet_hdr.c +++ b/src/shape_ethernet_hdr.c @@ -27,7 +27,7 @@ #include "shape_ethernet_hdr.h" libnet_t * -shape_ethernet_hdr(libnet_t *g_pkt_d) +shape_ethernet_hdr(libnet_t *pkt_d) { int i; u_int8_t us_addr[6]; @@ -50,8 +50,8 @@ shape_ethernet_hdr(libnet_t *g_pkt_d) if(g_ehdr_o.s_addr == NULL) { - if((hw_addr = libnet_get_hwaddr(g_pkt_d)) == NULL) - fatal_error("Unable to determine ethernet address: %s", libnet_geterror(g_pkt_d)); + if((hw_addr = libnet_get_hwaddr(pkt_d)) == NULL) + fatal_error("Unable to determine ethernet address: %s", libnet_geterror(pkt_d)); for(i = 0; i < 6; i++) us_addr[i] = hw_addr->ether_addr_octet[i]; @@ -86,17 +86,17 @@ shape_ethernet_hdr(libnet_t *g_pkt_d) g_injection_type, NULL, 0, - g_pkt_d, + pkt_d, 0) == -1) { fatal_error("Unable to build ethernet header"); } - return g_pkt_d; + return pkt_d; } libnet_t * -shape_ethernet_hdr_auto(libnet_t *g_pkt_d, u_int16_t type) +shape_ethernet_hdr_auto(libnet_t *pkt_d, u_int16_t type) { u_int8_t d_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; @@ -107,10 +107,10 @@ shape_ethernet_hdr_auto(libnet_t *g_pkt_d, u_int16_t type) if(libnet_autobuild_ethernet( d_addr, type, - g_pkt_d) == -1) + pkt_d) == -1) { fatal_error("Unable to auto-build ethernet header"); } - return g_pkt_d; + return pkt_d; } diff --git a/src/shape_icmpv4_hdr.c b/src/shape_icmpv4_hdr.c index ca5fecc..e5afca3 100644 --- a/src/shape_icmpv4_hdr.c +++ b/src/shape_icmpv4_hdr.c @@ -26,7 +26,7 @@ #include "shape_icmpv4_hdr.h" libnet_t * -shape_icmpv4_hdr(libnet_t *g_pkt_d) +shape_icmpv4_hdr(libnet_t *pkt_d) { u_int8_t ih_payload[8]; u_int32_t ih_payload_len = 8; @@ -70,10 +70,10 @@ shape_icmpv4_hdr(libnet_t *g_pkt_d) g_i4hdr_o.seqn, g_payload, g_payload_len, - g_pkt_d, + pkt_d, 0) == -1) { - fatal_error("Unable to build ICMPv4 echo header: %s", libnet_geterror(g_pkt_d)); + fatal_error("Unable to build ICMPv4 echo header: %s", libnet_geterror(pkt_d)); } break; @@ -106,13 +106,13 @@ shape_icmpv4_hdr(libnet_t *g_pkt_d) if(g_i4hdr_o.orig_s_addr == NULL) fatal_error("No original source IP address defined"); - if((ihn_saddr = libnet_name2addr4(g_pkt_d, (char*)g_i4hdr_o.orig_s_addr, 1)) == -1) + if((ihn_saddr = libnet_name2addr4(pkt_d, (char*)g_i4hdr_o.orig_s_addr, 1)) == -1) fatal_error("Invalid original source IP address: %s", g_i4hdr_o.orig_s_addr); if(g_i4hdr_o.orig_d_addr == NULL) fatal_error("No original destination IP address defined"); - if((ihn_daddr = libnet_name2addr4(g_pkt_d, (char*)g_i4hdr_o.orig_d_addr, 1)) == -1) + if((ihn_daddr = libnet_name2addr4(pkt_d, (char*)g_i4hdr_o.orig_d_addr, 1)) == -1) fatal_error("Invalid original destination IP address: %s", g_i4hdr_o.orig_d_addr); ih_payload[0] = (g_i4hdr_o.orig_s_port >> 8) & 0xff; @@ -153,10 +153,10 @@ shape_icmpv4_hdr(libnet_t *g_pkt_d) ihn_daddr, ih_payload, ih_payload_len, - g_pkt_d, + pkt_d, 0) == -1) { - fatal_error("Unable to build original IP header: %s", libnet_geterror(g_pkt_d)); + fatal_error("Unable to build original IP header: %s", libnet_geterror(pkt_d)); } if(libnet_build_icmpv4_unreach( @@ -165,10 +165,10 @@ shape_icmpv4_hdr(libnet_t *g_pkt_d) 0, NULL, 0, - g_pkt_d, + pkt_d, 0) == -1) { - fatal_error("Unable to build ICMPv4 unreach header: %s", libnet_geterror(g_pkt_d)); + fatal_error("Unable to build ICMPv4 unreach header: %s", libnet_geterror(pkt_d)); } } else @@ -184,7 +184,7 @@ shape_icmpv4_hdr(libnet_t *g_pkt_d) if(g_i4hdr_o.gw == NULL) fatal_error("No gateway IP address defined"); - if((ihn_gw = libnet_name2addr4(g_pkt_d, (char*)g_i4hdr_o.gw, 1)) == -1) + if((ihn_gw = libnet_name2addr4(pkt_d, (char*)g_i4hdr_o.gw, 1)) == -1) fatal_error("Invalid gateway IP address: %s", g_i4hdr_o.gw); g_hdr_len = ICMPV4_REDIRECT_H; @@ -208,10 +208,10 @@ shape_icmpv4_hdr(libnet_t *g_pkt_d) ihn_daddr, ih_payload, ih_payload_len, - g_pkt_d, + pkt_d, 0) == -1) { - fatal_error("Unable to build original IP header: %s", libnet_geterror(g_pkt_d)); + fatal_error("Unable to build original IP header: %s", libnet_geterror(pkt_d)); } if(libnet_build_icmpv4_redirect( @@ -221,10 +221,10 @@ shape_icmpv4_hdr(libnet_t *g_pkt_d) ihn_gw, NULL, 0, - g_pkt_d, + pkt_d, 0) == -1) { - fatal_error("Unable to build ICMPv4 redirect header: %s", libnet_geterror(g_pkt_d)); + fatal_error("Unable to build ICMPv4 redirect header: %s", libnet_geterror(pkt_d)); } } else @@ -255,10 +255,10 @@ shape_icmpv4_hdr(libnet_t *g_pkt_d) ihn_daddr, ih_payload, ih_payload_len, - g_pkt_d, + pkt_d, 0) == -1) { - fatal_error("Unable to build original IP header: %s", libnet_geterror(g_pkt_d)); + fatal_error("Unable to build original IP header: %s", libnet_geterror(pkt_d)); } if(libnet_build_icmpv4_timeexceed( @@ -267,10 +267,10 @@ shape_icmpv4_hdr(libnet_t *g_pkt_d) 0, NULL, 0, - g_pkt_d, + pkt_d, 0) == -1) { - fatal_error("Unable to build ICMPv4 timeexceed header: %s", libnet_geterror(g_pkt_d)); + fatal_error("Unable to build ICMPv4 timeexceed header: %s", libnet_geterror(pkt_d)); } } @@ -300,18 +300,18 @@ shape_icmpv4_hdr(libnet_t *g_pkt_d) g_i4hdr_o.type, g_i4hdr_o.code, 0, - g_i4hdr_o.id, - g_i4hdr_o.seqn, - g_i4hdr_o.otime, - g_i4hdr_o.rtime, - g_i4hdr_o.ttime, - g_payload, - g_payload_len, - g_pkt_d, - 0) == -1) - { - fatal_error("Unable to build ICMPv4 timestamp header: %s", libnet_geterror(g_pkt_d)); - } + g_i4hdr_o.id, + g_i4hdr_o.seqn, + g_i4hdr_o.otime, + g_i4hdr_o.rtime, + g_i4hdr_o.ttime, + g_payload, + g_payload_len, + pkt_d, + 0) == -1) + { + fatal_error("Unable to build ICMPv4 timestamp header: %s", libnet_geterror(pkt_d)); + } break; @@ -327,7 +327,7 @@ shape_icmpv4_hdr(libnet_t *g_pkt_d) g_i4hdr_o.id = (u_int16_t)retrieve_rand_int(P_UINT16); if(g_i4hdr_o.mask != NULL) - if((ihn_mask = libnet_name2addr4(g_pkt_d, (char*)g_i4hdr_o.mask, 1)) == -1) + if((ihn_mask = libnet_name2addr4(pkt_d, (char*)g_i4hdr_o.mask, 1)) == -1) fatal_error("Invalid mask address: %s", g_i4hdr_o.mask); g_hdr_len = ICMPV4_MASK_H; @@ -339,24 +339,24 @@ shape_icmpv4_hdr(libnet_t *g_pkt_d) g_pkt_len = 0; } - if(libnet_build_icmpv4_mask( - g_i4hdr_o.type, - g_i4hdr_o.code, - (g_i4hdr_o.mask != NULL) ? ihn_mask : 0, - g_i4hdr_o.id, - g_i4hdr_o.seqn, - ihn_mask, - g_payload, - g_payload_len, - g_pkt_d, - 0) == -1) - { - fatal_error("Unable to build ICMPv4 mask header: %s", libnet_geterror(g_pkt_d)); - } + if(libnet_build_icmpv4_mask( + g_i4hdr_o.type, + g_i4hdr_o.code, + (g_i4hdr_o.mask != NULL) ? ihn_mask : 0, + g_i4hdr_o.id, + g_i4hdr_o.seqn, + ihn_mask, + g_payload, + g_payload_len, + pkt_d, + 0) == -1) + { + fatal_error("Unable to build ICMPv4 mask header: %s", libnet_geterror(pkt_d)); + } break; } - return g_pkt_d; + return pkt_d; } diff --git a/src/shape_ipv4_hdr.c b/src/shape_ipv4_hdr.c index 296b04b..eecf068 100644 --- a/src/shape_ipv4_hdr.c +++ b/src/shape_ipv4_hdr.c @@ -26,7 +26,7 @@ #include "shape_ipv4_hdr.h" libnet_t * -shape_ipv4_hdr(libnet_t *g_pkt_d) +shape_ipv4_hdr(libnet_t *pkt_d) { #ifdef DEBUG fprintf(stdout, "DEBUG: shape_ipv4_hdr()\n"); @@ -40,19 +40,19 @@ shape_ipv4_hdr(libnet_t *g_pkt_d) if(g_ip4hdr_o.s_addr == NULL) { - if((g_ip4hdr_o.n_saddr = libnet_get_ipaddr4(g_pkt_d)) == -1) - fatal_error("Unable to retrieve local IP address: %s", libnet_geterror(g_pkt_d)); + if((g_ip4hdr_o.n_saddr = libnet_get_ipaddr4(pkt_d)) == -1) + fatal_error("Unable to retrieve local IP address: %s", libnet_geterror(pkt_d)); g_ip4hdr_o.s_addr = (u_int8_t*)libnet_addr2name4(g_ip4hdr_o.n_saddr, 1); } else - if((g_ip4hdr_o.n_saddr = libnet_name2addr4(g_pkt_d, (char*)g_ip4hdr_o.s_addr, 1)) == -1) + if((g_ip4hdr_o.n_saddr = libnet_name2addr4(pkt_d, (char*)g_ip4hdr_o.s_addr, 1)) == -1) fatal_error("Invalid source IP address: %s", g_ip4hdr_o.s_addr); if(g_ip4hdr_o.d_addr == NULL) fatal_error("No destination IP address defined"); - if((g_ip4hdr_o.n_daddr = libnet_name2addr4(g_pkt_d, (char*)g_ip4hdr_o.d_addr, 1)) == -1) + if((g_ip4hdr_o.n_daddr = libnet_name2addr4(pkt_d, (char*)g_ip4hdr_o.d_addr, 1)) == -1) fatal_error("Invalid destination IP address: %s", g_ip4hdr_o.d_addr); #ifdef DEBUG @@ -86,11 +86,11 @@ shape_ipv4_hdr(libnet_t *g_pkt_d) g_ip4hdr_o.n_daddr, (g_rawip) ? g_payload : NULL, (g_rawip) ? g_payload_len : 0, - g_pkt_d, + pkt_d, 0) == -1) { - fatal_error("Unable to build IP header: %s", libnet_geterror(g_pkt_d)); + fatal_error("Unable to build IP header: %s", libnet_geterror(pkt_d)); } - return g_pkt_d; + return pkt_d; } diff --git a/src/shape_packet.c b/src/shape_packet.c index c000b24..2971422 100644 --- a/src/shape_packet.c +++ b/src/shape_packet.c @@ -33,13 +33,16 @@ shape_packet() fprintf(stdout, "DEBUG: shape_packet()\n"); #endif + u_int8_t transport_type = (g_ipv6) ? g_ip6hdr_o.next_header : g_ip4hdr_o.p; + switch(g_injection_type) { case ETHERTYPE_IP: + case ETHERTYPE_IP6: #ifdef DEBUG fprintf(stdout, "DEBUG: Injecting IP traffic\n"); #endif - switch(g_ip4hdr_o.p) + switch(transport_type) { case IPPROTO_TCP: if((g_pkt_d = shape_tcp_hdr(g_pkt_d)) == NULL) @@ -60,8 +63,16 @@ shape_packet() break; } - if((g_pkt_d = shape_ipv4_hdr(g_pkt_d)) == NULL) - return g_pkt_d; + if(g_ipv6) + { + if((g_pkt_d = shape_ipv6_hdr(g_pkt_d)) == NULL) + return g_pkt_d; + } + else + { + if((g_pkt_d = shape_ipv4_hdr(g_pkt_d)) == NULL) + return g_pkt_d; + } break; diff --git a/src/shape_tcp_hdr.c b/src/shape_tcp_hdr.c index 9ca67fa..8989ae4 100644 --- a/src/shape_tcp_hdr.c +++ b/src/shape_tcp_hdr.c @@ -26,7 +26,7 @@ #include "shape_tcp_hdr.h" libnet_t * -shape_tcp_hdr(libnet_t *g_pkt_d) +shape_tcp_hdr(libnet_t *pkt_d) { int flags; @@ -34,7 +34,11 @@ shape_tcp_hdr(libnet_t *g_pkt_d) fprintf(stdout, "DEBUG: shape_tcp_hdr()\n"); #endif - g_ip4hdr_o.p = IPPROTO_TCP; + if(g_ipv6) + g_ip6hdr_o.next_header = IPPROTO_TCP; + else + g_ip4hdr_o.p = IPPROTO_TCP; + g_hdr_len = TCP_H; if(g_rand_s_port) @@ -57,7 +61,7 @@ shape_tcp_hdr(libnet_t *g_pkt_d) g_pkt_len = 0; } - if(libnet_build_tcp( + if((libnet_build_tcp( g_s_port, g_d_port, g_thdr_o.seqn, @@ -69,14 +73,14 @@ shape_tcp_hdr(libnet_t *g_pkt_d) g_hdr_len + g_payload_len, g_payload, g_payload_len, - g_pkt_d, - 0) == -1) + pkt_d, + 0)) == -1) { - fatal_error("Unable to build TCP header: %s", libnet_geterror(g_pkt_d)); + fatal_error("Unable to build TCP header: %s", libnet_geterror(pkt_d)); } if(g_port_range) g_d_port++; - return g_pkt_d; + return pkt_d; } diff --git a/src/shape_udp_hdr.c b/src/shape_udp_hdr.c index 3ae0301..a345601 100644 --- a/src/shape_udp_hdr.c +++ b/src/shape_udp_hdr.c @@ -26,14 +26,17 @@ #include "shape_udp_hdr.h" libnet_t * -shape_udp_hdr(libnet_t *g_pkt_d) +shape_udp_hdr(libnet_t *pkt_d) { #ifdef DEBUG fprintf(stdout, "DEBUG: shape_udp_hdr()\n"); #endif g_hdr_len = UDP_H; - g_ip4hdr_o.p = IPPROTO_UDP; + if(g_ipv6) + g_ip6hdr_o.next_header = IPPROTO_UDP; + else + g_ip4hdr_o.p = IPPROTO_UDP; if(g_rand_d_port) g_d_port = (u_int16_t)retrieve_rand_int(P_UINT16); @@ -57,11 +60,11 @@ shape_udp_hdr(libnet_t *g_pkt_d) 0, g_payload, g_payload_len, - g_pkt_d, + pkt_d, 0) == -1) { - fatal_error("Unable to build UDP header: %s", libnet_geterror(g_pkt_d)); + fatal_error("Unable to build UDP header: %s", libnet_geterror(pkt_d)); } - return g_pkt_d; + return pkt_d; } diff --git a/src/usage.c b/src/usage.c index d242ddb..37e0474 100644 --- a/src/usage.c +++ b/src/usage.c @@ -117,6 +117,7 @@ print_usage() fprintf(stdout, "\n"); fprintf(stdout, "IP header options\n"); + fprintf(stdout, " -6 IPv6\n"); fprintf(stdout, " -d address Destination address\n"); fprintf(stdout, " -f Don't fragment\n"); fprintf(stdout, " -n id ID number\n"); diff --git a/src/utils.c b/src/utils.c index 36cef96..2c7b2a9 100644 --- a/src/utils.c +++ b/src/utils.c @@ -681,3 +681,13 @@ u_int32_t format_hex_payload(u_int8_t *string) return len; } + +void +rand_ip6addr(struct libnet_in6_addr *addr) +{ + addr->__u6_addr.__u6_addr32[0] = retrieve_rand_int(0xffffffff); + addr->__u6_addr.__u6_addr32[1] = retrieve_rand_int(0xffffffff); + addr->__u6_addr.__u6_addr32[2] = retrieve_rand_int(0xffffffff); + addr->__u6_addr.__u6_addr32[3] = retrieve_rand_int(0xffffffff); +} + diff --git a/src/utils.h b/src/utils.h index 580d5ed..ff0232b 100644 --- a/src/utils.h +++ b/src/utils.h @@ -46,6 +46,7 @@ u_int16_t retrieve_datalink_hdr_len(u_int32_t); u_int32_t retrieve_rand_int(u_int32_t); u_int8_t format_ethernet_addr(u_int8_t *, u_int8_t[]); int retrieve_tcp_flags(); +void rand_ip6addr(struct libnet_in6_addr *); #endif /* __UTILS_H */ From a774b5b05903c640e49ca45f027eac2401e73c2f Mon Sep 17 00:00:00 2001 From: Sharad B Date: Fri, 13 Jan 2017 08:18:35 +0530 Subject: [PATCH 2/3] Adding missing new files --- src/shape_ipv6_hdr.c | 89 ++++++++++++++++++++++++++++++++++++++++++++ src/shape_ipv6_hdr.h | 34 +++++++++++++++++ 2 files changed, 123 insertions(+) create mode 100644 src/shape_ipv6_hdr.c create mode 100644 src/shape_ipv6_hdr.h diff --git a/src/shape_ipv6_hdr.c b/src/shape_ipv6_hdr.c new file mode 100644 index 0000000..f2e6ae2 --- /dev/null +++ b/src/shape_ipv6_hdr.c @@ -0,0 +1,89 @@ +/* + * Original author: Darren Bounds + * + * Copyright 2017 Sharad B + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + * + * packit official page at https://github.com/eribertomota/packit + * + */ + +#include "shape_ipv6_hdr.h" + +libnet_t * +shape_ipv6_hdr(libnet_t *pkt_d) +{ +#ifdef DEBUG + fprintf(stdout, "DEBUG: shape_ipv6_hdr()\n"); +#endif + + if(g_ip6hdr_o.rand_src_addr) + { + rand_ip6addr(&g_ip6hdr_o.src); + } + else if(g_ip6hdr_o.src_str) + { + g_ip6hdr_o.src = libnet_name2addr6(pkt_d, g_ip6hdr_o.src_str, LIBNET_RESOLVE); + } + else + fatal_error("No source address"); + + if(g_ip6hdr_o.rand_dst_addr) + { + rand_ip6addr(&g_ip6hdr_o.dst); + } + else if(g_ip6hdr_o.dst_str) + { + g_ip6hdr_o.dst = libnet_name2addr6(pkt_d, g_ip6hdr_o.dst_str, LIBNET_RESOLVE); + } + else + fatal_error("No destination address"); + +#ifdef DEBUG + char debug_src_string[256] = ""; + char debug_dst_string[256] = ""; + libnet_addr2name6_r(g_ip6hdr_o.src, LIBNET_DONT_RESOLVE, debug_src_string, 256); + libnet_addr2name6_r(g_ip6hdr_o.dst, LIBNET_DONT_RESOLVE, debug_dst_string, 256); + fprintf(stdout, "DEBUG: source IP: %s destination IP: %s\n", + debug_src_string, debug_dst_string); +#endif + +// if(g_ip4hdr_o.rand_p) +// g_ip4hdr_o.p = (u_int8_t)retrieve_rand_int(P_UINT8); +// +// if(g_ip4hdr_o.rand_id) +// g_ip4hdr_o.id = (u_int16_t)retrieve_rand_int(P_UINT16); + + g_hdr_len = g_hdr_len + g_payload_len; + + if(libnet_build_ipv6( + g_ip6hdr_o.traffic_class, + g_ip6hdr_o.flow_label, + g_hdr_len, + g_ip6hdr_o.next_header, + g_ip6hdr_o.hop_limit, + g_ip6hdr_o.src, + g_ip6hdr_o.dst, + NULL, 0, + pkt_d, + 0) == -1) + { + fatal_error("Unable to build IP header: %s", libnet_geterror(pkt_d)); + } + + return pkt_d; +} diff --git a/src/shape_ipv6_hdr.h b/src/shape_ipv6_hdr.h new file mode 100644 index 0000000..332abe8 --- /dev/null +++ b/src/shape_ipv6_hdr.h @@ -0,0 +1,34 @@ +/* + * Packit -- network injection and capture tool + * + * Original author: Darren Bounds + * + * Copyright 2017 Sharad B + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + * + * packit official page at https://github.com/eribertomota/packit + */ + +#ifndef __SHAPE_IPV6_HDR_H +#define __SHAPE_IPV6_HDR_H + +#include "globals.h" +#include "inject_defs.h" + +libnet_t *shape_ipv6_hdr(libnet_t *); + +#endif /* __SHAPE_IPV6_HDR_H */ From f00b46faedab412d3ed0857a151451b80a9e3304 Mon Sep 17 00:00:00 2001 From: Sharad B Date: Sat, 14 Jan 2017 10:21:38 +0530 Subject: [PATCH 3/3] "-6" and "-t" options affect how subsequent options are parsed. For this reason, we need to parse all the arguments from the beginning multiple times. This patch addresses that requirement. Now "-6" and "-t" can appear anywhere in the arguments and they are correctly parsed. --- src/globals.h | 12 ++++++++ src/main.c | 79 +++++++++++++++++++++++++++------------------------ 2 files changed, 54 insertions(+), 37 deletions(-) diff --git a/src/globals.h b/src/globals.h index f20a469..c55244d 100644 --- a/src/globals.h +++ b/src/globals.h @@ -138,6 +138,18 @@ #define P_INT64 0x7FFFFFFFFFFFFFFF #define P_UINT64 0xFFFFFFFFFFFFFFFF +#define TCP_OPTS_ "a:b:c:d:D:e:E:fF:hH:i:n:p:q:Rs:S:T:o:u:vw:W:Z:" +#define UDP_OPTS_ "b:c:d:D:e:E:fhH:i:n:o:p:Rs:S:T:vw:Z:" +#define ICMP_OPTS_ "b:c:C:d:e:E:fg:G:hH:i:j:J:k:K:l:L:m:M:n:N:o:O:p:P:Q:Rs:T:U:vw:z:Z:" +#define ARP_OPTS_ "A:b:c:e:E:i:p:Rs:S:vx:X:y:Y:" +#define RARP_OPTS_ "A:b:c:e:E:i:p:Rs:S:vx:X:y:Y:" +#define RAWIP_OPTS_ "b:c:d:e:E:f:i:n:o:p:Rs:T:U:vV:w:Z:" + +#define PROTO_OPTS_ TCP_OPTS_ UDP_OPTS_ ICMP_OPTS_ ARP_OPTS_ RARP_OPTS_ RAWIP_OPTS_ + +#define OPTS_PLUS(opts, more_opts) opts more_opts + + char g_w_file[OPT_MAXLEN]; char g_r_file[OPT_MAXLEN]; diff --git a/src/main.c b/src/main.c index 22430ca..e436e00 100644 --- a/src/main.c +++ b/src/main.c @@ -112,20 +112,26 @@ parse_inject_options(int argc, char *argv[], u_int16_t iopt) define_injection_defaults(); injection_struct_init(); - if((opt=getopt(argc, argv, "6:")) != -1) + // getopt parses arguments in the order they are seen. We want to detect -6 first + // because that modifies how some of the arguments are interpreted. Do a first pass + // now while only looking for -6 and ignoring all other options. + while((opt=getopt(argc, argv, PROTO_OPTS_ "6")) != -1) { switch(opt) { case '6': - g_init_type = LIBNET_RAW6; g_ipv6 = 1; - optind = 1; break; default: + // ignore everything else break; } } - while((opt = getopt(argc, argv, "t:6:")) != -1) + // Reset argument parser to the beginning + optind = 1; + + // Ignore -m, -6, and -t arguments + while((opt = getopt(argc, argv, PROTO_OPTS_ "6m:t:")) != -1) { switch(opt) { @@ -148,7 +154,7 @@ parse_inject_options(int argc, char *argv[], u_int16_t iopt) g_ip4hdr_o.p = IPPROTO_TCP; g_injection_type = ETHERTYPE_IP; } - opts = "6:a:b:c:d:D:e:E:fF:hH:i:n:p:q:Rs:S:T:o:u:vw:W:Z:"; + opts = "6m:t:" TCP_OPTS_; } else if(!strncasecmp(optarg, "UDP", 3)) { @@ -165,7 +171,7 @@ parse_inject_options(int argc, char *argv[], u_int16_t iopt) g_ip4hdr_o.p = IPPROTO_UDP; g_injection_type = ETHERTYPE_IP; } - opts = "6:b:c:d:D:e:E:fhH:i:n:o:p:Rs:S:T:vw:Z:"; + opts = "6m:t:" UDP_OPTS_; } else if(!strncasecmp(optarg, "ICMP", 4)) { @@ -175,7 +181,7 @@ parse_inject_options(int argc, char *argv[], u_int16_t iopt) g_ipv6 = 0; g_ip4hdr_o.p = IPPROTO_ICMP; g_injection_type = ETHERTYPE_IP; - opts = "b:c:C:d:e:E:fg:G:hH:i:j:J:k:K:l:L:m:M:n:N:o:O:p:P:Q:Rs:t:T:U:vw:z:Z:"; + opts = ICMP_OPTS_; } else if(!strncasecmp(optarg, "ARP", 3)) { @@ -191,7 +197,7 @@ parse_inject_options(int argc, char *argv[], u_int16_t iopt) g_ipv6 = 0; g_injection_type = ETHERTYPE_ARP; g_init_type = 0; - opts = "A:b:c:e:E:i:p:Rs:S:vx:X:y:Y:"; + opts = ARP_OPTS_; } else if(!strncasecmp(optarg, "RARP", 4)) { @@ -208,7 +214,7 @@ parse_inject_options(int argc, char *argv[], u_int16_t iopt) g_injection_type = ETHERTYPE_REVARP; g_ahdr_o.op_type = ARPOP_REVREQUEST; /* Update init */ g_init_type = 0; - opts = "A:b:c:e:E:i:p:Rs:S:vx:X:y:Y:"; + opts = RARP_OPTS_; } else if(!strncasecmp(optarg, "RAWIP", 3)) { @@ -220,7 +226,7 @@ parse_inject_options(int argc, char *argv[], u_int16_t iopt) g_ipv6 = 0; g_rawip = g_ip4hdr_o.p = IPPROTO_RAW; g_injection_type = ETHERTYPE_IP; - opts = "b:c:d:e:E:f:i:n:o:p:Rs:T:U:vV:w:Z:"; + opts = RAWIP_OPTS_; } else print_usage(); @@ -230,43 +236,42 @@ parse_inject_options(int argc, char *argv[], u_int16_t iopt) break; default: - if(optind > 1) optind--; - g_injection_type = ETHERTYPE_IP; - - if(g_p_mode == M_TRACE) - { - g_ipv6 = 0; - g_ip4hdr_o.p = IPPROTO_ICMP; - opts = "b:c:C:d:e:E:fg:G:hH:i:j:J:k:K:l:L:m:M:n:N:o:O:p:P:Q:Rs:t:T:U:vw:z:Z:"; - } - else - { - if(g_ipv6) - { - g_ip6hdr_o.next_header = IPPROTO_TCP; - g_injection_type = ETHERTYPE_IP6; - } - else - { - g_ip4hdr_o.p = IPPROTO_TCP; - g_injection_type = ETHERTYPE_IP; - } - opts = "6:a:b:c:d:D:e:E:fF:hH:i:n:p:q:Rs:S:T:o:u:vw:W:Z:"; - } - - goto parse_inject; - break; } } - print_usage(); + if(g_p_mode == M_TRACE) + { + g_ipv6 = 0; + g_ip4hdr_o.p = IPPROTO_ICMP; + opts = ICMP_OPTS_; + } + else + { + if(g_ipv6) + { + g_ip6hdr_o.next_header = IPPROTO_TCP; + g_injection_type = ETHERTYPE_IP6; + } + else + { + g_ip4hdr_o.p = IPPROTO_TCP; + g_injection_type = ETHERTYPE_IP; + } + opts = TCP_OPTS_; + } parse_inject: #ifdef DEBUG fprintf(stdout, "DEBUG: parse_inject\n"); #endif + if(g_ipv6) + g_init_type = LIBNET_RAW6; + + // Start parsing from the beginning again + optind = 1; + while((opt = getopt(argc, argv, opts)) != -1) { switch(opt)