chiark / gitweb /
pathmtu/pathmtu.c (raw): Maintain the port numbers separately.
authorMark Wooding <mdw@distorted.org.uk>
Fri, 15 Sep 2017 00:46:31 +0000 (01:46 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Thu, 28 Jun 2018 23:26:39 +0000 (00:26 +0100)
The Linux raw-IPv6-sockets machinery doesn't like port numbers in socket
addresses, so keep track of the ports separately and clear out the port
numbers in the address structures.

pathmtu/pathmtu.c

index 4e8f568fb33f295e5c52d054e59c814407f4fca8..65028edc1e76f45d87681c562bf5aad7a1195968 100644 (file)
@@ -441,6 +441,7 @@ struct phdr {
 struct raw_state {
   union addr me, a;
   int sk, rawicmp, rawudp;
+  uint16_t srcport, dstport;
   unsigned q;
 };
 
@@ -473,6 +474,10 @@ static int raw_setup(void *stv, int sk, const struct param *pp)
   if (getsockname(sk, &st->me.sa, &sz))
     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;
+
   /* 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
    * ourselves.  This is somewhat annoying, especially since we have an
@@ -546,8 +551,8 @@ static int raw_xmit(void *stv, int mtu)
 
   /* Build a UDP packet in the output buffer. */
   udp = (struct udphdr *)(ip + 1);
-  udp->uh_sport = st->me.sin.sin_port;
-  udp->uh_dport = st->a.sin.sin_port;
+  udp->uh_sport = st->srcport;
+  udp->uh_dport = st->dstport;
   udp->uh_ulen = htons(mtu - sizeof(*ip));
   udp->uh_sum = 0;
 
@@ -616,8 +621,8 @@ static int raw_selproc(void *stv, fd_set *fd_in, struct probestate *ps)
     n -= sizeof(*ip);
 
     udp = (struct udphdr *)(ip + 1);
-    if (n < sizeof(*udp) || udp->uh_sport != st->me.sin.sin_port ||
-       udp->uh_dport != st->a.sin.sin_port)
+    if (n < sizeof(*udp) || udp->uh_sport != st->srcport ||
+       udp->uh_dport != st->dstport)
       goto skip_icmp;
     n -= sizeof(*udp);