Skip to content

Commit

Permalink
Feature #625 - fixes for tcpprep tree
Browse files Browse the repository at this point in the history
  • Loading branch information
fklassen committed Jun 29, 2021
1 parent 193473c commit 103ad16
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 79 deletions.
6 changes: 1 addition & 5 deletions src/common/flows.c
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ flow_entry_type_t flow_decode(flow_hash_table_t *fht, const struct pcap_pkthdr *
uint32_t pkt_len = pkthdr->caplen;
const u_char *packet = pktdata;
uint32_t _U_ vlan_offset;
uint32_t _U_ l2offset;
uint16_t ether_type = 0;
ipv4_hdr_t *ip_hdr = NULL;
ipv6_hdr_t *ip6_hdr = NULL;
Expand All @@ -172,7 +173,6 @@ flow_entry_type_t flow_decode(flow_hash_table_t *fht, const struct pcap_pkthdr *
icmpv4_hdr_t *icmp_hdr;
flow_entry_data_t entry;
uint32_t l2len = 0;
uint32_t l2offset;
uint8_t protocol;
uint32_t hash;
int ip_len;
Expand Down Expand Up @@ -201,10 +201,6 @@ flow_entry_type_t flow_decode(flow_hash_table_t *fht, const struct pcap_pkthdr *
return FLOW_ENTRY_INVALID;
}

packet += l2offset;
l2len -= l2offset;
pkt_len -= l2offset;

assert(l2len > 0);

if (ether_type == ETHERTYPE_IP) {
Expand Down
4 changes: 0 additions & 4 deletions src/send_packets.c
Original file line number Diff line number Diff line change
Expand Up @@ -113,10 +113,6 @@ fast_edit_packet(struct pcap_pkthdr *pkthdr, u_char **pktdata,
if (res < 0)
return res;

packet += l2offset;
l2len -= l2offset;
pkt_len -= l2offset;

assert(l2len > 0);

switch (ether_type) {
Expand Down
99 changes: 30 additions & 69 deletions src/tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,6 @@ void
add_tree_first_ipv4(const u_char *data, const int len, const int datalink)
{
tcpr_tree_t *newnode, *findnode;
const u_char *packet = data;
uint32_t _U_ vlan_offset;
uint32_t pkt_len = len;
uint16_t ether_type;
Expand All @@ -382,32 +381,28 @@ add_tree_first_ipv4(const u_char *data, const int len, const int datalink)
uint32_t l2len;
int res;

assert(packet);
assert(data);

res = get_l2len_protocol(packet,
res = get_l2len_protocol(data,
pkt_len,
datalink,
&ether_type,
&l2len,
&l2offset,
&vlan_offset);

if (res == -1 || len < (TCPR_ETH_H + TCPR_IPV4_H)) {
if (res == -1 || len < (int)(l2len + TCPR_IPV4_H)) {
errx(-1, "Capture length %d too small for IPv4 parsing", len);
return;
}

packet += l2offset;
l2len -= l2offset;
pkt_len -= l2offset;

/*
* first add/find the source IP/client
*/
newnode = new_tree();

/* prevent issues with byte alignment, must memcpy */
memcpy(&ip_hdr, (packet + TCPR_ETH_H), TCPR_IPV4_H);
memcpy(&ip_hdr, data + l2len, TCPR_IPV4_H);

/* copy over the source ip, and values to guarantee this a client */
newnode->family = AF_INET;
Expand All @@ -427,7 +422,7 @@ add_tree_first_ipv4(const u_char *data, const int len, const int datalink)
* now add/find the destination IP/server
*/
newnode = new_tree();
memcpy(&ip_hdr, (packet + TCPR_ETH_H), TCPR_IPV4_H);
memcpy(&ip_hdr, data + l2len, TCPR_IPV4_H);

newnode->family = AF_INET;
newnode->u.ip = ip_hdr.ip_dst.s_addr;
Expand All @@ -446,7 +441,6 @@ void
add_tree_first_ipv6(const u_char *data, const int len, const int datalink)
{
tcpr_tree_t *newnode, *findnode;
const u_char *packet = data;
uint32_t _U_ vlan_offset;
uint32_t pkt_len = len;
uint16_t ether_type;
Expand All @@ -455,32 +449,28 @@ add_tree_first_ipv6(const u_char *data, const int len, const int datalink)
uint32_t l2len;
int res;

assert(packet);
assert(data);

res = get_l2len_protocol(packet,
res = get_l2len_protocol(data,
pkt_len,
datalink,
&ether_type,
&l2len,
&l2offset,
&vlan_offset);

if (res == -1 || len < (TCPR_ETH_H + TCPR_IPV6_H)) {
if (res == -1 || len < (int)(l2len + TCPR_IPV6_H)) {
errx(-1, "Capture length %d too small for IPv6 parsing", len);
return;
}

packet += l2offset;
l2len -= l2offset;
pkt_len -= l2offset;

/*
* first add/find the source IP/client
*/
newnode = new_tree();

/* prevent issues with byte alignment, must memcpy */
memcpy(&ip6_hdr, (packet + TCPR_ETH_H), TCPR_IPV6_H);
memcpy(&ip6_hdr, data + l2len, TCPR_IPV6_H);

/* copy over the source ip, and values to guarantee this a client */
newnode->family = AF_INET6;
Expand All @@ -500,7 +490,7 @@ add_tree_first_ipv6(const u_char *data, const int len, const int datalink)
* now add/find the destination IP/server
*/
newnode = new_tree();
memcpy(&ip6_hdr, (packet + TCPR_ETH_H), TCPR_IPV6_H);
memcpy(&ip6_hdr, data + l2len, TCPR_IPV6_H);

newnode->family = AF_INET6;
newnode->u.ip6 = ip6_hdr.ip_dst;
Expand Down Expand Up @@ -741,11 +731,9 @@ new_tree()
static tcpr_tree_t *
packet2tree(const u_char * data, const int len, int datalink)
{
const u_char *packet = data;
uint32_t _U_ vlan_offset;
ssize_t pkt_len = len;
tcpr_tree_t *node = NULL;
eth_hdr_t *eth_hdr = NULL;
ipv4_hdr_t ip_hdr;
ipv6_hdr_t ip6_hdr;
tcp_hdr_t tcp_hdr;
Expand All @@ -763,91 +751,67 @@ packet2tree(const u_char * data, const int len, int datalink)
char srcip[INET6_ADDRSTRLEN];
#endif

res = get_l2len_protocol(packet,
res = get_l2len_protocol(data,
pkt_len,
datalink,
&ether_type,
&l2len,
&l2offset,
&vlan_offset);

if (res == -1 || len < (int)sizeof(*eth_hdr))
if (res == -1)
goto len_error;

node = new_tree();

packet += l2offset;
l2len -= l2offset;
pkt_len -= l2offset;

assert(l2len > 0);

eth_hdr = (eth_hdr_t *) (packet);
if (ether_type == ETHERTYPE_IP) {
if (pkt_len < (TCPR_ETH_H + hl + TCPR_IPV4_H)) {
safe_free(node);
errx(-1, "packet capture length %d too small for IPv4 processing",
len);
return NULL;
}

if (pkt_len < TCPR_ETH_H + TCPR_IPV4_H + hl) {
if (pkt_len < l2len + TCPR_IPV4_H + hl)
goto len_error;
}

memcpy(&ip_hdr, packet + TCPR_ETH_H + hl, TCPR_IPV4_H);
memcpy(&ip_hdr, data + l2len + hl, TCPR_IPV4_H);

node->family = AF_INET;
node->u.ip = ip_hdr.ip_src.s_addr;
proto = ip_hdr.ip_p;
hl += ip_hdr.ip_hl * 4;

#ifdef DEBUG
strlcpy(srcip, get_addr2name4(ip_hdr.ip_src.s_addr,
RESOLVE), 16);
strlcpy(srcip, get_addr2name4(ip_hdr.ip_src.s_addr, RESOLVE), 16);
#endif
} else if (ether_type == ETHERTYPE_IP6) {
if (pkt_len < (TCPR_ETH_H + hl + TCPR_IPV6_H)) {
safe_free(node);
errx(-1, "packet capture length %d too small for IPv6 processing",
len);
return NULL;
}

if (pkt_len < TCPR_ETH_H + TCPR_IPV6_H + hl) {
if (pkt_len < l2len + TCPR_IPV6_H + hl) {
goto len_error;
}

memcpy(&ip6_hdr, packet + TCPR_ETH_H + hl, TCPR_IPV6_H);
memcpy(&ip6_hdr, data + l2len + hl, TCPR_IPV6_H);

node->family = AF_INET6;
node->u.ip6 = ip6_hdr.ip_src;
proto = ip6_hdr.ip_nh;
hl += TCPR_IPV6_H;

#ifdef DEBUG
strlcpy(srcip, get_addr2name6(&ip6_hdr.ip_src, RESOLVE), INET6_ADDRSTRLEN);
strlcpy(srcip, get_addr2name6(&ip6_hdr.ip_src, RESOLVE),
INET6_ADDRSTRLEN);
#endif
} else {
dbgx(2,"Unrecognized ether_type (%x)", ether_type);
}


/* copy over the source mac */
strlcpy((char *)node->mac, (char *)eth_hdr->ether_shost, sizeof(node->mac));

/*
* TCP
*/
if (proto == IPPROTO_TCP) {

dbgx(3, "%s uses TCP... ", srcip);

if (pkt_len < TCPR_ETH_H + TCPR_TCP_H + hl)
if (pkt_len < l2len + TCPR_TCP_H + hl)
goto len_error;

/* memcpy it over to prevent alignment issues */
memcpy(&tcp_hdr, (data + TCPR_ETH_H + hl), TCPR_TCP_H);
memcpy(&tcp_hdr, data + l2len + hl, TCPR_TCP_H);

/* ftp-data is going to skew our results so we ignore it */
if (tcp_hdr.th_sport == 20)
Expand All @@ -865,27 +829,25 @@ packet2tree(const u_char * data, const int len, int datalink)
else {
dbg(3, "is an unknown");
}

}
/*
* UDP
*/
else if (proto == IPPROTO_UDP) {
if (pkt_len < TCPR_ETH_H + TCPR_UDP_H + hl)
if (pkt_len < l2len + TCPR_UDP_H + hl)
goto len_error;

/* memcpy over to prevent alignment issues */
memcpy(&udp_hdr, (data + TCPR_ETH_H + hl), TCPR_UDP_H);
memcpy(&udp_hdr, data + l2len + hl, TCPR_UDP_H);
dbgx(3, "%s uses UDP... ", srcip);

switch (ntohs(udp_hdr.uh_dport)) {
case 0x0035: /* dns */
if (pkt_len < TCPR_ETH_H + TCPR_UDP_H + TCPR_DNS_H + hl)
if (pkt_len < l2len + TCPR_UDP_H + TCPR_DNS_H + hl)
goto len_error;

/* prevent memory alignment issues */
memcpy(&dnsv4_hdr,
(data + TCPR_ETH_H + hl + TCPR_UDP_H), TCPR_DNS_H);
memcpy(&dnsv4_hdr, data + l2len + hl + TCPR_UDP_H, TCPR_DNS_H);

if (dnsv4_hdr.flags & DNS_QUERY_FLAG) {
/* bit set, response */
Expand All @@ -908,13 +870,11 @@ packet2tree(const u_char * data, const int len, int datalink)

switch (ntohs(udp_hdr.uh_sport)) {
case 0x0035: /* dns */
if (pkt_len < TCPR_ETH_H + TCPR_UDP_H + TCPR_DNS_H + hl)
if (pkt_len < l2len + TCPR_UDP_H + TCPR_DNS_H + hl)
goto len_error;

/* prevent memory alignment issues */
memcpy(&dnsv4_hdr,
(data + TCPR_ETH_H + hl + TCPR_UDP_H),
TCPR_DNS_H);
memcpy(&dnsv4_hdr, data + l2len + hl + TCPR_UDP_H, TCPR_DNS_H);

if ((dnsv4_hdr.flags & 0x7FFFF) ^ DNS_QUERY_FLAG) {
/* bit set, response */
Expand All @@ -939,11 +899,11 @@ packet2tree(const u_char * data, const int len, int datalink)
* ICMP
*/
else if (proto == IPPROTO_ICMP) {
if (pkt_len < TCPR_ETH_H + TCPR_ICMPV4_H + hl)
if (pkt_len < l2len + TCPR_ICMPV4_H + hl)
goto len_error;

/* prevent alignment issues */
memcpy(&icmp_hdr, (data + TCPR_ETH_H + hl), TCPR_ICMPV4_H);
memcpy(&icmp_hdr, data + l2len + hl, TCPR_ICMPV4_H);

dbgx(3, "%s uses ICMP... ", srcip);

Expand All @@ -961,6 +921,7 @@ packet2tree(const u_char * data, const int len, int datalink)
return (node);

len_error:
safe_free(node);
errx(-1, "packet capture length %d too small to process", len);
return NULL;
}
Expand Down
1 change: 0 additions & 1 deletion src/tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ typedef struct tcpr_tree_s {
unsigned long ip; /* ip/network address in network byte order */
struct tcpr_in6_addr ip6;
} u;
u_char mac[ETHER_ADDR_LEN]; /* mac address of system */
int masklen; /* CIDR network mask length */
int server_cnt; /* count # of times this entry was flagged server */
int client_cnt; /* flagged client */
Expand Down

0 comments on commit 103ad16

Please sign in to comment.