Plan 9 from Bell Labs’s /usr/web/sources/extra/9hist/ip/udp.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


## diffname ip/udp.c 1997/0327
## diff -e /dev/null /n/emeliedump/1997/0327/sys/src/brazil/ip/udp.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
{
	UDP_PHDRSIZE	= 12,
	UDP_HDRSIZE	= 20,
	UDP_IPHDR	= 8,
	IP_UDPPROTO	= 17,
	UDP_USEAD	= 6,
	UDP_RELSIZE	= 16,

	Udprxms		= 200,
	Udptickms	= 100,
	Udpmaxxmit	= 10,
};

typedef struct Udphdr Udphdr;
struct Udphdr
{
	/* ip header */
	byte	vihl;		/* Version and header length */
	byte	tos;		/* Type of service */
	byte	length[2];	/* packet length */
	byte	id[2];		/* Identification */
	byte	frag[2];	/* Fragment information */
	byte	Unused;	
	byte	udpproto;	/* Protocol */
	byte	udpplen[2];	/* Header plus data length */
	byte	udpsrc[4];	/* Ip source */
	byte	udpdst[4];	/* Ip destination */

	/* udp header */
	byte	udpsport[2];	/* Source port */
	byte	udpdport[2];	/* Destination port */
	byte	udplen[2];	/* data length */
	byte	udpcksum[2];	/* Checksum */
};

/*
 *  protocol specific part of Conv
 */
typedef struct Udpcb Udpcb;
struct Udpcb
{
	QLock;
	byte	headers;
};

	Proto	udp;
	int	udpsum;
	uint	generation;
extern	Fs	fs;
	int	udpdebug;

static char*
udpconnect(Conv *c, char **argv, int argc)
{
	char *e;

	e = Fsstdconnect(c, argv, argc);
	Fsconnected(&fs, c, e);

	return e;
}

int
udpstate(char **s, Conv *c)
{
	USED(c);
	*s = "Datagram";
	return 1;
}

static void
udpannounce(Conv *c)
{
	Fsconnected(&fs, c, nil);
}

static void
udpcreate(Conv *c)
{
	c->rq = qopen(16*1024, 1, 0, 0);
	c->wq = qopen(16*1024, 0, 0, 0);
}

static void
udpclose(Conv *c)
{
	Udpcb *ucb;

	qclose(c->rq);
	qclose(c->wq);
	qclose(c->eq);
	c->laddr = 0;
	c->raddr = 0;
	c->lport = 0;
	c->rport = 0;

	ucb = (Udpcb*)c->ptcl;
	ucb->headers = 0;

	unlock(c);
}

void
udpkick(Conv *c, int l)
{
	Udphdr *uh;
	ushort port;
	Ipaddr addr;
	Block *bp, *f;
	Udpcb *ucb;
	int dlen, ptcllen;

	USED(l);

	bp = qget(c->wq);
	if(bp == nil)
		return;

	ucb = (Udpcb*)c->ptcl;
	if(ucb->headers) {
		/* get user specified addresses */
		bp = pullupblock(bp, UDP_USEAD);
		if(bp == nil) {
			freeblist(bp);
			return;
		}
		addr = nhgetl(bp->rp);
		bp->rp += 4;
		port = nhgets(bp->rp);
		bp->rp += 2;
	} else {
		addr = 0;
		port = 0;
	}

	/* 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;
		dlen++;	
	}

	/* Make space to fit udp & ip header */
	bp = padblock(bp, UDP_IPHDR+UDP_HDRSIZE);
	if(bp == nil)
		return;

	uh = (Udphdr *)(bp->rp);

	ptcllen = dlen + (UDP_HDRSIZE-UDP_PHDRSIZE);
	uh->Unused = 0;
	uh->udpproto = IP_UDPPROTO;
	uh->frag[0] = 0;
	uh->frag[1] = 0;
	hnputs(uh->udpplen, ptcllen);
	if(ucb->headers) {
		hnputl(uh->udpdst, addr);
		hnputs(uh->udpdport, port);

		/* pick the closest source address (best we can do) */
		hnputl(uh->udpsrc, Mediagetsrc(uh->udpdst));
	} else {
		hnputl(uh->udpdst, c->raddr);
		hnputs(uh->udpdport, c->rport);
		hnputl(uh->udpsrc, c->laddr);
	}
	hnputs(uh->udpsport, c->lport);
	hnputs(uh->udplen, ptcllen);
	uh->udpcksum[0] = 0;
	uh->udpcksum[1] = 0;

	hnputs(uh->udpcksum, ptclcsum(bp, UDP_IPHDR, dlen+UDP_HDRSIZE));

	ipoput(bp, 0, c->ttl);
}

void
udpiput(Block *bp)
{
	int len;
	Udphdr *uh;
	Ipaddr addr;
	Conv *c, **p;
	Udpcb *ucb;
	ushort dport, sport;

	uh = (Udphdr*)(bp->rp);

	/* Put back pseudo header for checksum */
	uh->Unused = 0;
	len = nhgets(uh->udplen);
	hnputs(uh->udpplen, len);

	addr = nhgetl(uh->udpsrc);

	if(udpsum && nhgets(uh->udpcksum)) {
		if(ptclcsum(bp, UDP_IPHDR, len+UDP_PHDRSIZE)) {
			udp.csumerr++;
			netlog(Logudp, "udp: checksum error %I\n", uh->udpsrc);
			freeblist(bp);
			return;
		}
	}

	dport = nhgets(uh->udpdport);
	sport = nhgets(uh->udpsport);

	/* Look for a conversation structure for this port */
	c = nil;
	for(p = udp.conv; *p; p++) {
		c = *p;
		if(c->inuse == 0)
			continue;
		if(c->lport == dport && (c->rport == 0 || c->rport == sport))
			break;
	}

	if(*p == nil) {
		freeblist(bp);
		return;
	}

	/*
	 * Trim the packet down to data size
	 */
	len -= (UDP_HDRSIZE-UDP_PHDRSIZE);
	bp = trimblock(bp, UDP_IPHDR+UDP_HDRSIZE, len);
	if(bp == nil){
		udp.lenerr++;
		return;
	}

	ucb = (Udpcb*)c->ptcl;

	if(ucb->headers) {
		/* pass the src address */
		bp = padblock(bp, UDP_USEAD);
		hnputl(bp->rp, addr);
		hnputs(bp->rp+4, sport);
	} else {
		/* connection oriented udp */
		if(c->raddr == 0){
			/* save the src address in the conversation */
		 	c->raddr = addr;
			c->rport = sport;

			/* reply with the same ip address (if not broadcast) */
			if(Mediaforme(uh->udpdst) > 0)
				c->laddr = nhgetl(uh->udpdst);
		}
	}
	if(bp->next)
		bp = concatblock(bp);

	if(qfull(c->rq))
		freeblist(bp);
	else
		qpass(c->rq, bp);
}

char*
udpctl(Conv *c, char **f, int n)
{
	Udpcb *ucb;

	ucb = (Udpcb*)c->ptcl;
	if(n == 1 && strcmp(f[0], "headers") == 0){
		ucb->headers = 1;
		return nil;
	}
	if(n == 1 && strcmp(f[0], "debug") == 0){
		udpdebug = 1;
		return nil;
	}
	return "unknown control request";
}

void
udpinit(Fs *fs)
{
	udp.name = "udp";
	udp.kick = udpkick;
	udp.connect = udpconnect;
	udp.announce = udpannounce;
	udp.ctl = udpctl;
	udp.state = udpstate;
	udp.create = udpcreate;
	udp.close = udpclose;
	udp.rcv = udpiput;
	udp.ipproto = IP_UDPPROTO;
	udp.nc = 16;
	udp.ptclsize = sizeof(Udpcb);

	Fsproto(fs, &udp);
}
.
## diffname ip/udp.c 1997/0403
## diff -e /n/emeliedump/1997/0327/sys/src/brazil/ip/udp.c /n/emeliedump/1997/0403/sys/src/brazil/ip/udp.c
86a

	return nil;
