Skip to content

Commit

Permalink
Merge pull request #700 from appneta/Feature_#563_mac_update_on_multi…
Browse files Browse the repository at this point in the history
…cast

Feature #563 mac update on multicast
  • Loading branch information
fklassen authored Jan 31, 2022
2 parents 266966f + 7f106b8 commit 8b131c2
Show file tree
Hide file tree
Showing 83 changed files with 237 additions and 59 deletions.
11 changes: 5 additions & 6 deletions docs/CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
06/19/2021 Version 4.4.0-beta2
06/19/2021 Version 4.4.0
- remove obsolete FORCE_ALIGN support to fix macOS 11 compile (#695)
- add a security policy document (#689)
- ability to specify directory of pcap files (#682)
- incorrect PPS rate for long-running sessions (#679)
- revert #630 to fix --multiplier issues (#674)
- option --skipbroadcast not working (#677)
- latest macOS SDK selected by default (#668)
- add feature VLAN Q-in-Q (#625)

06/19/2021 Version 4.3.5-beta1f
- revert #630 to fix --multiplier issues (#674)
- gcc 9.3 compiler warnings (#670)
- installed netmap not automatically detected (#669)
- latest macOS SDK selected by default (#668)
- heap-buffer-overflow with flow_decode() (#665)
- add feature VLAN Q-in-Q (#625)
- add feature update Ethernet MAC on multicast IP (#563)

04/01/2021 Version 4.3.4
- ASAN reports memory leaks while running tests (#662)
Expand Down
5 changes: 2 additions & 3 deletions src/tcpedit/edit_packet.c
Original file line number Diff line number Diff line change
Expand Up @@ -1102,8 +1102,8 @@ is_unicast_ipv4(tcpedit_t *tcpedit, uint32_t ip)
{
assert(tcpedit);

/* multicast/broadcast is 224.0.0.0 or greater */
if (ntohl(ip) > 3758096384)
/* multicast/broadcast is 224.0.0.0 to 239.255.255.255 */
if ((ntohl(ip) & 0xf0000000) == 0xe0000000)
return 0;

return 1;
Expand All @@ -1123,4 +1123,3 @@ is_multicast_ipv6(tcpedit_t *tcpedit, struct tcpr_in6_addr *addr)

return 0;
}

9 changes: 9 additions & 0 deletions src/tcpedit/edit_packet.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,15 @@ 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 extract_ipv4_multicast_mac(tcpedit_t *tcpedit,
uint32_t ip,
u_char *mac[ETHER_ADDR_LEN]);

int extract_ipv6_multicast_mac(tcpedit_t *tcpedit,
struct tcpr_in6_addr *ip6,
u_char *mac[ETHER_ADDR_LEN]);


#define BROADCAST_IP 4294967295

#endif
6 changes: 5 additions & 1 deletion src/tcpedit/fuzzing.c
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,11 @@ fuzzing(tcpedit_t *tcpedit, struct pcap_pkthdr *pkthdr,
}

/* in cases where 'l3data' is a working buffer, copy it back to '*pkthdr' */
plugin->plugin_merge_layer3(ctx, packet, caplen, l3data);
plugin->plugin_merge_layer3(ctx,
packet,
caplen,
(l2proto == ETHERTYPE_IP) ? l4data : NULL,
(l2proto == ETHERTYPE_IPV6) ? l4data : NULL);

done:
return packet_changed;
Expand Down
86 changes: 82 additions & 4 deletions src/tcpedit/plugins/dlt_en10mb/en10mb.c
Original file line number Diff line number Diff line change
Expand Up @@ -587,6 +587,7 @@ dlt_en10mb_encode(tcpeditdlt_t *ctx, u_char *packet, int pktlen, tcpr_dir_t dir)
memcpy(eth->ether_shost, ctx->srcaddr.ethernet, ETHER_ADDR_LEN);
}
} else if (ctx->addr_type == ETHERNET) {
extra->src_modified = memcmp(eth->ether_shost, ctx->srcaddr.ethernet, ETHER_ADDR_LEN);
memcpy(eth->ether_shost, ctx->srcaddr.ethernet, ETHER_ADDR_LEN);
} else {
tcpedit_seterr(ctx->tcpedit, "%s", "Please provide a source address");
Expand All @@ -603,6 +604,7 @@ dlt_en10mb_encode(tcpeditdlt_t *ctx, u_char *packet, int pktlen, tcpr_dir_t dir)
memcpy(eth->ether_dhost, ctx->dstaddr.ethernet, ETHER_ADDR_LEN);
}
} else if (ctx->addr_type == ETHERNET) {
extra->dst_modified = memcmp(eth->ether_dhost, ctx->dstaddr.ethernet, ETHER_ADDR_LEN);
memcpy(eth->ether_dhost, ctx->dstaddr.ethernet, ETHER_ADDR_LEN);
} else {
tcpedit_seterr(ctx->tcpedit, "%s", "Please provide a destination address");
Expand Down Expand Up @@ -778,25 +780,101 @@ dlt_en10mb_get_layer3(tcpeditdlt_t *ctx, u_char *packet, const int pktlen)
return tcpedit_dlt_l3data_copy(ctx, packet, pktlen, l2len);
}

/*
* Modify MAC address if IPv4 address is Multicast (#563)
* ip: 32-bit IP address in network order
* mac: pointer to packet ethernet source or destination address (6 bytes)
*/
static void dlt_en10mb_ipv4_multicast_mac_update(const uint32_t ip,
uint8_t mac[])
{
/* only modify multicast packets */
if ((ntohl(ip) & 0xf0000000) != 0xe0000000)
return;

mac[2] = (ntohl(ip) & 0x7fffff);
mac[0] =0x01;
mac[1] =0x0;
mac[2] =0x5e;
}

/*
* Modify MAC address if IPv4 address is Multicast (#563)
* ip6: 128-bit IPv6 address in network order
* mac: pointer to packet ethernet source or destination address (6 bytes)
*/
static void dlt_en10mb_ipv6_multicast_mac_update(const struct tcpr_in6_addr *ip6,
uint8_t mac[])
{
/* only modify multicast packets */
if (ip6->tcpr_s6_addr[0] == 0xff)
return;

mac[0] = 0x33;
mac[1] = 0x33;
mac[2] = ip6->tcpr_s6_addr[12];
mac[3] = ip6->tcpr_s6_addr[13];
mac[4] = ip6->tcpr_s6_addr[14];
mac[5] = ip6->tcpr_s6_addr[15];
}

/*
* function merges the packet (containing L2 and old L3) with the l3data buffer
* containing the new l3 data. Note, if L2 % 4 == 0, then they're pointing to the
* same buffer, otherwise there was a memcpy involved on strictly aligned architectures
* like SPARC
*/
u_char *
dlt_en10mb_merge_layer3(tcpeditdlt_t *ctx, u_char *packet, const int pktlen, u_char *l3data)
dlt_en10mb_merge_layer3(tcpeditdlt_t *ctx,
u_char *packet,
const int pktlen,
u_char *ipv4_data,
u_char *ipv6_data)
{
en10mb_extra_t *extra;
struct tcpr_ethernet_hdr *eth;

int l2len;

assert(ctx);
assert(packet);
assert(l3data);

l2len = dlt_en10mb_l2len(ctx, packet, pktlen);
if (l2len == -1 || pktlen < l2len)
return NULL;

return tcpedit_dlt_l3data_merge(ctx, packet, pktlen, l3data, l2len);

assert(ctx->decoded_extra_size == sizeof(*extra));
extra = (en10mb_extra_t *)ctx->decoded_extra;
eth = (struct tcpr_ethernet_hdr *)(packet + ctx->l2offset);
assert(eth);
/* modify source/destination MAC if source/destination IP is multicast */
if (ipv4_data) {
if ((size_t)pktlen >= sizeof(*eth) + sizeof(struct tcpr_ipv4_hdr)) {
struct tcpr_ipv4_hdr *ip_hdr = (struct tcpr_ipv4_hdr*)ipv4_data;
if (!extra->src_modified)
dlt_en10mb_ipv4_multicast_mac_update(ip_hdr->ip_src.s_addr,
eth->ether_shost);

if (!extra->dst_modified)
dlt_en10mb_ipv4_multicast_mac_update(ip_hdr->ip_dst.s_addr,
eth->ether_dhost);
}
return tcpedit_dlt_l3data_merge(ctx, packet, pktlen, ipv4_data, l2len);
} else if (ipv6_data) {
if ((size_t)pktlen >= sizeof(*eth) + sizeof(struct tcpr_ipv6_hdr)) {
struct tcpr_ipv6_hdr *ip6_hdr = (struct tcpr_ipv6_hdr*)ipv6_data;
if (!extra->src_modified)
dlt_en10mb_ipv6_multicast_mac_update(&ip6_hdr->ip_src,
eth->ether_shost);

if (!extra->dst_modified)
dlt_en10mb_ipv6_multicast_mac_update(&ip6_hdr->ip_dst,
eth->ether_dhost);
}
return tcpedit_dlt_l3data_merge(ctx, packet, pktlen, ipv6_data, l2len);
}

return NULL;
}

/*
Expand Down
6 changes: 5 additions & 1 deletion src/tcpedit/plugins/dlt_en10mb/en10mb.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,11 @@ int dlt_en10mb_decode(tcpeditdlt_t *ctx, const u_char *packet, const int pktlen)
int dlt_en10mb_encode(tcpeditdlt_t *ctx, u_char *packet, int pktlen, tcpr_dir_t dir);
int dlt_en10mb_proto(tcpeditdlt_t *ctx, const u_char *packet, const int pktlen);
u_char *dlt_en10mb_get_layer3(tcpeditdlt_t *ctx, u_char *packet, const int pktlen);
u_char *dlt_en10mb_merge_layer3(tcpeditdlt_t *ctx, u_char *packet, const int pktlen, u_char *l3data);
u_char *dlt_en10mb_merge_layer3(tcpeditdlt_t *ctx,
u_char *packet,
const int pktlen,
u_char *ipv4_data,
u_char *ipv6_data);
int dlt_en10mb_l2len(tcpeditdlt_t *ctx, const u_char *packet, const int pktlen);
u_char *dlt_en10mb_get_mac(tcpeditdlt_t *ctx, tcpeditdlt_mac_type_t mac, const u_char *packet, const int pktlen);

Expand Down
2 changes: 2 additions & 0 deletions src/tcpedit/plugins/dlt_en10mb/en10mb_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ typedef struct {
u_int16_t vlan_pri;
u_int16_t vlan_cfi;
u_int16_t vlan_proto;
bool src_modified;
bool dst_modified;
} en10mb_extra_t;

typedef enum {
Expand Down
10 changes: 7 additions & 3 deletions src/tcpedit/plugins/dlt_hdlc/hdlc.c
Original file line number Diff line number Diff line change
Expand Up @@ -339,18 +339,22 @@ dlt_hdlc_get_layer3(tcpeditdlt_t *ctx, u_char *packet, const int pktlen)
* like SPARC
*/
u_char *
dlt_hdlc_merge_layer3(tcpeditdlt_t *ctx, u_char *packet, const int pktlen, u_char *l3data)
dlt_hdlc_merge_layer3(tcpeditdlt_t *ctx,
u_char *packet,
const int pktlen,
u_char *ipv4_data,
u_char *ipv6_data)
{
int l2len;
assert(ctx);
assert(packet);
assert(l3data);
assert(ipv4_data || ipv6_data);

l2len = dlt_hdlc_l2len(ctx, packet, pktlen);
if (l2len == -1 || pktlen < l2len)
return NULL;

return tcpedit_dlt_l3data_merge(ctx, packet, pktlen, l3data, l2len);
return tcpedit_dlt_l3data_merge(ctx, packet, pktlen, ipv4_data ?: ipv6_data, l2len);
}

/*
Expand Down
6 changes: 5 additions & 1 deletion src/tcpedit/plugins/dlt_hdlc/hdlc.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,11 @@ int dlt_hdlc_decode(tcpeditdlt_t *ctx, const u_char *packet, const int pktlen);
int dlt_hdlc_encode(tcpeditdlt_t *ctx, u_char *packet, int pktlen, tcpr_dir_t dir);
int dlt_hdlc_proto(tcpeditdlt_t *ctx, const u_char *packet, const int pktlen);
u_char *dlt_hdlc_get_layer3(tcpeditdlt_t *ctx, u_char *packet, const int pktlen);
u_char *dlt_hdlc_merge_layer3(tcpeditdlt_t *ctx, u_char *packet, const int pktlen, u_char *l3data);
u_char *dlt_hdlc_merge_layer3(tcpeditdlt_t *ctx,
u_char *packet,
const int pktlen,
u_char *ipv4_data,
u_char *ipv6_data);
tcpeditdlt_l2addr_type_t dlt_hdlc_l2addr_type(void);
int dlt_hdlc_l2len(tcpeditdlt_t *ctx, const u_char *packet, const int pktlen);
u_char *dlt_hdlc_get_mac(tcpeditdlt_t *ctx, tcpeditdlt_mac_type_t mac, const u_char *packet, const int pktlen);
Expand Down
10 changes: 7 additions & 3 deletions src/tcpedit/plugins/dlt_ieee80211/ieee80211.c
Original file line number Diff line number Diff line change
Expand Up @@ -305,18 +305,22 @@ dlt_ieee80211_get_layer3(tcpeditdlt_t *ctx, u_char *packet, const int pktlen)
* like SPARC
*/
u_char *
dlt_ieee80211_merge_layer3(tcpeditdlt_t *ctx, u_char *packet, const int pktlen, u_char *l3data)
dlt_ieee80211_merge_layer3(tcpeditdlt_t *ctx,
u_char *packet,
const int pktlen,
u_char *ipv4_data,
u_char *ipv6_data)
{
int l2len;
assert(ctx);
assert(packet);
assert(l3data);
assert(ipv4_data || ipv6_data);

l2len = dlt_ieee80211_l2len(ctx, packet, pktlen);
if (l2len == -1 || pktlen < l2len)
return NULL;

return tcpedit_dlt_l3data_merge(ctx, packet, pktlen, l3data, l2len);
return tcpedit_dlt_l3data_merge(ctx, packet, pktlen, ipv4_data ?: ipv6_data, l2len);
}

/*
Expand Down
6 changes: 5 additions & 1 deletion src/tcpedit/plugins/dlt_ieee80211/ieee80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,11 @@ int dlt_ieee80211_decode(tcpeditdlt_t *ctx, const u_char *packet, const int pktl
int dlt_ieee80211_encode(tcpeditdlt_t *ctx, u_char *packet, int pktlen, tcpr_dir_t dir);
int dlt_ieee80211_proto(tcpeditdlt_t *ctx, const u_char *packet, const int pktlen);
u_char *dlt_ieee80211_get_layer3(tcpeditdlt_t *ctx, u_char *packet, const int pktlen);
u_char *dlt_ieee80211_merge_layer3(tcpeditdlt_t *ctx, u_char *packet, const int pktlen, u_char *l3data);
u_char *dlt_ieee80211_merge_layer3(tcpeditdlt_t *ctx,
u_char *packet,
const int pktlen,
u_char *ipv4_data,
u_char *ipv6_data);
tcpeditdlt_l2addr_type_t dlt_ieee80211_l2addr_type(void);
int dlt_ieee80211_l2len(tcpeditdlt_t *ctx, const u_char *packet, const int pktlen);
u_char *dlt_ieee80211_get_mac(tcpeditdlt_t *ctx, tcpeditdlt_mac_type_t mac, const u_char *packet, const int pktlen);
Expand Down
10 changes: 7 additions & 3 deletions src/tcpedit/plugins/dlt_jnpr_ether/jnpr_ether.c
Original file line number Diff line number Diff line change
Expand Up @@ -353,18 +353,22 @@ dlt_jnpr_ether_get_layer3(tcpeditdlt_t *ctx, u_char *packet, const int pktlen)
* like SPARC
*/
u_char *
dlt_jnpr_ether_merge_layer3(tcpeditdlt_t *ctx, u_char *packet, const int pktlen, u_char *l3data)
dlt_jnpr_ether_merge_layer3(tcpeditdlt_t *ctx,
u_char *packet,
const int pktlen,
u_char *ipv4_data,
u_char *ipv6_data)
{
int l2len;
assert(ctx);
assert(packet);
assert(l3data);
assert(ipv4_data || ipv6_data);

l2len = dlt_jnpr_ether_l2len(ctx, packet, pktlen);
if (l2len == -1 || pktlen < l2len)
return NULL;

return tcpedit_dlt_l3data_merge(ctx, packet, pktlen, l3data, l2len);
return tcpedit_dlt_l3data_merge(ctx, packet, pktlen, ipv4_data ?: ipv6_data, l2len);
}

/*
Expand Down
6 changes: 5 additions & 1 deletion src/tcpedit/plugins/dlt_jnpr_ether/jnpr_ether.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,11 @@ int dlt_jnpr_ether_decode(tcpeditdlt_t *ctx, const u_char *packet, const int pkt
int dlt_jnpr_ether_encode(tcpeditdlt_t *ctx, u_char *packet, int pktlen, tcpr_dir_t dir);
int dlt_jnpr_ether_proto(tcpeditdlt_t *ctx, const u_char *packet, const int pktlen);
u_char *dlt_jnpr_ether_get_layer3(tcpeditdlt_t *ctx, u_char *packet, const int pktlen);
u_char *dlt_jnpr_ether_merge_layer3(tcpeditdlt_t *ctx, u_char *packet, const int pktlen, u_char *l3data);
u_char *dlt_jnpr_ether_merge_layer3(tcpeditdlt_t *ctx,
u_char *packet,
const int pktlen,
u_char *ipv4_data,
u_char *ipv6_data);
tcpeditdlt_l2addr_type_t dlt_jnpr_ether_l2addr_type(void);
int dlt_jnpr_ether_l2len(tcpeditdlt_t *ctx, const u_char *packet, const int pktlen);
u_char *dlt_jnpr_ether_get_mac(tcpeditdlt_t *ctx, tcpeditdlt_mac_type_t mac, const u_char *packet, const int pktlen);
Expand Down
10 changes: 7 additions & 3 deletions src/tcpedit/plugins/dlt_linuxsll/linuxsll.c
Original file line number Diff line number Diff line change
Expand Up @@ -256,18 +256,22 @@ dlt_linuxsll_get_layer3(tcpeditdlt_t *ctx, u_char *packet, const int pktlen)
* like SPARC
*/
u_char *
dlt_linuxsll_merge_layer3(tcpeditdlt_t *ctx, u_char *packet, const int pktlen, u_char *l3data)
dlt_linuxsll_merge_layer3(tcpeditdlt_t *ctx,
u_char *packet,
const int pktlen,
u_char *ipv4_data,
u_char *ipv6_data)
{
int l2len;
assert(ctx);
assert(packet);
assert(l3data);
assert(ipv4_data || ipv6_data);

l2len = dlt_linuxsll_l2len(ctx, packet, pktlen);
if (l2len == -1 || pktlen < l2len)
return NULL;

return tcpedit_dlt_l3data_merge(ctx, packet, pktlen, l3data, l2len);
return tcpedit_dlt_l3data_merge(ctx, packet, pktlen, ipv4_data ?: ipv6_data, l2len);
}

/*
Expand Down
6 changes: 5 additions & 1 deletion src/tcpedit/plugins/dlt_linuxsll/linuxsll.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,11 @@ int dlt_linuxsll_decode(tcpeditdlt_t *ctx, const u_char *packet, const int pktle
int dlt_linuxsll_encode(tcpeditdlt_t *ctx, u_char *packet, int pktlen, tcpr_dir_t dir);
int dlt_linuxsll_proto(tcpeditdlt_t *ctx, const u_char *packet, const int pktlen);
u_char *dlt_linuxsll_get_layer3(tcpeditdlt_t *ctx, u_char *packet, const int pktlen);
u_char *dlt_linuxsll_merge_layer3(tcpeditdlt_t *ctx, u_char *packet, const int pktlen, u_char *l3data);
u_char *dlt_linuxsll_merge_layer3(tcpeditdlt_t *ctx,
u_char *packet,
const int pktlen,
u_char *ipv4_data,
u_char *ipv6_data);
tcpeditdlt_l2addr_type_t dlt_linuxsll_l2addr_type(void);
int dlt_linuxsll_l2len(tcpeditdlt_t *ctx, const u_char *packet, const int pktlen);
u_char *dlt_linuxsll_get_mac(tcpeditdlt_t *ctx, tcpeditdlt_mac_type_t mac, const u_char *packet, const int pktlen);
Expand Down
11 changes: 7 additions & 4 deletions src/tcpedit/plugins/dlt_null/null.c
Original file line number Diff line number Diff line change
Expand Up @@ -265,19 +265,22 @@ dlt_null_get_layer3(tcpeditdlt_t *ctx, u_char *packet, const int pktlen)
* like SPARC
*/
u_char *
dlt_null_merge_layer3(tcpeditdlt_t *ctx, u_char *packet, const int pktlen, u_char *l3data)
dlt_null_merge_layer3(tcpeditdlt_t *ctx,
u_char *packet,
const int pktlen,
u_char *ipv4_data,
u_char *ipv6_data)
{
int l2len;
assert(ctx);
assert(packet);
assert(l3data);
assert(ipv4_data || ipv6_data);

l2len = dlt_null_l2len(ctx, packet, pktlen);

if (pktlen < l2len)
return NULL;

return tcpedit_dlt_l3data_merge(ctx, packet, pktlen, l3data, l2len);
return tcpedit_dlt_l3data_merge(ctx, packet, pktlen, ipv4_data ?: ipv6_data, l2len);
}

/*
Expand Down
Loading

0 comments on commit 8b131c2

Please sign in to comment.