## diffname ip/gre.c 1997/0327 ## diff -e /dev/null /n/emeliedump/1997/0327/sys/src/brazil/ip/gre.c 0a #include "u.h" #include "../port/lib.h" #include "mem.h" #include "dat.h" #include "fns.h" #include "../port/error.h" #include "ip.h" #define DPRINT if(0)print enum { GRE_IPHDRSIZE = 20, /* size of ip header */ GRE_HDRSIZE = 4, /* minimum size of GRE header */ IP_GREPROTO = 47, GRErxms = 200, GREtickms = 100, GREmaxxmit = 10, }; typedef struct GREhdr { /* ip header */ byte vihl; /* Version and header length */ byte tos; /* Type of service */ byte len[2]; /* packet length (including headers) */ byte id[2]; /* Identification */ byte frag[2]; /* Fragment information */ byte Unused; byte proto; /* Protocol */ byte cksum[2]; /* checksum */ byte src[4]; /* Ip source */ byte dst[4]; /* Ip destination */ /* gre header */ byte flags[2]; byte eproto[2]; /* encapsulation protocol */ } GREhdr; Proto gre; extern Fs fs; int gredebug; static char* greconnect(Conv *c, char **argv, int argc) { Proto *p; char *err; Conv *tc, **cp, **ecp; err = Fsstdconnect(c, argv, argc); if(err != nil) return err; /* make sure noone's already connected to this other sys */ p = c->p; lock(p); ecp = &p->conv[p->nc]; for(cp = p->conv; cp < ecp; cp++){ tc = *cp; if(tc == nil) break; if(tc == c) continue; if(tc->rport == c->rport && tc->raddr == c->raddr){ err = "already connected to that addr/proto"; c->rport = 0; c->raddr = 0; break; } } unlock(p); Fsconnected(&fs, c, err); return err; } static int grestate(char **msg, Conv *c) { USED(c); *msg = "Datagram"; return 1; } static void grecreate(Conv *c) { c->rq = qopen(64*1024, 0, 0, c); c->wq = qopen(64*1024, 0, 0, 0); } static void greannounce(Conv *c) { Fsconnected(&fs, c, "pktifc does not support announce"); } static void greclose(Conv *c) { qclose(c->rq); qclose(c->wq); qclose(c->eq); c->laddr = 0; c->raddr = 0; c->lport = 0; c->rport = 0; unlock(c); } int drop; static void grekick(Conv *c, int l) { GREhdr *ghp; Block *bp, *f; int dlen; USED(l); bp = qget(c->wq); if(bp == nil) return; /* Round packet up to even number of bytes */ dlen = blocklen(bp); if(dlen & 1) { for(f = bp; f->next; f = f->next) ; if(f->wp >= f->lim) { f->next = allocb(1); f = f->next; } *f->wp++ = 0; } /* Make space to fit ip header (gre header already there) */ bp = padblock(bp, GRE_IPHDRSIZE); if(bp == nil) return; /* make sure the message has a GRE header */ bp = pullupblock(bp, GRE_IPHDRSIZE+GRE_HDRSIZE); if(bp == nil) return; ghp = (GREhdr *)(bp->rp); ghp->proto = IP_GREPROTO; hnputl(ghp->dst, c->raddr); hnputl(ghp->src, c->laddr); hnputs(ghp->eproto, c->rport); ipoput(bp, 0, c->ttl); } static void greiput(Block *bp) { int len; GREhdr *ghp; Ipaddr addr; Conv *c, **p; ushort eproto; ghp = (GREhdr*)(bp->rp); eproto = nhgets(ghp->eproto); addr = nhgetl(ghp->src); /* Look for a conversation structure for this port and address */ c = nil; for(p = gre.conv; *p; p++) { c = *p; if(c->inuse == 0) continue; if(c->raddr == addr && c->rport == eproto) break; } if(*p == nil) { freeblist(bp); return; } /* * Trim the packet down to data size */ len = nhgets(ghp->len) - GRE_IPHDRSIZE; if(len < GRE_HDRSIZE){ freeblist(bp); return; } bp = trimblock(bp, GRE_IPHDRSIZE, len); if(bp == nil){ gre.lenerr++; return; } /* * Can't delimit packet so pull it all into one block. */ if(qlen(c->rq) > 64*1024) freeblist(bp); else{ bp = concatblock(bp); if(bp == 0) panic("greiput"); qpass(c->rq, bp); } } void greinit(Fs *fs) { gre.name = "gre"; gre.kick = grekick; gre.connect = greconnect; gre.announce = greannounce; gre.state = grestate; gre.create = grecreate; gre.close = greclose; gre.rcv = greiput; gre.ctl = nil; gre.advise = nil; gre.ipproto = IP_GREPROTO; gre.nc = 64; gre.ptclsize = 0; Fsproto(fs, &gre); } . ## diffname ip/gre.c 1997/0403 ## diff -e /n/emeliedump/1997/0327/sys/src/brazil/ip/gre.c /n/emeliedump/1997/0403/sys/src/brazil/ip/gre.c 99c return "pktifc does not support announce"; . 96,97c static char* greannounce(Conv*, char**, int) . 78c return nil; . 76c if(err != nil) return err; Fsconnected(&fs, c, nil); . ## diffname ip/gre.c 1997/0423 ## diff -e /n/emeliedump/1997/0403/sys/src/brazil/ip/gre.c /n/emeliedump/1997/0423/sys/src/brazil/ip/gre.c 173a USED(m); . 166c greiput(Media *m, Block *bp) . ## diffname ip/gre.c 1997/0522 ## diff -e /n/emeliedump/1997/0423/sys/src/brazil/ip/gre.c /n/emeliedump/1997/0522/sys/src/brazil/ip/gre.c 160a ghp->frag[0] = 0; ghp->frag[1] = 0; . ## diffname ip/gre.c 1997/0524 ## diff -e /n/emeliedump/1997/0522/sys/src/brazil/ip/gre.c /n/emeliedump/1997/0524/sys/src/brazil/ip/gre.c 132,143d 124,125c Block *bp; . ## diffname ip/gre.c 1997/0530 ## diff -e /n/emeliedump/1997/0524/sys/src/brazil/ip/gre.c /n/emeliedump/1997/0530/sys/src/brazil/ip/gre.c 192c bp = trimblock(bp, GRE_IPONLY, len); . 187,188c len = nhgets(ghp->len) - GRE_IPONLY; if(len < GRE_IPPLUSGRE){ . 145,146c hnputl(ghp->dst, raddr); hnputl(ghp->src, laddr); . 143a raddr = nhgetl(ghp->src); laddr = nhgetl(ghp->dst); if(raddr == 0) raddr = c->raddr; if(laddr == 0 || Mediaforme(ghp->dst) <= 0) laddr = c->laddr; . 138c bp = pullupblock(bp, GRE_IPONLY+GRE_IPPLUSGRE); . 133c bp = padblock(bp, GRE_IPONLY); . 124a ulong raddr, laddr; . 14,15c GRE_IPONLY = 12, /* size of ip header */ GRE_IPPLUSGRE = 12, /* minimum size of GRE header */ . ## diffname ip/gre.c 1997/0531 ## diff -e /n/emeliedump/1997/0530/sys/src/brazil/ip/gre.c /n/emeliedump/1997/0531/sys/src/brazil/ip/gre.c 149c if(laddr == 0 || Mediaforme(ghp->src) <= 0) . 145,146c raddr = nhgetl(ghp->dst); laddr = nhgetl(ghp->src); . ## diffname ip/gre.c 1998/0306 ## diff -e /n/emeliedump/1997/0531/sys/src/brazil/ip/gre.c /n/emeliedump/1998/0306/sys/src/brazil/ip/gre.c 231a gre.stats = grestats; . 218a int grestats(char *buf, int len) { return snprint(buf, len, "gre: csum %d hlen %d len %d order %d rexmit %d\n", gre.csumerr, gre.hlenerr, gre.lenerr, gre.order, gre.rexmit); } . 183c if(c->rport == eproto && ipcmp(c->raddr, raddr) == 0) . 175d 173a v4tov6(raddr, ghp->src); . 171d 169a uchar raddr[IPaddrlen]; . 167d 163c greiput(uchar*, Block *bp) . 153,154d 145,150c v4tov6(raddr, ghp->dst); if(ipcmp(raddr, v4prefix) == 0) memmove(ghp->dst, c->raddr + IPv4off, IPv4addrlen); v4tov6(laddr, ghp->src); if(ipcmp(laddr, v4prefix) == 0){ if(ipcmp(c->laddr, IPnoaddr) == 0) findlocalip(c->laddr, raddr); /* pick interface closest to dest */ memmove(ghp->src, c->laddr + IPv4off, IPv4addrlen); } . 125c uchar laddr[IPaddrlen], raddr[IPaddrlen]; . 110,111c ipmove(c->laddr, IPnoaddr); ipmove(c->raddr, IPnoaddr); . 87,88c return snprint(state, n, "%s", "Datagram"); . 84c grestate(Conv *c, char *state, int n) . 74c qunlock(p); . 69,70c ipmove(c->laddr, IPnoaddr); ipmove(c->raddr, IPnoaddr); . 59c qlock(p); . 38,39c uchar flags[2]; uchar eproto[2]; /* encapsulation protocol */ . 26,35c uchar vihl; /* Version and header length */ uchar tos; /* Type of service */ uchar len[2]; /* packet length (including headers) */ uchar id[2]; /* Identification */ uchar frag[2]; /* Fragment information */ uchar Unused; uchar proto; /* Protocol */ uchar cksum[2]; /* checksum */ uchar src[4]; /* Ip source */ uchar dst[4]; /* Ip destination */ . ## diffname ip/gre.c 1998/0313 ## diff -e /n/emeliedump/1998/0306/sys/src/brazil/ip/gre.c /n/emeliedump/1998/0313/sys/src/brazil/ip/gre.c 244c gre = smalloc(sizeof(Proto)); gre->priv = smalloc(sizeof(GREpriv)); gre->name = "gre"; gre->kick = grekick; gre->connect = greconnect; gre->announce = greannounce; gre->state = grestate; gre->create = grecreate; gre->close = greclose; gre->rcv = greiput; gre->ctl = nil; gre->advise = nil; gre->stats = grestats; gre->ipproto = IP_GREPROTO; gre->nc = 64; gre->ptclsize = 0; Fsproto(fs, gre); . 229,242c Proto *gre; . 221,223c GREpriv *gpriv; gpriv = gre->priv; return snprint(buf, len, "gre: len %d\n", gpriv->lenerr); . 219c grestats(Proto *gre, char *buf, int len) . 201c gpriv->lenerr++; . 178c for(p = gre->conv; *p; p++) { . 170a gpriv = gre->priv; . 169a GREpriv *gpriv; . 163c greiput(Proto *gre, uchar*, Block *bp) . 159c ipoput(c->p->f, bp, 0, c->ttl); . 150c findlocalip(c->p->f, c->laddr, raddr); /* pick interface closest to dest */ . 78c Fsconnected(c, nil); . 42,44c typedef struct GREpriv GREpriv; struct GREpriv { /* non-MIB stats */ ulong csumerr; /* checksum errors */ ulong lenerr; /* short packet */ }; . ## diffname ip/gre.c 1998/0401 ## diff -e /n/emeliedump/1998/0313/sys/src/brazil/ip/gre.c /n/emeliedump/1998/0401/sys/src/brazil/ip/gre.c 71c if(tc->rport == c->rport && ipcmp(tc->raddr, c->raddr) == 0){ . ## diffname ip/gre.c 1998/0825 ## diff -e /n/emeliedump/1998/0401/sys/src/brazil/ip/gre.c /n/emeliedump/1998/0825/sys/src/brazil/ip/gre.c 231c return snprint(buf, len, "gre: len %lud\n", gpriv->lenerr); . ## diffname ip/gre.c 1999/0302 ## diff -e /n/emeliedump/1998/0825/sys/src/brazil/ip/gre.c /n/emeliedump/1999/0302/sys/src/brazil/ip/gre.c 195a qunlock(gre); . 192a qunlock(gre); . 181a qlock(gre); . 118c qunlock(c); . ## diffname ip/gre.c 1999/0817 ## diff -e /n/emeliedump/1999/0302/sys/src/brazil/ip/gre.c /n/emeliedump/1999/0817/sys/src/brazil/ip/gre.c 163c ipoput(c->p->f, bp, 0, c->ttl, c->tos); . ## diffname ip/gre.c 2000/1220 ## diff -e /n/emeliedump/1999/0817/sys/src/brazil/ip/gre.c /n/emeliedump/2000/1220/sys/src/9/ip/gre.c 117,118d ## diffname ip/gre.c 2001/0127 ## diff -e /n/emeliedump/2000/1220/sys/src/9/ip/gre.c /n/emeliedump/2001/0127/sys/src/9/ip/gre.c 97c c->rq = qopen(64*1024, 1, 0, c); . ## diffname ip/gre.c 2001/0306 ## diff -e /n/emeliedump/2001/0127/sys/src/9/ip/gre.c /n/emeliedump/2001/0306/sys/src/9/ip/gre.c 127,128d 122c grekick(Conv *c) . ## diffname ip/gre.c 2001/0623 ## diff -e /n/emeliedump/2001/0306/sys/src/9/ip/gre.c /n/emeliedump/2001/0623/sys/src/9/ip/gre.c 163c greiput(Proto *gre, Ipifc*, Block *bp) . ## diffname ip/gre.c 2002/0507 ## diff -e /n/emeliedump/2001/0623/sys/src/9/ip/gre.c /n/emeliedump/2002/0507/sys/src/9/ip/gre.c 159c ipoput4(c->p->f, bp, 0, c->ttl, c->tos); . 142a ghp->vihl = IP_VER4; . ## diffname ip/gre.c 2002/0711 ## diff -e /n/emeliedump/2002/0507/sys/src/9/ip/gre.c /n/emeliedump/2002/0711/sys/src/9/ip/gre.c 97c c->rq = qopen(64*1024, Qmsg, 0, c); . ## diffname ip/gre.c 2002/0712 ## diff -e /n/emeliedump/2002/0711/sys/src/9/ip/gre.c /n/emeliedump/2002/0712/sys/src/9/ip/gre.c 244d 123a Conv *c = x; . 122c grekick(void *x) . 94,100d 86a static void grecreate(Conv *c) { c->rq = qopen(64*1024, Qmsg, 0, c); c->wq = qopen(64*1024, Qkick, grekick, c); } . 49a static void grekick(void *x); . ## diffname ip/gre.c 2003/0220 ## diff -e /n/emeliedump/2002/0712/sys/src/9/ip/gre.c /n/emeliedump/2003/0220/sys/src/9/ip/gre.c 131d 128d 124c grekick(void *x, Block *bp) . 93c c->wq = qbypass(grekick, c); . 50c static void grekick(void *x, Block *bp); . ## diffname ip/gre.c 2003/0308 ## diff -e /n/emeliedump/2003/0220/sys/src/9/ip/gre.c /n/emeliedump/2003/0308/sys/src/9/ip/gre.c 161c ipoput4(c->p->f, bp, 0, c->ttl, c->tos, nil); .