## 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);
.
|