]> git.lizzy.rs Git - plan9front.git/blobdiff - sys/src/cmd/ip/6in4.c
snoopy(8): avoid extra spaces in dhcp filter output
[plan9front.git] / sys / src / cmd / ip / 6in4.c
index ae591a607f7ad1abb6b7e94c5c5da65aff25c8b4..dc16b2d180315a74f786b1bb7d3b3718a537d0f7 100644 (file)
@@ -46,6 +46,8 @@ struct Iphdr
 
 #define STFHDR offsetof(Iphdr, payload[0])
 
+int mtu = 1500-8;
+
 int anysender;
 int gateway;
 int debug;
@@ -71,7 +73,7 @@ static void   tunnel2ip(int, int);
 static void
 usage(void)
 {
-       fprint(2, "usage: %s [-ag] [-x mtpt] [-o mtpt] [-i local4] [local6[/mask]] [remote4 [remote6]]\n",
+       fprint(2, "usage: %s [-ag] [-m mtu] [-x mtpt] [-o mtpt] [-i local4] [local6[/mask]] [remote4 [remote6]]\n",
                argv0);
        exits("Usage");
 }
@@ -89,44 +91,28 @@ defv6addr(void)
 static void
 procargs(int argc, char **argv)
 {
-       char *p, *loc6;
+       char *ipstr, *maskstr;
 
        if (argc < 1)
-               loc6 = defv6addr();
+               ipstr = defv6addr();
        else if (strcmp(argv[0], "-") == 0) {
-               loc6 = defv6addr();
-               argv++;
-               argc--;
-       } else {
-               loc6 = *argv++;
-               argc--;
-       }
-
-       /* local v6 address (mask defaults to /128) */
-       memcpy(localmask, IPallbits, sizeof localmask);
-       p = strchr(loc6, '/');
-       if (p != nil) {
-               parseipmask(localmask, p);
-               *p = 0;
-       }
-       if (parseip(local6, loc6) == -1)
-               sysfatal("bad local v6 address %s", loc6);
-       if (isv4(local6))
-               usage();
-       if (argc >= 1 && argv[0][0] == '/') {
-               parseipmask(localmask, *argv++);
-               argc--;
-       }
+               argv++, argc--;
+               ipstr = defv6addr();
+       } else
+               ipstr = *argv++, argc--;
+       maskstr = strchr(ipstr, '/');
+       if (maskstr == nil && argc >= 1 && **argv == '/')
+               maskstr = *argv++, argc--;
+       if (parseipandmask(local6, localmask, ipstr, maskstr) == -1 || isv4(local6))
+               sysfatal("bad local v6 address/mask: %s", ipstr);
        if (debug)
                fprint(2, "local6 %I %M\n", local6, localmask);
 
        /* remote v4 address (defaults to anycast 6to4) */
        if (argc >= 1) {
-               if (parseip(remote4, *argv++) == -1)
-                       sysfatal("bad remote v4 address %s", argv[-1]);
                argc--;
-               if (!isv4(remote4))
-                       usage();
+               if (parseip(remote4, *argv++) == -1 || !isv4(remote4))
+                       sysfatal("bad remote v4 address %s", argv[-1]);
        } else {
                v4tov6(remote4, anycast6to4);
                anysender++;
@@ -136,9 +122,9 @@ procargs(int argc, char **argv)
 
        /* remote v6 address (defaults to link-local w/ v4 as interface part) */
        if (argc >= 1) {
-               if (parseip(remote6, *argv++) == -1)
-                       sysfatal("bad remote v6 address %s", argv[-1]);
                argc--;
+               if (parseip(remote6, *argv++) == -1 || isv4(remote6))
+                       sysfatal("bad remote v6 address %s", argv[-1]);
        } else {
                remote6[0] = 0xFE;              /* link local */
                remote6[1] = 0x80;
@@ -191,8 +177,8 @@ setup(int *v6net, int *tunp)
        *v6net = open(path, ORDWR);
        if (*v6net < 0 || fprint(cfd, "bind pkt") < 0)
                sysfatal("can't bind packet interface: %r");
-       /* 1280 is MTU, apparently from rfc2460 */
-       if (fprint(cfd, "add %I %M %I 1280", local6, localmask, remote6) <= 0)
+       if (fprint(cfd, "add %I %M %I %d", local6, localmask, remote6,
+               mtu - IPV4HDR_LEN) <= 0)
                sysfatal("can't set local ipv6 address: %r");
        close(cfd);
        if (debug)
@@ -255,6 +241,9 @@ main(int argc, char **argv)
        case 'g':
                gateway++;
                break;
+       case 'm':
+               mtu = atoi(EARGF(usage()));
+               break;
        case 'x':
                outside = inside = EARGF(usage());
                break;
@@ -279,31 +268,6 @@ main(int argc, char **argv)
        exits(0);
 }
 
-/*
- * based on libthread's threadsetname, but drags in less library code.
- * actually just sets the arguments displayed.
- */
-void
-procsetname(char *fmt, ...)
-{
-       int fd;
-       char *cmdname;
-       char buf[128];
-       va_list arg;
-
-       va_start(arg, fmt);
-       cmdname = vsmprint(fmt, arg);
-       va_end(arg);
-       if (cmdname == nil)
-               return;
-       snprint(buf, sizeof buf, "#p/%d/args", getpid());
-       if((fd = open(buf, OWRITE)) >= 0){
-               write(fd, cmdname, strlen(cmdname)+1);
-               close(fd);
-       }
-       free(cmdname);
-}
-
 /*
  * encapsulate v6 packets from the packet interface in v4 ones
  * and send them into the tunnel.
@@ -348,7 +312,7 @@ ip2tunnel(int in, int out)
                                ip->src, ip->dst);
                        continue;
                }
-               if ((!equivip6(ip->dst, remote6) && badipv6(ip->dst))) {
+               if ((ipcmp(ip->dst, remote6) != 0 && badipv6(ip->dst))) {
                        syslog(0, "6in4", "egress filtered %I -> %I; "
                                "bad dst not remote", ip->src, ip->dst);
                        continue;
@@ -381,7 +345,6 @@ tunnel2ip(int in, int out)
 {
        int n, m;
        char buf[64*1024];
-       uchar a[IPaddrlen];
        Ip6hdr *op;
        Iphdr *ip;
 
@@ -419,14 +382,10 @@ tunnel2ip(int in, int out)
                op = (Ip6hdr*)(buf + IPaddrlen + STFHDR);
                n -= STFHDR;
 
-               /*
-                * don't relay: just accept packets for local host/subnet
-                * (this blocks link-local and multicast addresses as well)
-                */
-               maskip(op->dst, localmask, a);
-               if (!equivip6(a, localnet)) {
-                       syslog(0, "6in4", "ingress filtered %I -> %I; "
-                               "dst not on local net", op->src, op->dst);
+               /* filter multicast and link-local, but allow relay traffic */
+               if (badipv6(op->src) || badipv6(op->dst)) {
+                       syslog(0, "6in4", "ingress filtered %I -> %I; bad src/dst",
+                               op->src, op->dst);
                        continue;
                }
                if (debug > 1)