From fa3cd7e50b9305ff3956817ab246c810f6564022 Mon Sep 17 00:00:00 2001 From: dsugisawa-mixi Date: Tue, 29 Jan 2019 17:39:59 +0900 Subject: [PATCH 1/3] fix, ip address range --- src/tcpedit/edit_packet.c | 51 ++++++++++++++++++++++++++++++++++++ src/tcpedit/edit_packet.h | 4 +++ src/tcpedit/parse_args.c | 29 ++++++++++++++++++++ src/tcpedit/tcpedit.c | 10 +++++++ src/tcpedit/tcpedit_opts.def | 31 ++++++++++++++++++++++ src/tcpedit/tcpedit_types.h | 7 ++++- 6 files changed, 131 insertions(+), 1 deletion(-) diff --git a/src/tcpedit/edit_packet.c b/src/tcpedit/edit_packet.c index 740a090e9..dc2134e79 100644 --- a/src/tcpedit/edit_packet.c +++ b/src/tcpedit/edit_packet.c @@ -1202,3 +1202,54 @@ is_multicast_ipv6(tcpedit_t *tcpedit, struct tcpr_in6_addr *addr) return 0; } + +/** + * rewrite the source and destination IP addresses based on a + * range number which is generated via the range_[src/dst]. + * return 1 since we changed one or more IP addresses + */ +int +range_ipv4(tcpedit_t *tcpedit, struct pcap_pkthdr *pkthdr, + u_char *pktdata, ipv4_hdr_t *ip_hdr, int len) +{ +#ifdef DEBUG + char srcip[16], dstip[16]; +#endif + assert(tcpedit); + assert(pkthdr); + assert(pktdata); + assert(ip_hdr); + +#ifdef DEBUG + strlcpy(srcip, get_addr2name4(tcpedit->range_src_ipv4, RESOLVE), 16); + strlcpy(dstip, get_addr2name4(tcpedit->range_dst_ipv4, RESOLVE), 16); +#endif + + /* randomize IP addresses based on the value of random */ + dbgx(1, "Old Src IP: %s\tOld Dst IP: %s", srcip, dstip); + + /* don't rewrite broadcast addresses */ + if ((tcpedit->skip_broadcast && is_unicast_ipv4(tcpedit, (u_int32_t)ip_hdr->ip_dst.s_addr)) + || !tcpedit->skip_broadcast) { + uint32_t old_ip = ip_hdr->ip_dst.s_addr; + ip_hdr->ip_dst.s_addr = htonl(ntohl(tcpedit->range_dst_ipv4) + tcpedit->range_pos); + ipv4_addr_csum_replace(ip_hdr, old_ip, ip_hdr->ip_dst.s_addr, len); + } + if ((tcpedit->skip_broadcast && is_unicast_ipv4(tcpedit, (u_int32_t)ip_hdr->ip_src.s_addr)) + || !tcpedit->skip_broadcast) { + uint32_t old_ip = ip_hdr->ip_src.s_addr; + ip_hdr->ip_src.s_addr = htonl(ntohl(tcpedit->range_src_ipv4) + tcpedit->range_pos); + ipv4_addr_csum_replace(ip_hdr, old_ip, ip_hdr->ip_src.s_addr, len); + } + if (tcpedit->range_pos++ > tcpedit->range_count){ + tcpedit->range_pos = 0; + } +#ifdef DEBUG + strlcpy(srcip, get_addr2name4(ip_hdr->ip_src.s_addr, RESOLVE), 16); + strlcpy(dstip, get_addr2name4(ip_hdr->ip_dst.s_addr, RESOLVE), 16); +#endif + + dbgx(1, "New Src IP: %s\tNew Dst IP: %s\n", srcip, dstip); + + return 0; +} diff --git a/src/tcpedit/edit_packet.h b/src/tcpedit/edit_packet.h index c65ef6d4d..b15ca5c60 100644 --- a/src/tcpedit/edit_packet.h +++ b/src/tcpedit/edit_packet.h @@ -61,6 +61,10 @@ int rewrite_ipv4_ttl(tcpedit_t *tcpedit, ipv4_hdr_t *ip_hdr); int rewrite_ipv6_hlim(tcpedit_t *tcpedit, ipv6_hdr_t *ip6_hdr); +int range_ipv4(tcpedit_t *tcpedit, struct pcap_pkthdr *pktdhr, + u_char *pktdata, ipv4_hdr_t *ip_hdr, int len); + + #define BROADCAST_IP 4294967295 #endif diff --git a/src/tcpedit/parse_args.c b/src/tcpedit/parse_args.c index 3f0f7b34e..6a73bc357 100644 --- a/src/tcpedit/parse_args.c +++ b/src/tcpedit/parse_args.c @@ -247,6 +247,35 @@ tcpedit_post_args(tcpedit_t *tcpedit) { return -1; } } + /* --rangecount */ + tcpedit->range_count = 0; + tcpedit->range_pos = 0; + tcpedit->range_src_ipv4 = htonl(0xC6123202); + tcpedit->range_dst_ipv4 = htonl(0xC6130001); + if (HAVE_OPT(RANGE_COUNT)) { + tcpedit->rewrite_ip = true; + tcpedit->range_count = OPT_VALUE_RANGE_COUNT; + if (HAVE_OPT(RANGE_ADDRESS)) { + unsigned ip1[4] = {0},ip2[4] = {0}; + int r; + /* ipv4 only */ + if ((r = sscanf(OPT_ARG(RANGE_ADDRESS), "%u.%u.%u.%u:%u.%u.%u.%u", + &ip1[0], &ip1[1], &ip1[2], &ip1[3], + &ip2[0], &ip2[1], &ip2[2], &ip2[3])) != 8){ + tcpedit_seterr(tcpedit, + "Unable to parse --range_address=%s(%d)", OPT_ARG(RANGE_ADDRESS), r); + return -1; + } + tcpedit->range_src_ipv4 = htonl(((uint8_t)ip1[0])<<24 | + ((uint8_t)ip1[1])<<16 | + ((uint8_t)ip1[2])<<8 | + ((uint8_t)ip1[3])<<0); + tcpedit->range_dst_ipv4 = htonl(((uint8_t)ip2[0])<<24 | + ((uint8_t)ip2[1])<<16 | + ((uint8_t)ip2[2])<<8 | + ((uint8_t)ip2[3])<<0); + } + } /* parse the tcpedit dlt args */ rcode = tcpedit_dlt_post_args(tcpedit); diff --git a/src/tcpedit/tcpedit.c b/src/tcpedit/tcpedit.c index 69659dfa0..f519d015b 100644 --- a/src/tcpedit/tcpedit.c +++ b/src/tcpedit/tcpedit.c @@ -336,6 +336,16 @@ tcpedit_packet(tcpedit_t *tcpedit, struct pcap_pkthdr **pkthdr, } } } + /* range ip address (ipv4 only) */ + if (tcpedit->range_count) { + /* only IPv4 Packets */ + if (ip_hdr != NULL) { + if ((retval = range_ipv4(tcpedit, *pkthdr, packet, + ip_hdr, (*pkthdr)->caplen - l2len)) < 0) + return TCPEDIT_ERROR; + } + } + /* * fix IP packet lengths in case they are corrupted by TCP segmentation diff --git a/src/tcpedit/tcpedit_opts.def b/src/tcpedit/tcpedit_opts.def index c85dd6853..72b1af4f1 100644 --- a/src/tcpedit/tcpedit_opts.def +++ b/src/tcpedit/tcpedit_opts.def @@ -58,6 +58,37 @@ you can reuse the same seed value to recreate the traffic. EOText; }; +flag = { + name = range_count; + descrip = "Set the count of ip address range"; + arg-type = number; + arg-range = "1->1048575"; + arg-default = 1; + max = 1; + doc = <<- EOText +Increament ip address (ipv4) within specified range. +EOText; +}; + +flag = { + name = range_address; + arg-type = string; + max = 1; + flags-must = range_count; + descrip = "Rewrite IP addresses to be src/dst"; + doc = <<- EOText +Takes a pair of colon delimited IPv4 addresses which will be used to rewrite +all traffic to appear to be based on the src/dst IP addresses. + +IPv4 Example: +@example +--endpoints=198.18.50.2:198.19.0.2 +@end example + +EOText; +}; + + flag = { name = pnat; value = N; diff --git a/src/tcpedit/tcpedit_types.h b/src/tcpedit/tcpedit_types.h index 049b1228e..ec1a9d07b 100644 --- a/src/tcpedit/tcpedit_types.h +++ b/src/tcpedit/tcpedit_types.h @@ -152,7 +152,7 @@ typedef struct { /* pseudo-randomize IP addresses using a seed */ uint32_t seed; - + /* rewrite tcp/udp ports */ tcpedit_portmap_t *portmap; @@ -162,6 +162,11 @@ typedef struct { uint32_t fuzz_seed; uint32_t fuzz_factor; + + uint32_t range_count; + uint32_t range_pos; + uint32_t range_src_ipv4; + uint32_t range_dst_ipv4; } tcpedit_t; From 63e0dc9f9803a762cadf1321ef11ee88af2b20d4 Mon Sep 17 00:00:00 2001 From: dsugisawa-mixi Date: Tue, 29 Jan 2019 17:47:12 +0900 Subject: [PATCH 2/3] modify, comment --- src/tcpedit/edit_packet.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tcpedit/edit_packet.c b/src/tcpedit/edit_packet.c index dc2134e79..36a4c2c13 100644 --- a/src/tcpedit/edit_packet.c +++ b/src/tcpedit/edit_packet.c @@ -1203,9 +1203,9 @@ is_multicast_ipv6(tcpedit_t *tcpedit, struct tcpr_in6_addr *addr) } + /** - * rewrite the source and destination IP addresses based on a - * range number which is generated via the range_[src/dst]. + * based on which is generated via the range_[src/dst] and range. * return 1 since we changed one or more IP addresses */ int From ea2340c940894b07a25f115cb4256cfc05a586f6 Mon Sep 17 00:00:00 2001 From: dsugisawa-mixi Date: Tue, 5 Feb 2019 11:11:32 +0900 Subject: [PATCH 3/3] fix, modify ip address range --- src/tcpedit/edit_packet.c | 58 ++++++++++++++++++++++++++++++++++++ src/tcpedit/edit_packet.h | 4 +++ src/tcpedit/parse_args.c | 36 ++++++++++++++++++++++ src/tcpedit/tcpedit.c | 10 +++++++ src/tcpedit/tcpedit_opts.def | 43 ++++++++++++++++++++++++++ src/tcpedit/tcpedit_types.h | 9 +++++- 6 files changed, 159 insertions(+), 1 deletion(-) diff --git a/src/tcpedit/edit_packet.c b/src/tcpedit/edit_packet.c index 740a090e9..38e81f29e 100644 --- a/src/tcpedit/edit_packet.c +++ b/src/tcpedit/edit_packet.c @@ -1202,3 +1202,61 @@ is_multicast_ipv6(tcpedit_t *tcpedit, struct tcpr_in6_addr *addr) return 0; } + +/** + * based on which is generated via the range_[src/dst] and range. + * return 1 since we changed one or more IP addresses + */ +int +range_ipv4(tcpedit_t *tcpedit, struct pcap_pkthdr *pkthdr, + u_char *pktdata, ipv4_hdr_t *ip_hdr, int len) +{ +#ifdef DEBUG + char srcip[16], dstip[16]; +#endif + assert(tcpedit); + assert(pkthdr); + assert(pktdata); + assert(ip_hdr); + +#ifdef DEBUG + strlcpy(srcip, get_addr2name4(tcpedit->range_src_ipv4, RESOLVE), 16); + strlcpy(dstip, get_addr2name4(tcpedit->range_dst_ipv4, RESOLVE), 16); +#endif + + /* randomize IP addresses based on the value of random */ + dbgx(1, "Old Src IP: %s\tOld Dst IP: %s", srcip, dstip); + + /* don't rewrite broadcast addresses */ + if (tcpedit->range_count_dst){ + if ((tcpedit->skip_broadcast && is_unicast_ipv4(tcpedit, (u_int32_t)ip_hdr->ip_dst.s_addr)) + || !tcpedit->skip_broadcast) { + uint32_t old_ip = ip_hdr->ip_dst.s_addr; + ip_hdr->ip_dst.s_addr = htonl(ntohl(tcpedit->range_dst_ipv4) + tcpedit->range_pos_dst); + ipv4_addr_csum_replace(ip_hdr, old_ip, ip_hdr->ip_dst.s_addr, len); + } + } + if (tcpedit->range_count_src){ + if ((tcpedit->skip_broadcast && is_unicast_ipv4(tcpedit, (u_int32_t)ip_hdr->ip_src.s_addr)) + || !tcpedit->skip_broadcast) { + uint32_t old_ip = ip_hdr->ip_src.s_addr; + ip_hdr->ip_src.s_addr = htonl(ntohl(tcpedit->range_src_ipv4) + tcpedit->range_pos_src); + ipv4_addr_csum_replace(ip_hdr, old_ip, ip_hdr->ip_src.s_addr, len); + } + } + if ((++tcpedit->range_pos_dst) >= tcpedit->range_count_dst){ + tcpedit->range_pos_dst = 0; + } + if ((++tcpedit->range_pos_src) >= tcpedit->range_count_src){ + tcpedit->range_pos_src = 0; + } + +#ifdef DEBUG + strlcpy(srcip, get_addr2name4(ip_hdr->ip_src.s_addr, RESOLVE), 16); + strlcpy(dstip, get_addr2name4(ip_hdr->ip_dst.s_addr, RESOLVE), 16); +#endif + + dbgx(1, "New Src IP: %s\tNew Dst IP: %s\n", srcip, dstip); + + return 0; +} diff --git a/src/tcpedit/edit_packet.h b/src/tcpedit/edit_packet.h index c65ef6d4d..b15ca5c60 100644 --- a/src/tcpedit/edit_packet.h +++ b/src/tcpedit/edit_packet.h @@ -61,6 +61,10 @@ int rewrite_ipv4_ttl(tcpedit_t *tcpedit, ipv4_hdr_t *ip_hdr); int rewrite_ipv6_hlim(tcpedit_t *tcpedit, ipv6_hdr_t *ip6_hdr); +int range_ipv4(tcpedit_t *tcpedit, struct pcap_pkthdr *pktdhr, + u_char *pktdata, ipv4_hdr_t *ip_hdr, int len); + + #define BROADCAST_IP 4294967295 #endif diff --git a/src/tcpedit/parse_args.c b/src/tcpedit/parse_args.c index 3f0f7b34e..e9b2c1560 100644 --- a/src/tcpedit/parse_args.c +++ b/src/tcpedit/parse_args.c @@ -247,6 +247,42 @@ tcpedit_post_args(tcpedit_t *tcpedit) { return -1; } } + /* --rangecount */ + tcpedit->range_count_src = 0; + tcpedit->range_count_dst = 0; + tcpedit->range_pos_src = 0; + tcpedit->range_pos_dst = 0; + tcpedit->range_src_ipv4 = htonl(0xC6123202); + tcpedit->range_dst_ipv4 = htonl(0xC6130001); + if (HAVE_OPT(RANGE_COUNT_SRC)) { + tcpedit->rewrite_ip = true; + tcpedit->range_count_src = OPT_VALUE_RANGE_COUNT_SRC; + } + if (HAVE_OPT(RANGE_COUNT_DST)) { + tcpedit->rewrite_ip = true; + tcpedit->range_count_dst = OPT_VALUE_RANGE_COUNT_DST; + } + + if (HAVE_OPT(RANGE_ADDRESS)) { + unsigned ip1[4] = {0},ip2[4] = {0}; + int r; + /* ipv4 only */ + if ((r = sscanf(OPT_ARG(RANGE_ADDRESS), "%u.%u.%u.%u:%u.%u.%u.%u", + &ip1[0], &ip1[1], &ip1[2], &ip1[3], + &ip2[0], &ip2[1], &ip2[2], &ip2[3])) != 8){ + tcpedit_seterr(tcpedit, + "Unable to parse --range_address=%s(%d)", OPT_ARG(RANGE_ADDRESS), r); + return -1; + } + tcpedit->range_src_ipv4 = htonl(((uint8_t)ip1[0])<<24 | + ((uint8_t)ip1[1])<<16 | + ((uint8_t)ip1[2])<<8 | + ((uint8_t)ip1[3])<<0); + tcpedit->range_dst_ipv4 = htonl(((uint8_t)ip2[0])<<24 | + ((uint8_t)ip2[1])<<16 | + ((uint8_t)ip2[2])<<8 | + ((uint8_t)ip2[3])<<0); + } /* parse the tcpedit dlt args */ rcode = tcpedit_dlt_post_args(tcpedit); diff --git a/src/tcpedit/tcpedit.c b/src/tcpedit/tcpedit.c index 69659dfa0..4f0049a48 100644 --- a/src/tcpedit/tcpedit.c +++ b/src/tcpedit/tcpedit.c @@ -336,6 +336,16 @@ tcpedit_packet(tcpedit_t *tcpedit, struct pcap_pkthdr **pkthdr, } } } + /* range ip address (ipv4 only) */ + if (tcpedit->range_count_src || tcpedit->range_count_dst) { + /* only IPv4 Packets */ + if (ip_hdr != NULL) { + if ((retval = range_ipv4(tcpedit, *pkthdr, packet, + ip_hdr, (*pkthdr)->caplen - l2len)) < 0) + return TCPEDIT_ERROR; + } + } + /* * fix IP packet lengths in case they are corrupted by TCP segmentation diff --git a/src/tcpedit/tcpedit_opts.def b/src/tcpedit/tcpedit_opts.def index c85dd6853..1277e0664 100644 --- a/src/tcpedit/tcpedit_opts.def +++ b/src/tcpedit/tcpedit_opts.def @@ -58,6 +58,49 @@ you can reuse the same seed value to recreate the traffic. EOText; }; +flag = { + name = range_count_src; + descrip = "Set the count of source ip address range"; + arg-type = number; + arg-range = "1->1048575"; + arg-default = 1; + max = 1; + doc = <<- EOText +Increament source ip address (ipv4) within specified range. +EOText; +}; + +flag = { + name = range_count_dst; + descrip = "Set the count of destination ip address range"; + arg-type = number; + arg-range = "1->1048575"; + arg-default = 1; + max = 1; + doc = <<- EOText +Increament destination ip address (ipv4) within specified range. +EOText; +}; + + +flag = { + name = range_address; + arg-type = string; + max = 1; + descrip = "Rewrite IP addresses to be src/dst"; + doc = <<- EOText +Takes a pair of colon delimited IPv4 addresses which will be used to rewrite +all traffic to appear to be based on the src/dst IP addresses. + +IPv4 Example: +@example +--endpoints=198.18.50.2:198.19.0.2 +@end example + +EOText; +}; + + flag = { name = pnat; value = N; diff --git a/src/tcpedit/tcpedit_types.h b/src/tcpedit/tcpedit_types.h index 049b1228e..8e2628858 100644 --- a/src/tcpedit/tcpedit_types.h +++ b/src/tcpedit/tcpedit_types.h @@ -152,7 +152,7 @@ typedef struct { /* pseudo-randomize IP addresses using a seed */ uint32_t seed; - + /* rewrite tcp/udp ports */ tcpedit_portmap_t *portmap; @@ -162,6 +162,13 @@ typedef struct { uint32_t fuzz_seed; uint32_t fuzz_factor; + + uint32_t range_count_src; + uint32_t range_count_dst; + uint32_t range_pos_src; + uint32_t range_pos_dst; + uint32_t range_src_ipv4; + uint32_t range_dst_ipv4; } tcpedit_t;