.
83,84c
static char*
udpannounce(Conv *c, char**, int)
.
## diffname ip/udp.c 1997/0411
## diff -e /n/emeliedump/1997/0403/sys/src/brazil/ip/udp.c /n/emeliedump/1997/0411/sys/src/brazil/ip/udp.c
85a
	char *e;

	e = Fsstdannounce(c, argv, argc);
	if(e != nil)
		return e;
.
84c
udpannounce(Conv *c, char** argv, int argc)
.
## diffname ip/udp.c 1997/0423
## diff -e /n/emeliedump/1997/0411/sys/src/brazil/ip/udp.c /n/emeliedump/1997/0423/sys/src/brazil/ip/udp.c
211a
	USED(m);
.
203c
udpiput(Media *m, Block *bp)
.
## diffname ip/udp.c 1997/0530
## diff -e /n/emeliedump/1997/0423/sys/src/brazil/ip/udp.c /n/emeliedump/1997/0530/sys/src/brazil/ip/udp.c
270,271c
		 	c->raddr = raddr;
			c->rport = rport;
.
264,265c
		hnputl(bp->rp, raddr);
		hnputl(bp->rp+4, laddr);
		hnputs(bp->rp+8, rport);
		hnputs(bp->rp+10, lport);
.
240c
		if(c->lport == lport && (c->rport == 0 || c->rport == rport))
.
231,232c
	lport = nhgets(uh->udpdport);
	rport = nhgets(uh->udpsport);
.
220c
	raddr = nhgetl(uh->udpsrc);
	laddr = nhgetl(uh->udpdst);
.
210c
	Ipaddr raddr, laddr;
	ushort rport, lport;
.
207d
182,186c
		hnputl(uh->udpdst, raddr);
		hnputs(uh->udpdport, rport);
		if(laddr)
			hnputl(uh->udpsrc, laddr);
		else
			hnputl(uh->udpsrc, Mediagetsrc(uh->udpdst));
.
151,152c
		raddr = 0;
		rport = 0;
		laddr = 0;
.
149a
		/* ignore local port number */
		bp->rp += 2;
.
148c
		laddr = nhgetl(bp->rp);
		if(laddr != 0 && Mediaforme(bp->rp) <= 0)
			laddr = 0;
		bp->rp += 4;
		rport = nhgets(bp->rp);
.
146c
		raddr = nhgetl(bp->rp);
.
126,127c
	ushort rport;
	Ipaddr laddr, raddr;
.
18,19c
	UDP_USEAD	= 12,
.
## diffname ip/udp.c 1997/0708
## diff -e /n/emeliedump/1997/0530/sys/src/brazil/ip/udp.c /n/emeliedump/1997/0708/sys/src/brazil/ip/udp.c
285c
				c->laddr = laddr;
			else
				c->laddr = m->myip[0];
.
273c
		if(Mediaforme(uh->udpdst) > 0)
			hnputl(bp->rp+4, laddr);
		else
			hnputl(bp->rp+4, m->myip[0]);
.
## diffname ip/udp.c 1997/0725
## diff -e /n/emeliedump/1997/0708/sys/src/brazil/ip/udp.c /n/emeliedump/1997/0725/sys/src/brazil/ip/udp.c
298c
	}else
