bool validate_inner_pkt_ipv4(unsigned char *payload, u16 len) { struct iphdr *hdr_ipv4; struct tcphdr *hdr_tcp; unsigned char *inner_payload; struct tuple tuple4; if (init_ipv4_tuple(&tuple4, "2.2.2.2", 4321, "1.1.1.1", 1234, L4PROTO_TCP) != 0) return false; hdr_ipv4 = (struct iphdr *) payload; hdr_tcp = (struct tcphdr *) (hdr_ipv4 + 1); inner_payload = (unsigned char *) (hdr_tcp + 1); if (!validate_ipv4_hdr(hdr_ipv4, 1320, 0, IP_DF, 0, 0, IPPROTO_TCP, &tuple4)) return false; if (!validate_tcp_hdr(hdr_tcp, &tuple4)) return false; if (!validate_payload(inner_payload, len - sizeof(*hdr_ipv4) - sizeof(*hdr_tcp), 0)) return false; return true; }
bool validate_inner_pkt_ipv6(unsigned char *payload, u16 len) { struct ipv6hdr *hdr_ipv6; struct tcphdr *hdr_tcp; unsigned char *inner_payload; struct tuple tuple6; if (init_ipv6_tuple(&tuple6, "2::2", 4321, "1::1", 1234, L4PROTO_TCP) != 0) return false; hdr_ipv6 = (struct ipv6hdr *) payload; hdr_tcp = (struct tcphdr *) (hdr_ipv6 + 1); inner_payload = (unsigned char *) (hdr_tcp + 1); if (!validate_ipv6_hdr(hdr_ipv6, 1300, NEXTHDR_TCP, &tuple6)) return false; if (!validate_tcp_hdr(hdr_tcp, &tuple6)) return false; if (!validate_payload(inner_payload, len - sizeof(*hdr_ipv6) - sizeof(*hdr_tcp), 0)) return false; return true; }
static bool validate_frag6(struct sk_buff *skb, bool is_first, bool is_last, u16 offset, u16 payload_len, u16 payload_offset, struct tuple *tuple, l4_protocol l4proto, u16 total_payload) { size_t l4hdr_size; u16 l4_next_hdr; u16 mf = is_last ? 0 : IP6_MF; u16 hdr_payload_len; switch (l4proto) { case (L4PROTO_TCP): l4hdr_size = sizeof(struct tcphdr); l4_next_hdr = NEXTHDR_TCP; break; case (L4PROTO_UDP): l4hdr_size = sizeof(struct udphdr); l4_next_hdr = NEXTHDR_UDP; break; case (L4PROTO_ICMP): l4hdr_size = sizeof(struct icmp6hdr); l4_next_hdr = NEXTHDR_ICMP; break; default: log_debug("Invalid l4 protocol: %u", l4proto); return false; } hdr_payload_len = sizeof(struct frag_hdr) + (is_first ? l4hdr_size : 0) + payload_len; if (!skb) { log_err("The skb is NULL."); return false; } if (!validate_cb_l3(skb, L3PROTO_IPV6, sizeof(struct ipv6hdr) + sizeof(struct frag_hdr))) return false; if (!validate_cb_l4(skb, l4proto, is_first ? l4hdr_size : 0)) return false; if (!validate_cb_payload(skb, payload_len)) return false; if (!validate_ipv6_hdr(ipv6_hdr(skb), hdr_payload_len, NEXTHDR_FRAGMENT, tuple)) return false; if (!validate_frag_hdr(get_extension_header(ipv6_hdr(skb), NEXTHDR_FRAGMENT), offset, mf, l4_next_hdr)) return false; switch (l4proto) { case (L4PROTO_TCP): if (is_first && !validate_tcp_hdr(tcp_hdr(skb), tuple)) return false; break; case (L4PROTO_UDP): if (is_first && !validate_udp_hdr(udp_hdr(skb), total_payload, tuple)) return false; break; case (L4PROTO_ICMP): /*id field is not used in the validate_icmp6_hdr function.*/ if (is_first && !validate_icmp6_hdr(icmp6_hdr(skb), 1234, tuple)) return false; break; } if (!validate_payload(skb_payload(skb), payload_len, payload_offset)) return false; return true; }