From b9e97e20d79f6fc7075093745a4f6b44a5f7dd59 Mon Sep 17 00:00:00 2001 From: Mark Wooding Date: Fri, 15 Sep 2017 01:51:07 +0100 Subject: [PATCH] pathmtu/pathmtu.c (raw): Switchify the code. This is mostly an exercise in re-indenting things. There's no functional change; here, we just ease the transition to the next commit. --- pathmtu/pathmtu.c | 167 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 97 insertions(+), 70 deletions(-) diff --git a/pathmtu/pathmtu.c b/pathmtu/pathmtu.c index 65028edc..c1494796 100644 --- a/pathmtu/pathmtu.c +++ b/pathmtu/pathmtu.c @@ -475,8 +475,14 @@ static int raw_setup(void *stv, int sk, const struct param *pp) goto fail_0; /* An unfortunate bodge which will make sense in the future. */ - st->srcport = st->me.sin.sin_port; st->me.sin.sin_port = 0; - st->dstport = st->a.sin.sin_port; st->a.sin.sin_port = 0; + switch (pp->a.sa.sa_family) { + case AF_INET: + st->srcport = st->me.sin.sin_port; st->me.sin.sin_port = 0; + st->dstport = st->a.sin.sin_port; st->a.sin.sin_port = 0; + break; + default: + abort(); + } /* There isn't a portable way to force the DF flag onto a packet through * UDP, or even through raw IP, unless we write the entire IP header @@ -535,41 +541,51 @@ static int raw_xmit(void *stv, int mtu) struct phdr ph; unsigned ck; - /* Build the IP header. */ - ip = (struct ip *)b; - ip->ip_v = 4; - ip->ip_hl = sizeof(*ip)/4; - ip->ip_tos = IPTOS_RELIABILITY; - ip->ip_len = sane_htons(mtu); - STEP(st->q); ip->ip_id = htons(st->q); - ip->ip_off = sane_htons(0 | IP_DF); - ip->ip_ttl = 64; - ip->ip_p = IPPROTO_UDP; - ip->ip_sum = 0; - ip->ip_src = st->me.sin.sin_addr; - ip->ip_dst = st->a.sin.sin_addr; - - /* Build a UDP packet in the output buffer. */ - udp = (struct udphdr *)(ip + 1); - udp->uh_sport = st->srcport; - udp->uh_dport = st->dstport; - udp->uh_ulen = htons(mtu - sizeof(*ip)); - udp->uh_sum = 0; - - /* Copy the payload. */ - p = (unsigned char *)(udp + 1); - memcpy(p, buf, mtu - (p - b)); - - /* Calculate the UDP checksum. */ - ph.ph_src = ip->ip_src; - ph.ph_dst = ip->ip_dst; - ph.ph_z = 0; - ph.ph_p = IPPROTO_UDP; - ph.ph_len = udp->uh_ulen; - ck = IPCK_INIT; - ck = ipcksum(&ph, sizeof(ph), ck); - ck = ipcksum(udp, mtu - sizeof(*ip), ck); - udp->uh_sum = htons(ck); + switch (st->a.sa.sa_family) { + + case AF_INET: + + /* Build the IP header. */ + ip = (struct ip *)b; + ip->ip_v = 4; + ip->ip_hl = sizeof(*ip)/4; + ip->ip_tos = IPTOS_RELIABILITY; + ip->ip_len = sane_htons(mtu); + STEP(st->q); ip->ip_id = htons(st->q); + ip->ip_off = sane_htons(0 | IP_DF); + ip->ip_ttl = 64; + ip->ip_p = IPPROTO_UDP; + ip->ip_sum = 0; + ip->ip_src = st->me.sin.sin_addr; + ip->ip_dst = st->a.sin.sin_addr; + + /* Build a UDP packet in the output buffer. */ + udp = (struct udphdr *)(ip + 1); + udp->uh_sport = st->srcport; + udp->uh_dport = st->dstport; + udp->uh_ulen = htons(mtu - sizeof(*ip)); + udp->uh_sum = 0; + + /* Copy the payload. */ + p = (unsigned char *)(udp + 1); + memcpy(p, buf, mtu - (p - b)); + + /* Calculate the UDP checksum. */ + ph.ph_src = ip->ip_src; + ph.ph_dst = ip->ip_dst; + ph.ph_z = 0; + ph.ph_p = IPPROTO_UDP; + ph.ph_len = udp->uh_ulen; + ck = IPCK_INIT; + ck = ipcksum(&ph, sizeof(ph), ck); + ck = ipcksum(udp, mtu - sizeof(*ip), ck); + udp->uh_sum = htons(ck); + + break; + + default: + abort(); + } /* Send the whole thing off. If we're too big for the interface then we * might need to trim immediately. @@ -600,40 +616,51 @@ static int raw_selproc(void *stv, fd_set *fd_in, struct probestate *ps) if (FD_ISSET(st->rawicmp, fd_in)) { if ((n = read(st->rawicmp, b, sizeof(b))) < 0) goto fail_0; - ip = (struct ip *)b; - if (n < sizeof(*ip) || n < sizeof(4*ip->ip_hl) || - ip->ip_v != 4 || ip->ip_p != IPPROTO_ICMP) - goto skip_icmp; - n -= sizeof(4*ip->ip_hl); - - icmp = (struct icmp *)(b + 4*ip->ip_hl); - if (n < sizeof(*icmp) || icmp->icmp_type != ICMP_UNREACH) - goto skip_icmp; - n -= offsetof(struct icmp, icmp_ip); - - ip = &icmp->icmp_ip; - if (n < sizeof(*ip) || - ip->ip_p != IPPROTO_UDP || ip->ip_hl != sizeof(*ip)/4 || - ip->ip_id != htons(st->q) || - ip->ip_src.s_addr != st->me.sin.sin_addr.s_addr || - ip->ip_dst.s_addr != st->a.sin.sin_addr.s_addr) - goto skip_icmp; - n -= sizeof(*ip); - - udp = (struct udphdr *)(ip + 1); - if (n < sizeof(*udp) || udp->uh_sport != st->srcport || - udp->uh_dport != st->dstport) - goto skip_icmp; - n -= sizeof(*udp); - - payload = (const unsigned char *)(udp + 1); - if (!mypacketp(ps, payload, n)) goto skip_icmp; - - if (icmp->icmp_code == ICMP_UNREACH_PORT) return (RC_HIGHER); - else if (icmp->icmp_code != ICMP_UNREACH_NEEDFRAG) goto skip_icmp; - else if (icmp->icmp_nextmtu) return (htons(icmp->icmp_nextmtu)); - else return (RC_LOWER); + switch (st->me.sa.sa_family) { + + case AF_INET: + + ip = (struct ip *)b; + if (n < sizeof(*ip) || n < sizeof(4*ip->ip_hl) || + ip->ip_v != 4 || ip->ip_p != IPPROTO_ICMP) + goto skip_icmp; + n -= sizeof(4*ip->ip_hl); + + icmp = (struct icmp *)(b + 4*ip->ip_hl); + if (n < sizeof(*icmp) || icmp->icmp_type != ICMP_UNREACH) + goto skip_icmp; + n -= offsetof(struct icmp, icmp_ip); + + ip = &icmp->icmp_ip; + if (n < sizeof(*ip) || + ip->ip_p != IPPROTO_UDP || ip->ip_hl != sizeof(*ip)/4 || + ip->ip_id != htons(st->q) || + ip->ip_src.s_addr != st->me.sin.sin_addr.s_addr || + ip->ip_dst.s_addr != st->a.sin.sin_addr.s_addr) + goto skip_icmp; + n -= sizeof(*ip); + + udp = (struct udphdr *)(ip + 1); + if (n < sizeof(*udp) || udp->uh_sport != st->srcport || + udp->uh_dport != st->dstport) + goto skip_icmp; + n -= sizeof(*udp); + + payload = (const unsigned char *)(udp + 1); + if (!mypacketp(ps, payload, n)) goto skip_icmp; + + if (icmp->icmp_code == ICMP_UNREACH_PORT) return (RC_HIGHER); + else if (icmp->icmp_code != ICMP_UNREACH_NEEDFRAG) goto skip_icmp; + else if (icmp->icmp_nextmtu) return (htons(icmp->icmp_nextmtu)); + else return (RC_LOWER); + + break; + + default: + abort(); + } } + skip_icmp:; /* If we got a reply to the current probe then we're good. If we got an -- 2.11.0