From 5e7f6e5f7263f8b248c16a93c050de35d904711c Mon Sep 17 00:00:00 2001 From: Bjørn Mork Date: Wed, 9 Nov 2011 16:08:39 +0100 Subject: checking more header values MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Bjørn Mork --- ldra.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 52 insertions(+), 7 deletions(-) diff --git a/ldra.c b/ldra.c index 20dcbc4..30954e2 100644 --- a/ldra.c +++ b/ldra.c @@ -270,11 +270,10 @@ int sendit(int s, char *txbuf, int len, int ifidx) } int main(int argc, char *argv[]) { - int domain, s, i; - char str[INET6_ADDRSTRLEN]; + int s; struct sockaddr_ll ll; char *buf, *txbuf; - int fromlen, len = 0; + int len = 0; int on = 1; int vlan; int size; @@ -302,6 +301,12 @@ int main(int argc, char *argv[]) { int idx_up, idx_down; + struct in6_addr all_dhcp_servers_and_relays; + + + /* prepare for comparing later on */ + inet_pton(AF_INET6, "ff02::1:2", &all_dhcp_servers_and_relays); + /* FIXME: When using VLANs, we receive the *same* packet on both main interface and VLAN interface, with no difference except for the ifindex */ @@ -453,6 +458,9 @@ Steven McCanne and Van Jacobson of Lawrence Berkeley Laboratory. } /* do some common checks before knowing whether this packet goes up or down */ + + /* we need this for checking the source port */ + udp = (struct udphdr *)(buf + sizeof(struct ethhdr) + sizeof(struct ip6_hdr)); /* NOTE: Not necessarily a relay message, but we only look at msg_type until we know for sure */ dhcpv6 = (struct dhcpv6_relay_msg *)(buf + sizeof(struct ethhdr) + sizeof(struct ip6_hdr) + sizeof(struct udphdr)); @@ -469,11 +477,17 @@ Steven McCanne and Van Jacobson of Lawrence Berkeley Laboratory. continue; } - /* FIMXE: + /* verify that destination and source address is link local verify that source port is 547 */ + /* verify that source port is correct */ + if (udp->source != htons(547)) { + fprintf(stderr, "invalid source port: %d\n", ntohs(udp->source)); + continue; + } + /* parse DHCP RELAY message */ opt = (struct dhcpv6_option *)&dhcpv6->options; txintf = parse_relay_packet(&opt, buf + len - (char *)&dhcpv6->options); @@ -485,16 +499,28 @@ Steven McCanne and Van Jacobson of Lawrence Berkeley Laboratory. fprintf(stderr, "received %d bytes from %s on interface %d (vlan=%d) with DHCPv6 type=%hhd\n", len, macstr((char *)ll.sll_addr), ll.sll_ifindex, vlan, dhcpv6->msg_type); - /* create tx packet header */ size = copyheader(txbuf, buf, txintf & 0xfff); - /* we change most of the UDP header, so create a new instead of copying */ + /* setup pointer to IPv6 header */ ip6 = (struct ip6_hdr *)(txbuf + size - sizeof(struct ip6_hdr)); + + /* verify that both source and dest are link local */ + if (!IN6_IS_ADDR_LINKLOCAL(&ip6->ip6_src)) { + fprintf(stderr, "invalid source address: %s\n", ip6str(&ip6->ip6_src)); + continue; + } + if (!IN6_IS_ADDR_LINKLOCAL(&ip6->ip6_dst)) { + fprintf(stderr, "invalid destination address: %s\n", ip6str(&ip6->ip6_dst)); + continue; + } + + /* we change most of the UDP header, so create a new instead of copying */ udp = setlen(ip6, ntohs(opt->len)); udp->dest = htons(546); udp->source = htons(547); size += sizeof(struct udphdr); + /* copy in the DHCP message */ memcpy(txbuf + size, &opt->data, ntohs(opt->len)); @@ -544,7 +570,7 @@ Steven McCanne and Van Jacobson of Lawrence Berkeley Laboratory. hopcount = dhcpv6->hop_count + 1; /* propagate */ } - /* FIMXE: + /* verify that destination address is ff02::1:2 verify that source address is link local verify that source port is 546 (unless hopcount > 0) @@ -552,6 +578,12 @@ Steven McCanne and Van Jacobson of Lawrence Berkeley Laboratory. */ + /* verify that source port is correct */ + if ((hopcount && udp->source != htons(547)) || (!hopcount && udp->source != htons(546))) { + fprintf(stderr, "invalid source port: %d\n", ntohs(udp->source)); + continue; + } + fprintf(stderr, "received %d bytes from %s on interface %d (vlan=%d) with DHCPv6 type=%hhd\n", len, macstr((char *)ll.sll_addr), ll.sll_ifindex, vlan, dhcpv6->msg_type); @@ -561,6 +593,19 @@ Steven McCanne and Van Jacobson of Lawrence Berkeley Laboratory. /* save a pointer to the IPv6 header */ ip6 = (struct ip6_hdr *)(txbuf + size - sizeof(struct ip6_hdr)); + + /* verify that source address is link local */ + if (!IN6_IS_ADDR_LINKLOCAL(&ip6->ip6_src)) { + fprintf(stderr, "invalid source address: %s\n", ip6str(&ip6->ip6_src)); + continue; + } + + /* verify that destination is ff02::1:2 */ + if (memcmp(&all_dhcp_servers_and_relays, &ip6->ip6_dst, sizeof(&ip6->ip6_dst))) { + fprintf(stderr, "invalid destination address: %s\n", ip6str(&ip6->ip6_dst)); + continue; + } + /* abusing the fact that we haven't updated this field yet */ datalen = ntohs(ip6->ip6_plen) - sizeof(struct udphdr); -- cgit v1.2.3