.
296c
	if(qfull(c->rq)){
		netlog(Logudp, "udp: qfull %I.%d -> %I.%d\n", uh->udpsrc, rport,
			uh->udpdst, lport);
.
262a
		netlog(Logudp, "udp: len err %I.%d -> %I.%d\n", uh->udpsrc, rport,
			uh->udpdst, lport);
.
252a
		netlog(Logudp, "udp: no conv %I.%d -> %I.%d\n", uh->udpsrc, rport,
			uh->udpdst, lport);
.
239,241d
228a
	lport = nhgets(uh->udpdport);
	rport = nhgets(uh->udpsport);
.
## diffname ip/udp.c 1997/0806
## diff -e /n/emeliedump/1997/0725/sys/src/brazil/ip/udp.c /n/emeliedump/1997/0806/sys/src/brazil/ip/udp.c
268a

	netlog(Logudpmsg, "udp: %I.%d -> %I.%d l %d\n", uh->udpsrc, rport,
		uh->udpdst, lport, len);
.
163,172d
161d
127c
	Block *bp;
.
98,99c
	c->rq = qopen(64*1024, 1, 0, 0);
	c->wq = qopen(64*1024, 0, 0, 0);
.
## diffname ip/udp.c 1997/0815
## diff -e /n/emeliedump/1997/0806/sys/src/brazil/ip/udp.c /n/emeliedump/1997/0815/sys/src/brazil/ip/udp.c
292,293c
		netlog(Logudp, "udp: qfull %I.%d -> %I.%d\n", src, rport,
			dst, lport);
.
282c
			if(Mediaforme(dst) > 0)
.
268c
		if(Mediaforme(dst) > 0)
.
259,260c
	netlog(Logudpmsg, "udp: %I.%d -> %I.%d l %d\n", src, rport,
		dst, lport, len);
.
253,254c
		netlog(Logudp, "udp: len err %I.%d -> %I.%d\n", src, rport,
			dst, lport);
.
241,242c
		netlog(Logudp, "udp: no conv %I.%d -> %I.%d\n", src, rport,
			dst, lport);
.
224c
			netlog(Logudp, "udp: checksum error %I\n", src);
.
219a
	memmove(src, uh->udpsrc, IPaddrlen);
	memmove(dst, uh->udpdst, IPaddrlen);
.
206a
	uchar dst[IPaddrlen];
	uchar src[IPaddrlen];
.
## diffname ip/udp.c 1997/0829
## diff -e /n/emeliedump/1997/0815/sys/src/brazil/ip/udp.c /n/emeliedump/1997/0829/sys/src/brazil/ip/udp.c
331a
	udp.advise = udpadvise;
.
320a
udpadvise(Block *bp, char *msg)
{
	Udphdr *h;
	Ipaddr source, dest;
	ushort psource, pdest;
	Conv *s, **p;

	h = (Udphdr*)(bp->rp);

	dest = nhgetl(h->udpdst);
	source = nhgetl(h->udpsrc);
	psource = nhgets(h->udpsport);
	pdest = nhgets(h->udpdport);

	/* Look for a connection */
	for(p = udp.conv; *p; p++) {
		s = *p;
		if(s->rport == pdest && s->lport == psource)
		if(s->raddr == dest && s->laddr == source){
			qhangup(s->rq, msg);
			qhangup(s->wq, msg);
			break;
		}
	}
	freeblist(bp);
}

void
.
## diffname ip/udp.c 1997/0901
## diff -e /n/emeliedump/1997/0829/sys/src/brazil/ip/udp.c /n/emeliedump/1997/0901/sys/src/brazil/ip/udp.c
275a
		else if(media != 0)
			hnputl(bp->rp+4, media->myip[0]);
		else
			hnputl(bp->rp+4, laddr);
.
274c
		else if(m != 0)
.
## diffname ip/udp.c 1997/0903
## diff -e /n/emeliedump/1997/0901/sys/src/brazil/ip/udp.c /n/emeliedump/1997/0903/sys/src/brazil/ip/udp.c
246a
		icmpnoconv(bp);
.
## diffname ip/udp.c 1997/0904
## diff -e /n/emeliedump/1997/0903/sys/src/brazil/ip/udp.c /n/emeliedump/1997/0904/sys/src/brazil/ip/udp.c
247c
		/* don't complain about broadcasts... */
		if(Mediaforme(dst) > 0){
			uh->Unused = ottl;
			hnputs(uh->udpplen, olen);
			icmpnoconv(bp);
		}
.
215a
	olen = nhgets(uh->udpplen);
.
213c
	/* Put back pseudo header for checksum (remember old values for icmpnoconv()) */
	ottl = uh->Unused;
.
201c
	int len, olen, ottl;
.
## diffname ip/udp.c 1998/0306
## diff -e /n/emeliedump/1997/0904/sys/src/brazil/ip/udp.c /n/emeliedump/1998/0306/sys/src/brazil/ip/udp.c
372a
	udp.stats = udpstats;
.
359a
int
udpstats(char *buf, int len)
{
	return snprint(buf, len,
		"udp: csum %d hlen %d len %d order %d rexmit %d\n",
		udp.csumerr, udp.hlenerr, udp.lenerr, udp.order, udp.rexmit);
}

.
350,351c
		if(s->rport == pdest)
		if(s->lport == psource)
		if(ipcmp(s->raddr, dest) == 0)
		if(ipcmp(s->laddr, source) == 0){
.
342,343c
	v4tov6(dest, h->udpdst);
	v4tov6(source, h->udpsrc);
.
336c
	uchar source[IPaddrlen], dest[IPaddrlen];
.
308,309c
		netlog(Logudp, "udp: qfull %I.%d -> %I.%d\n", raddr, rport,
			laddr, lport);
.
301c
				ipmove(c->laddr, ia);
.
298,299c
			if(ipforme(laddr) == Runi)
				ipmove(c->laddr, laddr);
.
294c
		 	ipmove(c->raddr, raddr);
.
287,289c
			ipmove(bp->rp+IPaddrlen, ia);
		hnputs(bp->rp+2*IPaddrlen, rport);
		hnputs(bp->rp+2*IPaddrlen+2, lport);
.
279,285c
		ipmove(bp->rp, raddr);
		if(ipforme(laddr) == Runi)
			ipmove(bp->rp+IPaddrlen, laddr);
.
271,272c
	netlog(Logudpmsg, "udp: %I.%d -> %I.%d l %d\n", raddr, rport,
		laddr, lport, len);
.
265,266c
		netlog(Logudp, "udp: len err %I.%d -> %I.%d\n", raddr, rport,
			laddr, lport);
.
250c
		if(ipforme(raddr) == 0){
.
247,248c
		netlog(Logudp, "udp: no conv %I.%d -> %I.%d\n", raddr, rport,
			laddr, lport);
.
230c
			netlog(Logudp, "udp: checksum error %I\n", raddr);
.
224,225d
220,221c
	v4tov6(raddr, uh->udpsrc);
	v4tov6(laddr, uh->udpdst);
.
210d
207,208d
205c
	uchar raddr[IPaddrlen], laddr[IPaddrlen];
.
199c
udpiput(uchar *ia, Block *bp)
.
186c
		if(ipcmp(c->laddr, IPnoaddr) == 0)
			findlocalip(c->laddr, c->raddr);	/* pick interface closest to dest */
		v6tov4(uh->udpsrc, c->laddr);
.
184c
		v6tov4(uh->udpdst, c->raddr);
.
179,182c
		v6tov4(uh->udpsrc, laddr);
.
177c
		v6tov4(uh->udpdst, raddr);
.
158d
156d
144,150c
		ipmove(raddr, bp->rp);
		bp->rp += IPaddrlen;
		ipmove(laddr, bp->rp);
		bp->rp += IPaddrlen;
		if(ipforme(laddr) != Runi)
			findlocalip(laddr, raddr);	/* pick interface closest to dest */
.
141,142c
		if(bp == nil)
.
131,132c
	netlog(Logudp, "udp: kick\n");
.
126c
	uchar laddr[IPaddrlen], raddr[IPaddrlen];
.
122c
udpkick(Conv *c, int)
.
110,111c
	ipmove(c->laddr, IPnoaddr);
	ipmove(c->raddr, IPnoaddr);
.
78,79c
	return snprint(state, n, "%s", "Datagram");
.
74,75c
static int
udpstate(Conv *c, char *state, int n)
.
54c
	uchar	headers;
.
41,44c
	uchar	udpsport[2];	/* Source port */
	uchar	udpdport[2];	/* Destination port */
	uchar	udplen[2];	/* data length */
	uchar	udpcksum[2];	/* Checksum */
.
29,38c
	uchar	vihl;		/* Version and header length */
	uchar	tos;		/* Type of service */
	uchar	length[2];	/* packet length */
	uchar	id[2];		/* Identification */
	uchar	frag[2];	/* Fragment information */
	uchar	Unused;	
	uchar	udpproto;	/* Protocol */
	uchar	udpplen[2];	/* Header plus data length */
	uchar	udpsrc[4];	/* Ip source */
	uchar	udpdst[4];	/* Ip destination */
.
18c
	UDP_USEAD	= 36,
.
## diffname ip/udp.c 1998/0311
## diff -e /n/emeliedump/1998/0306/sys/src/brazil/ip/udp.c /n/emeliedump/1998/0311/sys/src/brazil/ip/udp.c
18c
	UDP_USEAD	= 12,
.
## diffname ip/udp.c 1998/0313
## diff -e /n/emeliedump/1998/0311/sys/src/brazil/ip/udp.c /n/emeliedump/1998/0313/sys/src/brazil/ip/udp.c
372c
	udp = smalloc(sizeof(Proto));
	udp->priv = smalloc(sizeof(Udppriv));
	udp->name = "udp";
	udp->kick = udpkick;
	udp->connect = udpconnect;
	udp->announce = udpannounce;
	udp->ctl = udpctl;
	udp->state = udpstate;
	udp->create = udpcreate;
	udp->close = udpclose;
	udp->rcv = udpiput;
	udp->advise = udpadvise;
	udp->stats = udpstats;
	udp->ipproto = IP_UDPPROTO;
	udp->nc = 16;
	udp->ptclsize = sizeof(Udpcb);

	Fsproto(fs, udp);
.
357,370c
	Proto *udp;
.
349,351c
	Udppriv *upriv;

	upriv = udp->priv;
	return snprint(buf, len, "%d %d %d %d",
		upriv->ustats.udpInDatagrams,
		upriv->ustats.udpNoPorts,
		upriv->ustats.udpInErrors,
		upriv->ustats.udpOutDatagrams);
.
347c
udpstats(Proto *udp, char *buf, int len)
.
332c
	for(p = udp->conv; *p; p++) {
.
317c
udpadvise(Proto *udp, Block *bp, char *msg)
.
309,312d
305,307c
	if(n == 1){
		if(strcmp(f[0], "headers4") == 0){
			ucb->headers = 4;
			return nil;
		} else if(strcmp(f[0], "headers") == 0){
			ucb->headers = 6;
			return nil;
		}
.
292c
		netlog(f, Logudp, "udp: qfull %I.%d -> %I.%d\n", raddr, rport,
.
286a
		break;
.
285c
				v4tov6(c->laddr, ia);
.
282c
			if(ipforme(f, laddr) == Runi)
.
274c
		break;
	case 4:
		/* pass the src address */
		bp = padblock(bp, UDP_USEAD4);
		memmove(bp->rp, raddr, IPv4addrlen);
		if(ipforme(f, laddr) == Runi)
			memmove(bp->rp+IPv4addrlen, laddr, IPv4addrlen);
		else
			memmove(bp->rp+IPv4addrlen, ia, IPv4addrlen);
		hnputs(bp->rp + 2*IPv4addrlen, rport);
		hnputs(bp->rp + 2*IPv4addrlen + 2, lport);
		break;
	default:
.
268c
		if(ipforme(f, laddr) == Runi)
.
266c
		bp = padblock(bp, UDP_USEAD6);
.
264c
	switch(ucb->headers){
	case 6:
.
259c
	netlog(f, Logudpmsg, "udp: %I.%d -> %I.%d l %d\n", raddr, rport,
.
255c
		upriv->lenerr++;
.
253c
		netlog(f, Logudp, "udp: len err %I.%d -> %I.%d\n", raddr, rport,
.
241c
			icmpnoconv(f, bp);
.
238c
		if(ipforme(f, raddr) == 0){
.
235c
		upriv->ustats.udpNoPorts++;
		netlog(f, Logudp, "udp: no conv %I.%d -> %I.%d\n", raddr, rport,
.
226c
	for(p = udp->conv; *p; p++) {
.
217,218c
			upriv->ustats.udpInErrors++;
			netlog(f, Logudp, "udp: checksum error %I\n", raddr);
.
215c
	if(nhgets(uh->udpcksum)) {
.
200a
	upriv = udp->priv;
	f = udp->f;

	upriv->ustats.udpInDatagrams++;

.
199a
	Udppriv *upriv;
	Fs *f;
.
192c
udpiput(Proto *udp, uchar *ia, Block *bp)
.
188c
	upriv->ustats.udpOutDatagrams++;
	ipoput(f, bp, 0, c->ttl);
.
179a
		break;
.
178c
			findlocalip(f, c->laddr, c->raddr);	/* pick interface closest to dest */
.
174c
		break;
	case 4:
		memmove(uh->udpdst, raddr, IPv4addrlen);
		hnputs(uh->udpdport, rport);
		memmove(uh->udpsrc, laddr, IPv4addrlen);
		break;
	default:
.
170c
	switch(ucb->headers){
	case 6:
.
152a
		break;
.
151c
		break;
	case 4:
		/* get user specified addresses */
		bp = pullupblock(bp, UDP_USEAD4);
		if(bp == nil)
			return;
		v4tov6(raddr, bp->rp);
		bp->rp += IPv4addrlen;
		v4tov6(laddr, bp->rp);
		bp->rp += IPv4addrlen;
		if(ipforme(f, laddr) != Runi)
			findlocalip(f, laddr, raddr);	/* pick interface closest to dest */
		rport = nhgets(bp->rp);
		bp->rp += 2;
		/* ignore local port number */
		bp->rp += 2;
		break;
	default:
.
145,146c
		if(ipforme(f, laddr) != Runi)
			findlocalip(f, laddr, raddr);	/* pick interface closest to dest */
.
138c
		bp = pullupblock(bp, UDP_USEAD6);
.
136c
	switch(ucb->headers) {
	case 6:
.
130c
	upriv = c->p->priv;
	f = c->p->f;

	netlog(c->p->f, Logudp, "udp: kick\n");
.
128a
	Udppriv *upriv;
	Fs *f;
.
89c
	Fsconnected(c, nil);
.
73a

.
69c
	Fsconnected(c, e);
.
57,62d
46a
/* MIB II counters */
typedef struct Udpstats Udpstats;
struct Udpstats
{
	ulong	udpInDatagrams;
	ulong	udpNoPorts;
	ulong	udpInErrors;
	ulong	udpOutDatagrams;
};

typedef struct Udppriv Udppriv;
struct Udppriv
{
	/* MIB counters */
	Udpstats	ustats;

	/* non-MIB stats */
	ulong		csumerr;		/* checksum errors */
	ulong		lenerr;			/* short packet */
};

.
18c
	UDP_USEAD6	= 36,
	UDP_USEAD4	= 12,
.
## diffname ip/udp.c 1998/0414
## diff -e /n/emeliedump/1998/0313/sys/src/brazil/ip/udp.c /n/emeliedump/1998/0414/sys/src/brazil/ip/udp.c
425c
	return snprint(buf, len, "%d %d %d %d\n",
.
339c
			v6tov4(bp->rp+IPv4addrlen, laddr);
.
337c
		v6tov4(bp->rp, raddr);
.
293c
		netlog(f, Logudp, "udp: no conv %I!%d -> %I!%d\n", raddr, rport,
.
226c
			findlocalip(f, c->laddr, c->raddr);
.
217,221d
211a
	case 4:
.
187,189c
		bp->rp += 2+2;
.
185c
			findlocalip(f, laddr, raddr);
.
176d
171,173c
		bp->rp += 2+2;			/* Igonore local port */
.
169c
			findlocalip(f, laddr, raddr);
.
167a
		/* pick interface closest to dest */
.
## diffname ip/udp.c 1998/0509
## diff -e /n/emeliedump/1998/0414/sys/src/brazil/ip/udp.c /n/emeliedump/1998/0509/sys/src/brazil/ip/udp.c
287,292c
		uh->Unused = ottl;
		hnputs(uh->udpplen, olen);
		icmpnoconv(f, bp);
.
## diffname ip/udp.c 1998/0604
## diff -e /n/emeliedump/1998/0509/sys/src/brazil/ip/udp.c /n/emeliedump/1998/0604/sys/src/brazil/ip/udp.c
330c
			v6tov4(bp->rp+IPv4addrlen, ia);
.
## diffname ip/udp.c 1998/0630
## diff -e /n/emeliedump/1998/0604/sys/src/brazil/ip/udp.c /n/emeliedump/1998/0630/sys/src/brazil/ip/udp.c
267a
			DPRINT("udp: checksum error %I\n", raddr);
.
## diffname ip/udp.c 1998/0728
## diff -e /n/emeliedump/1998/0630/sys/src/brazil/ip/udp.c /n/emeliedump/1998/0728/sys/src/brazil/ip/udp.c
280,281c
		if(c->lport == lport){
			ucb = (Udpcb*)c->ptcl;

			/* with headers turned on, descriminate only on local port */
			if(ucb->headers)
				break;

			/* otherwise discriminate on lport, rport, and raddr */
			if(c->rport == 0 || c->rport == rport)
			if(ipisbm(c->raddr) || ipcmp(c->raddr, IPnoaddr) == 0
			   || ipcmp(c->raddr, raddr) == 0)
				break;
		}
.
## diffname ip/udp.c 1998/0731
## diff -e /n/emeliedump/1998/0728/sys/src/brazil/ip/udp.c /n/emeliedump/1998/0731/sys/src/brazil/ip/udp.c
348c
		if(ipcmp(c->raddr, IPnoaddr) == 0){
.
## diffname ip/udp.c 1998/0801
## diff -e /n/emeliedump/1998/0731/sys/src/brazil/ip/udp.c /n/emeliedump/1998/0801/sys/src/brazil/ip/udp.c
94,95c
	return snprint(state, n, "%s", c->inuse?"Open":"Closed");
.
## diffname ip/udp.c 1998/0813
## diff -e /n/emeliedump/1998/0801/sys/src/brazil/ip/udp.c /n/emeliedump/1998/0813/sys/src/brazil/ip/udp.c
425c
	return snprint(buf, len, "%d %d %d %d",
.
## diffname ip/udp.c 1998/0825
## diff -e /n/emeliedump/1998/0813/sys/src/brazil/ip/udp.c /n/emeliedump/1998/0825/sys/src/brazil/ip/udp.c
425c
	return snprint(buf, len, "%lud %lud %lud %lud",
.
## diffname ip/udp.c 1999/0302
## diff -e /n/emeliedump/1998/0825/sys/src/brazil/ip/udp.c /n/emeliedump/1999/0302/sys/src/brazil/ip/udp.c
415a
	qunlock(udp);
.
413c
			qunlock(s);
			freeblist(bp);
			return;
.
410a
			qlock(s);
			qunlock(udp);
.
404a
	qlock(udp);
.
367,368c
		return;
	}

	qpass(c->rq, bp);
	qunlock(c);

.
363a
		qunlock(c);
.
320,321d
310a
		qunlock(c);
.
304a
	ucb = (Udpcb*)c->ptcl;
	qlock(c);
	qunlock(udp);

.
295a
		qunlock(udp);
.
272a
	qlock(udp);

.
133c
	qunlock(c);
.
## diffname ip/udp.c 1999/0522
## diff -e /n/emeliedump/1999/0302/sys/src/brazil/ip/udp.c /n/emeliedump/1999/0522/sys/src/brazil/ip/udp.c
218c
		if(v6tov4(uh->udpsrc, c->laddr) < 0)
			memset(uh->udpsrc, 0, sizeof(uh->udpsrc));
.
## diffname ip/udp.c 1999/0523
## diff -e /n/emeliedump/1999/0522/sys/src/brazil/ip/udp.c /n/emeliedump/1999/0523/sys/src/brazil/ip/udp.c
218,219c
		v6tov4(uh->udpsrc, c->laddr);
.
## diffname ip/udp.c 1999/0817
## diff -e /n/emeliedump/1999/0523/sys/src/brazil/ip/udp.c /n/emeliedump/1999/0817/sys/src/brazil/ip/udp.c
229c
	ipoput(f, bp, 0, c->ttl, c->tos);
.
## diffname ip/udp.c 1999/0906
## diff -e /n/emeliedump/1999/0817/sys/src/brazil/ip/udp.c /n/emeliedump/1999/0906/sys/src/brazil/ip/udp.c
468c
	udp->nc = Nchans;
.
## diffname ip/udp.c 1999/0909
## diff -e /n/emeliedump/1999/0906/sys/src/brazil/ip/udp.c /n/emeliedump/1999/0909/sys/src/brazil/ip/udp.c
295,305c
	if(*p == nil){
		if(gc != nil)
			c = gc;
		else {
			upriv->ustats.udpNoPorts++;
			qunlock(udp);
			netlog(f, Logudp, "udp: no conv %I!%d -> %I!%d\n", raddr, rport,
				laddr, lport);
			uh->Unused = ottl;
			hnputs(uh->udpplen, olen);
			icmpnoconv(f, bp);
			freeblist(bp);
			return;
		}
.
285,286c
			if(ucb->headers && gc == nil){
				gc = c;
				continue;
			}
.
275,276c
	/*
	 *  Look for a conversation structure for this port.  One
	 *  with headers off wins over one with headers on, i.e.,
	 *  specific wins over generic.
	 */
	gc = c = nil;
.
237c
	Conv *c, **p, *gc;
.
## diffname ip/udp.c 1999/0910
## diff -e /n/emeliedump/1999/0909/sys/src/brazil/ip/udp.c /n/emeliedump/1999/0910/sys/src/brazil/ip/udp.c
402a
			/* close any calls that got in twixt announce and headers */
			udpcloseincalls(c);
.
399a
			/* close any calls that got in twixt announce and headers */
			udpcloseincalls(c);
.
390a
/* close any incoming calls waiting on this conversation */
void
udpcloseincalls(Conv *c)
{
	Conv *nc;

	qlock(c);

	for(nc = c->incall; nc; nc = c->incall){
		c->incall = nc->next;
		closeconv(nc);
	}

	qunlock(c);
}

.
374a

.
360,373d
302,304c
		if(spec != nil)
			gen = spec;
		if(gen != nil){
			if(ipforme(f, laddr) != Runi)
				v4tov6(laddr, ia);
			c = Fsnewcall(gen, raddr, rport, laddr, lport);
			if(c == nil){
				freeblist(bp);
				return;
			}
			c->state = Connected;
		} else {
.
300a
found:
.
294,298c
		} else if(c->lport == 0) {
			/* generic listen for all udp ports */
			if(c->state == Announced)
				gen = c;
.
288,291c
			switch(c->state){
			case Announced:
				/* headers + Announced is special behaviour */
				if(ucb->headers)
					goto found;
				spec = c;
				break;
				
			case Connected:
				/* exact match */
				if(c->rport == rport)
				if(ipcmp(c->raddr, raddr) == 0 || ipisbm(c->raddr))
					goto found;
.
280c
	spec = gen = c = nil;
.
276,278c
	 *  Look for a conversation structure for this packet
.
237c
	Conv *c, **p, *spec, *gen;
.
121a
	c->state = 0;
.
## diffname ip/udp.c 2000/0424
## diff -e /n/emeliedump/1999/0910/sys/src/brazil/ip/udp.c /n/emeliedump/2000/0424/sys/src/9/ip/udp.c
499a
	udp->gc = nil;
.
## diffname ip/udp.c 2000/0527
## diff -e /n/emeliedump/2000/0424/sys/src/9/ip/udp.c /n/emeliedump/2000/0527/sys/src/9/ip/udp.c
113,114c
	c->rq = qopen(128*1024, 1, 0, 0);
	c->wq = qopen(128*1024, 0, 0, 0);
.
## diffname ip/udp.c 2000/0706
## diff -e /n/emeliedump/2000/0527/sys/src/9/ip/udp.c /n/emeliedump/2000/0706/sys/src/9/ip/udp.c
474,479c
	priv = udp->priv;
	p = buf;
	e = p+len;
	for(i = 0; i < Nstats; i++)
		p = seprint(p, e, "%s: %lud\n", statnames[i], priv->stats[i]);
	return p - buf;
.
472c
	Udppriv *priv;
	char *p, *e;
	int i;
.
347c
		upriv->stats[LenErrs]++;
		upriv->stats[InErrors]++;
.
322c
			upriv->stats[NoPorts]++;
.
266c
			upriv->stats[InErrors]++;
			upriv->stats[CsumErrs]++;
.
248c
	upriv->stats[InDatagrams]++;
.
229c
	upriv->stats[OutDatagrams]++;
.
61,66c
	ulong	stats[Nstats];
.
57a
static char *statnames[] = {
[InDatagrams]	"InDatagrams",
[NoPorts]	"NoPorts",
[InErrors]	"InErrors",
[OutDatagrams]	"OutDatagrams",
[CsumErrs]	"CsumErrs",
[LenErrs]	"LenErrs",
};


.
52,55c
	/* MIB II counters */
	InDatagrams,
	NoPorts,
	InErrors,
	OutDatagrams,

	/* non-MIB counters */
	CsumErrs,
	LenErrs,

	Nstats,
.
48,50c
enum
.
## diffname ip/udp.c 2000/1220
## diff -e /n/emeliedump/2000/0706/sys/src/9/ip/udp.c /n/emeliedump/2000/1220/sys/src/9/ip/udp.c
422a
/* called with c locked */
.
419,420d
413,414d
407c
/*
 *  close any incoming calls waiting on this conversation
 *  	called with c locked
 */
.
143,144d
## diffname ip/udp.c 2001/0207
## diff -e /n/emeliedump/2000/1220/sys/src/9/ip/udp.c /n/emeliedump/2001/0207/sys/src/9/ip/udp.c
123c
	c->rq = qopen(256*1024, 1, 0, 0);
.
## diffname ip/udp.c 2001/0209
## diff -e /n/emeliedump/2001/0207/sys/src/9/ip/udp.c /n/emeliedump/2001/0209/sys/src/9/ip/udp.c
512d
486,491c
	upriv = udp->priv;
	return snprint(buf, len, "%lud %lud %lud %lud",
		upriv->ustats.udpInDatagrams,
		upriv->ustats.udpNoPorts,
		upriv->ustats.udpInErrors,
		upriv->ustats.udpOutDatagrams);
.
482,484c
	Udppriv *upriv;
.
435,436d
430,431d
405,420d
356,357c
		upriv->lenerr++;
.
342a
	/* no converstation found */
	upriv->ustats.udpNoPorts++;
	qunlock(udp);
	netlog(f, Logudp, "udp: no conv %I!%d -> %I!%d\n", raddr, rport,
		laddr, lport);
	uh->Unused = ottl;
	hnputs(uh->udpplen, olen);
	icmpnoconv(f, bp);
	freeblist(bp);
	return;

found:
.
340a
		c->state = Connected;
		goto found;
.
317,337c
	if(gen != nil){
		c = gen;
		goto found;
	}

	/* look for a connected port */
	for(p = udp->conv; *p; p++){
		c = *p;
		if(c->inuse == 0 || c->state != Connected)
			continue;
		if(c->lport == lport
		&& c->rport == rport
		&& (ipcmp(c->laddr, laddr) == 0)
		&& ipcmp(c->raddr, raddr) == 0 || ipisbm(c->raddr))
			goto found;
	}

	/* finally, look for a listener */
	for(p = udp->conv; *p; p++){
		c = *p;
		ucb = (Udpcb*)c->ptcl;
		if(c->inuse == 0 || c->state != Announced || ucb->headers != 0)
			continue;
		
		if(c->lport != lport)
			continue;

		if(ipcmp(c->laddr, laddr) == 0)
			break;

		if(ipcmp(c->laddr, IPnoaddr) == 0)
			gen = c;
	}
	c = *p;
	if(c == nil)
		c = gen;
	if(c != nil){
		if(ipforme(f, laddr) != Runi)
			v4tov6(laddr, ia);
		c = Fsnewcall(gen, raddr, rport, laddr, lport);
		if(c == nil){
.
311,315c
		if(ipcmp(c->laddr, IPnoaddr) == 0 || ipcmp(c->laddr, v4prefix) == 0)
			gen = c;
.
296,309c
		if(ipcmp(c->laddr, laddr) == 0)
			goto found;
.
293,294c
		
		if(c->lport != lport)
			continue;
.
291c
		ucb = (Udpcb*)c->ptcl;
		if(c->inuse == 0 || c->state != Announced || ucb->headers == 0)
.
285,289c
	gen = nil;

	/* look for an announced port with headers (most likely) */
	for(p = udp->conv; *p; p++){
.
274,275c
			upriv->ustats.udpInErrors++;
.
256c
	upriv->ustats.udpInDatagrams++;
.
246c
	Conv *c, **p, *gen;
.
240a
Conv*
udpincoming(Conv *c, uchar *raddr, ushort rport, uchar *laddr, ushort lport)
{
	Conv *new;

	new = Fsnewcall(c, raddr, rport, laddr, lport);
	if(new == nil)
		return nil;
}

.
237c
	upriv->ustats.udpOutDatagrams++;
.
142a

	qunlock(c);
.
123,124c
	c->rq = qopen(64*1024, 1, 0, 0);
	c->wq = qopen(64*1024, 0, 0, 0);
.
76c
	/* MIB counters */
	Udpstats	ustats;

	/* non-MIB stats */
	ulong		csumerr;		/* checksum errors */
	ulong		lenerr;			/* short packet */
.
63,72d
50,60c
	ulong	udpInDatagrams;
	ulong	udpNoPorts;
	ulong	udpInErrors;
	ulong	udpOutDatagrams;
.
48c
/* MIB II counters */
typedef struct Udpstats Udpstats;
struct Udpstats
.
## diffname ip/udp.c 2001/0301
## diff -e /n/emeliedump/2001/0209/sys/src/9/ip/udp.c /n/emeliedump/2001/0301/sys/src/9/ip/udp.c
352,364d
348,349d
309,346c
	if(c->state == Announced){
		if(ucb->headers == 0){
			/* create a new conversation */
			if(ipforme(f, laddr) != Runi)
				v4tov6(laddr, ia);
			c = Fsnewcall(c, raddr, rport, laddr, lport);
			if(c == nil){
				qunlock(udp);
				freeblist(bp);
				return;
			}
			iphtadd(&upriv->ht, c);
			ucb = (Udpcb*)c->ptcl;
.
304,307c
	ucb = (Udpcb*)c->ptcl;
.
286,302c
	c = iphtlook(&upriv->ht, raddr, rport, laddr, lport);
	if(c == nil){
		/* no converstation found */
		upriv->ustats.udpNoPorts++;
		qunlock(udp);
		netlog(f, Logudp, "udp: no conv %I!%d -> %I!%d\n", raddr, rport,
			laddr, lport);
		uh->Unused = ottl;
		hnputs(uh->udpplen, olen);
		icmpnoconv(f, bp);
		freeblist(bp);
		return;
.
248c
	Conv *c;
.
121a
	upriv = c->p->priv;
	iphtrem(&upriv->ht, c);

.
120a
	Udppriv *upriv;
.
105a
	iphtadd(&upriv->ht, c);
.
101a
	upriv = c->p->priv;
.
100a
	Udppriv *upriv;
.
85a
	iphtadd(&upriv->ht, c);
.
83a
	upriv = c->p->priv;
.
82a
	Udppriv *upriv;
.
60a
	Ipht		ht;

.
## diffname ip/udp.c 2001/0306
## diff -e /n/emeliedump/2001/0301/sys/src/9/ip/udp.c /n/emeliedump/2001/0306/sys/src/9/ip/udp.c
150c
udpkick(Conv *c)
.
## diffname ip/udp.c 2001/0412
## diff -e /n/emeliedump/2001/0306/sys/src/9/ip/udp.c /n/emeliedump/2001/0412/sys/src/9/ip/udp.c
449c
	return snprint(buf, len, "InDatagrams: %lud\nNoPorts: %lud\nInErrors: %lud\nOutDatagrams: %lud\n",
.
## diffname ip/udp.c 2001/0530
## diff -e /n/emeliedump/2001/0412/sys/src/9/ip/udp.c /n/emeliedump/2001/0530/sys/src/9/ip/udp.c
145,146d
## diffname ip/udp.c 2001/0623
## diff -e /n/emeliedump/2001/0530/sys/src/9/ip/udp.c /n/emeliedump/2001/0623/sys/src/9/ip/udp.c
365c
			v6tov4(bp->rp+IPv4addrlen, ifc->lifc->local);
.
354c
			ipmove(bp->rp+IPaddrlen, ifc->lifc->local);
.
315c
				v4tov6(laddr, ifc->lifc->local);
.
254c
udpiput(Proto *udp, Ipifc *ifc, Block *bp)
.
## diffname ip/udp.c 2002/0507
## diff -e /n/emeliedump/2001/0623/sys/src/9/ip/udp.c /n/emeliedump/2002/0507/sys/src/9/ip/udp.c
429a
print("udpadvise: found, hanging up\n");
.
419a
print("udpadvise: looking for s %I sp %d d %I dp %d\n", source, (int)psource, dest, (int)pdest);

.
415,418c
	if(version == 4) {
		v4tov6(dest, h4->udpdst);
		v4tov6(source, h4->udpsrc);
		psource = nhgets(h4->udpsport);
		pdest = nhgets(h4->udpdport);
	} else {
		h6 = (Udp6hdr*)(bp->rp);
		ipmove(dest, h6->udpdst);
		ipmove(source, h6->udpsrc);
		psource = nhgets(h6->udpsport);
		pdest = nhgets(h6->udpdport);
	}
.
413c
	h4 = (Udp4hdr*)(bp->rp);
	version = ((h4->vihl&0xF0)==IP_VER6) ? 6 : 4;
.
411a
	int version;
.
408c
	Udp4hdr *h4;
	Udp6hdr *h6;
.
377c
		       laddr, lport);
.
344c
	       laddr, lport, len);
.
338c
		       laddr, lport);
.
333,334c
	len -= UDP_UDPHDR_SZ;
	if(version == 4)
		bp = trimblock(bp, UDP4_IPHDR_SZ+UDP_UDPHDR_SZ, len);
	else
		bp = trimblock(bp, UDP6_IPHDR_SZ+UDP_UDPHDR_SZ, len);
.
314,315c
			if(ipforme(f, laddr) != Runi) {
				if(version == 4)
					v4tov6(laddr, ifc->lifc->local);
				else
					ipmove(laddr, ifc->lifc->local);
			}
.
302,305c
		       laddr, lport);

		if(version == 4) 
			icmpnoconv(f, bp);
		else {
print("udpiput: no conv %I!%d -> %I!%d\n", raddr, rport, laddr, lport);
			icmphostunr(f, ifc, bp, icmp6_port_unreach, 0);
		}

.
291a
		hnputl(uh6->viclfl, oviclfl);
		hnputs(uh6->len, olen);
		uh6->nextheader = IP_UDPPROTO;
		uh6->hoplimit = ottl;
.
284,285c
		if(nhgets(uh4->udpcksum)) {
			if(ptclcsum(bp, UDP4_PHDR_OFF, len+UDP4_PHDR_SZ)) {
				upriv->ustats.udpInErrors++;
				netlog(f, Logudp, "udp: checksum error %I\n", raddr);
				DPRINT("udp: checksum error %I\n", raddr);
				freeblist(bp);
				return;
			}
		}
		uh4->Unused = ottl;
		hnputs(uh4->udpplen, olen);
	}
	else {
		int ottl, oviclfl, olen;
		uh6 = (Udp6hdr*)(bp->rp);
		len = nhgets(uh6->udplen);
		oviclfl = nhgetl(uh6->viclfl);
		olen = nhgets(uh6->len);
		ottl = uh6->hoplimit;
		ipmove(raddr, uh6->udpsrc);
		ipmove(laddr, uh6->udpdst);
		lport = nhgets(uh6->udpdport);
		rport = nhgets(uh6->udpsport);
		memset(uh6, 0, 8);
		hnputl(uh6->viclfl, len);
		uh6->hoplimit = IP_UDPPROTO;
		if(ptclcsum(bp, UDP6_PHDR_OFF, len+UDP6_PHDR_SZ)) {
.
279,282c
		v4tov6(raddr, uh4->udpsrc);
		v4tov6(laddr, uh4->udpdst);
		lport = nhgets(uh4->udpdport);
		rport = nhgets(uh4->udpsport);
.
272,277c
	/* Put back pseudo header for checksum 
	 * (remember old values for icmpnoconv()) */
	if(version == 4) {
		int ottl, olen;
		ottl = uh4->Unused;
		uh4->Unused = 0;
		len = nhgets(uh4->udplen);
		olen = nhgets(uh4->udpplen);
		hnputs(uh4->udpplen, len);
.
270c
	uh4 = (Udp4hdr*)(bp->rp);
	version = ((uh4->vihl&0xF0)==IP_VER6) ? 6 : 4;
.
267d
263a
	int version;
.
256,257c
	int len;
	Udp4hdr *uh4;
	Udp6hdr *uh6;
.
240d
237,238c
		ipoput6(f, bp, 0, c->ttl, c->tos);
	}
.
232,235c
	else {
		// using the v6 ip header to create pseudo header 
		// first then reset it to the normal ip header
		uh6 = (Udp6hdr *)(bp->rp);
		memset(uh6, 0, 8);
		ptcllen = dlen + UDP_UDPHDR_SZ;
		hnputl(uh6->viclfl, ptcllen);
		uh6->hoplimit = IP_UDPPROTO;
		if(ucb->headers == 6) {
			ipmove(uh6->udpdst, raddr);
			hnputs(uh6->udpdport, rport);
			ipmove(uh6->udpsrc, laddr);
		} else {
			ipmove(uh6->udpdst, c->raddr);
			hnputs(uh6->udpdport, c->rport);
			if(ipcmp(c->laddr, IPnoaddr) == 0)
				findlocalip(f, c->laddr, c->raddr);
			ipmove(uh6->udpsrc, c->laddr);
		}
		hnputs(uh6->udpsport, c->lport);
		hnputs(uh6->udplen, ptcllen);
		uh6->udpcksum[0] = 0;
		uh6->udpcksum[1] = 0;
		hnputs(uh6->udpcksum, 
		       ptclcsum(bp, UDP6_PHDR_OFF, dlen+UDP_UDPHDR_SZ+UDP6_PHDR_SZ));
		memset(uh6, 0, 8);
		uh6->viclfl[0] = IP_VER6;
		hnputs(uh6->len, ptcllen);
		uh6->nextheader = IP_UDPPROTO;
.
209,230c
	/* fill in pseudo header and compute checksum */
	if(version == 4) 
	{
		uh4 = (Udp4hdr *)(bp->rp);
		ptcllen = dlen + UDP_UDPHDR_SZ;
		uh4->Unused = 0;
		uh4->udpproto = IP_UDPPROTO;
		uh4->frag[0] = 0;
		uh4->frag[1] = 0;
		hnputs(uh4->udpplen, ptcllen);
		if(ucb->headers == 4 || ucb->headers == 6) {
			v6tov4(uh4->udpdst, raddr);
			hnputs(uh4->udpdport, rport);
			v6tov4(uh4->udpsrc, laddr);
		} else {
			v6tov4(uh4->udpdst, c->raddr);
			hnputs(uh4->udpdport, c->rport);
			if(ipcmp(c->laddr, IPnoaddr) == 0)
				findlocalip(f, c->laddr, c->raddr);
			v6tov4(uh4->udpsrc, c->laddr);
		}
		hnputs(uh4->udpsport, c->lport);
		hnputs(uh4->udplen, ptcllen);
		uh4->udpcksum[0] = 0;
		uh4->udpcksum[1] = 0;
		hnputs(uh4->udpcksum, 
		       ptclcsum(bp, UDP4_PHDR_OFF, dlen+UDP_UDPHDR_SZ+UDP4_PHDR_SZ));
		uh4->vihl = IP_VER4;
		ipoput4(f, bp, 0, c->ttl, c->tos);
.
205c
	if(version == 4)
		bp = padblock(bp, UDP4_IPHDR_SZ+UDP_UDPHDR_SZ);
	else
		bp = padblock(bp, UDP6_IPHDR_SZ+UDP_UDPHDR_SZ);

.
203a
	dlen = blocklen(bp);
.
202c
	if(ucb->headers == 6) {
		if(memcmp(laddr, v4prefix, IPv4off) == 0 ||
		    ipcmp(laddr, IPnoaddr) == 0)
			version = 4;
		else
			version = 6;
	}
	else if(ucb->headers == 4)
		version = 4;
	else {
		if( (memcmp(c->raddr, v4prefix, IPv4off) == 0 &&
			memcmp(c->laddr, v4prefix, IPv4off) == 0)
			|| ipcmp(c->raddr, IPnoaddr) == 0)
			version = 4;
		else
			version = 6;
	}
.
182c
		bp->rp += 2+2;			/* Ignore local port */
.
157a
	int version;
.
150c
	Udp4hdr *uh4;
	Udp6hdr *uh6;
.
144a

	qunlock(c);
.
70a
void (*etherprofiler)(char *name, int qlen);

.
47a
typedef struct Udp6hdr Udp6hdr;
struct Udp6hdr {
	uchar viclfl[4];
	uchar len[2];
	uchar nextheader;
	uchar hoplimit;
	uchar udpsrc[IPaddrlen];
	uchar udpdst[IPaddrlen];

	/* udp header */
	uchar	udpsport[2];	/* Source port */
	uchar	udpdport[2];	/* Destination port */
	uchar	udplen[2];	/* data length */
	uchar	udpcksum[2];	/* Checksum */
};

.
38,39c
	uchar	udpsrc[IPv4addrlen];	/* Ip source */
	uchar	udpdst[IPv4addrlen];	/* Ip destination */
.
26,27c
typedef struct Udp4hdr Udp4hdr;
struct Udp4hdr
.
14,16c
	UDP_UDPHDR_SZ	= 8,

	UDP4_PHDR_OFF = 8,
	UDP4_PHDR_SZ = 12,
	UDP4_IPHDR_SZ = 20,
	UDP6_IPHDR_SZ = 40,
	UDP6_PHDR_SZ = 40,
	UDP6_PHDR_OFF = 0,

.
9a

.
8a
#include	"ipv6.h"
.
## diffname ip/udp.c 2002/0508
## diff -e /n/emeliedump/2002/0507/sys/src/9/ip/udp.c /n/emeliedump/2002/0508/sys/src/9/ip/udp.c
118c
	iphtadd(&upriv->ht, c);
	return nil;
.
116c
	if(e != nil)
		return e;
.
## diffname ip/udp.c 2002/0517
## diff -e /n/emeliedump/2002/0508/sys/src/9/ip/udp.c /n/emeliedump/2002/0517/sys/src/9/ip/udp.c
573d
561,562d
## diffname ip/udp.c 2002/0601
## diff -e /n/emeliedump/2002/0517/sys/src/9/ip/udp.c /n/emeliedump/2002/0601/sys/src/9/ip/udp.c
558a
		break;
	default:
		panic("udpadvise: version %d", version);
		return;  /* to avoid a warning */
.
553c
		break;
	case V6:
.
548c
	switch(version) {
	case V4:
.
464a
		break;
	default:
		bp = nil;
		panic("udpiput4: version %d", version);
	}
.
463c
		break;
	case V6:
.
461c
	switch(version){
	case V4:
.
443c
			c = Fsnewcall(c, raddr, rport, laddr, lport, version);
.
441a
					break;
				default:
					panic("udpiput3: version %d", version);
				}
.
440c
					break;
				case V6:
.
438c
				switch(version){
				case V4:
.
426a
			break;
		default:
			panic("udpiput2: version %d", version);
.
424,425c
			break;
		case V6:
.
422c
		switch(version){
		case V4:
.
409a
		break;
	default:
		panic("udpiput: version %d", version);
		return;	/* to avoid a warning */
.
384,386c
		break;
	case V6:
.
360,361c
	switch(version) {
	case V4:
.
349a
	int ottl, oviclfl, olen;
.
327,336d
322a
		break;

	default:
		panic("udpkick: version %d", version);
.
321d
291,292c
		break;

	case V6:
		bp = padblock(bp, UDP6_IPHDR_SZ+UDP_UDPHDR_SZ);
		if(bp == nil)
			return;

.
263,264c
	switch(version){
	case V4:
		bp = padblock(bp, UDP4_IPHDR_SZ+UDP_UDPHDR_SZ);
		if(bp == nil)
			return;

.
259,261d
253,257d
## diffname ip/udp.c 2002/0615
## diff -e /n/emeliedump/2002/0601/sys/src/9/ip/udp.c /n/emeliedump/2002/0615/sys/src/9/ip/udp.c
149,150c
	c->rq = qopen(128*1024, 1, 0, 0);
	c->wq = qopen(128*1024, 0, 0, 0);
.
## diffname ip/udp.c 2002/0625
## diff -e /n/emeliedump/2002/0615/sys/src/9/ip/udp.c /n/emeliedump/2002/0625/sys/src/9/ip/udp.c
589a
			if(s->ignoreadvice)
				break;
.
## diffname ip/udp.c 2002/0711
## diff -e /n/emeliedump/2002/0625/sys/src/9/ip/udp.c /n/emeliedump/2002/0711/sys/src/9/ip/udp.c
149c
	c->rq = qopen(128*1024, Qmsg, 0, 0);
.
## diffname ip/udp.c 2002/0712
## diff -e /n/emeliedump/2002/0711/sys/src/9/ip/udp.c /n/emeliedump/2002/0712/sys/src/9/ip/udp.c
626d
179a
	Conv *c = x;
.
178c
udpkick(void *x)
.
150c
	c->wq = qopen(128*1024, Qkick, udpkick, c);
.
95a
void udpkick(void *x);
.
## diffname ip/udp.c 2003/0220
## diff -e /n/emeliedump/2002/0712/sys/src/9/ip/udp.c /n/emeliedump/2003/0220/sys/src/9/ip/udp.c
197d
186d
179c
udpkick(void *x, Block *bp)
.
151c
	c->wq = qbypass(udpkick, c);
.
96c
void udpkick(void *x, Block *bp);
.
## diffname ip/udp.c 2003/0308
## diff -e /n/emeliedump/2003/0220/sys/src/9/ip/udp.c /n/emeliedump/2003/0308/sys/src/9/ip/udp.c
322c
		ipoput6(f, bp, 0, c->ttl, c->tos, rc);
.
310a
			rc = c;
.
304a
			rc = nil;
.
286c
		ipoput4(f, bp, 0, c->ttl, c->tos, rc);
.
277a
			rc = c;
.
271a
			rc = nil;
.
190a
	Conv *rc;
.
## diffname ip/udp.c 2003/0420
## diff -e /n/emeliedump/2003/0308/sys/src/9/ip/udp.c /n/emeliedump/2003/0420/sys/src/9/ip/udp.c
548c
			ucb->headers = 7;
.
544,545c
		if(strcmp(f[0], "oldheaders") == 0){
			ucb->headers = 6;
.
508,518d
500,506c
		p = bp->rp;
		ipmove(p, raddr); p += IPaddrlen;
		ipmove(p, ipforme(f, laddr)==Runi ? laddr : ifc->lifc->local); p += IPaddrlen;
		hnputs(p, rport); p += 2;
		hnputs(p, lport);
.
496a
	case 7:
		/* pass the src address */
		bp = padblock(bp, UDP_USEAD7);
		p = bp->rp;
		ipmove(p, raddr); p += IPaddrlen;
		ipmove(p, laddr); p += IPaddrlen;
		ipmove(p, ifc->lifc->local); p += IPaddrlen;
		hnputs(p, rport); p += 2;
		hnputs(p, lport);
		break;
.
349a
	uchar *p;
.
304c
		if(ucb->headers) {
.
269c
		if(ucb->headers) {
.
241,244c
	} else {
.
235c
	if(ucb->headers) {
.
228c
		bp->rp += 2+2;			/* Ignore local port */
.
221,224c
		ipmove(raddr, bp->rp);
		bp->rp += IPaddrlen;
		ipmove(laddr, bp->rp);
		bp->rp += IPaddrlen;
		/* pick interface closest to dest */
.
217,218c
	case 6:
		/* get user specified addresses */
		bp = pullupblock(bp, UDP_USEAD6);
.
213a
		bp->rp += IPaddrlen;		/* Ignore ifc address */
.
204c
		bp = pullupblock(bp, UDP_USEAD7);
.
202c
	case 7:
.
27d
25a
	UDP_USEAD7	= 52,
.

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to [email protected].