예제 #1
0
파일: esp.c 프로젝트: npe9/harvey
static char*
espconnect(Conv *c, char **argv, int argc)
{
	char *p, *pp, *e = nil;
	uint32_t spi;
	Espcb *ecb = (Espcb*)c->ptcl;

	switch(argc) {
	default:
		e = "bad args to connect";
		break;
	case 2:
		p = strchr(argv[1], '!');
		if(p == nil){
			e = "malformed address";
			break;
		}
		*p++ = 0;
		if (parseip(c->raddr, argv[1]) == -1) {
			e = Ebadip;
			break;
		}
		findlocalip(c->p->f, c->laddr, c->raddr);
		ecb->incoming = 0;
		ecb->seq = 0;
		if(strcmp(p, "*") == 0) {
			qlock(c->p);
			for(;;) {
				spi = nrand(1<<16) + 256;
				if(convlookup(c->p, spi) == nil)
					break;
			}
			qunlock(c->p);
			ecb->spi = spi;
			ecb->incoming = 1;
			qhangup(c->wq, nil);
		} else {
			spi = strtoul(p, &pp, 10);
			if(pp == p) {
				e = "malformed address";
				break;
			}
			ecb->spi = spi;
			qhangup(c->rq, nil);
		}
		nullespinit(ecb, "null", nil, 0);
		nullahinit(ecb, "null", nil, 0);
	}
	Fsconnected(c, e);

	return e;
}
예제 #2
0
파일: rudp.c 프로젝트: Shamar/harvey
void
relsendack(Conv *c, Reliable *r, int hangup)
{
	Udphdr *uh;
	Block *bp;
	Rudphdr *rh;
	int ptcllen;
	Fs *f;

	bp = allocb(UDP_IPHDR + UDP_RHDRSIZE);
	if(bp == nil)
		return;
	bp->wp += UDP_IPHDR + UDP_RHDRSIZE;
	f = c->p->f;
	uh = (Udphdr *)(bp->rp);
	uh->vihl = IP_VER4;
	rh = (Rudphdr*)uh;

	ptcllen = (UDP_RHDRSIZE-UDP_PHDRSIZE);
	uh->Unused = 0;
	uh->udpproto = IP_UDPPROTO;
	uh->frag[0] = 0;
	uh->frag[1] = 0;
	hnputs(uh->udpplen, ptcllen);

	v6tov4(uh->udpdst, r->addr);
	hnputs(uh->udpdport, r->port);
	hnputs(uh->udpsport, c->lport);
	if(ipcmp(c->laddr, IPnoaddr) == 0)
		findlocalip(f, c->laddr, c->raddr);
	v6tov4(uh->udpsrc, c->laddr);
	hnputs(uh->udplen, ptcllen);

	if(hangup)
		hnputl(rh->relsgen, Hangupgen);
	else
		hnputl(rh->relsgen, r->sndgen);
	hnputl(rh->relseq, 0);
	hnputl(rh->relagen, r->rcvgen);
	hnputl(rh->relack, r->rcvseq);

	if(r->acksent < r->rcvseq)
		r->acksent = r->rcvseq;

	uh->udpcksum[0] = 0;
	uh->udpcksum[1] = 0;
	hnputs(uh->udpcksum, ptclcsum(bp, UDP_IPHDR, UDP_RHDRSIZE));

	DPRINT("sendack: %lud/%lud, %lud/%lud\n", 0L, r->sndgen, r->rcvseq, r->rcvgen);
	doipoput(c, f, bp, 0, c->ttl, c->tos);
}
예제 #3
0
파일: gre.c 프로젝트: 8l/inferno
static void
grekick(void *x, Block *bp)
{
	Conv *c = x;
	GREhdr *ghp;
	uchar laddr[IPaddrlen], raddr[IPaddrlen];

	if(bp == nil)
		return;

	/* Make space to fit ip header (gre header already there) */
	bp = padblock(bp, GRE_IPONLY);
	if(bp == nil)
		return;

	/* make sure the message has a GRE header */
	bp = pullupblock(bp, GRE_IPONLY+GRE_IPPLUSGRE);
	if(bp == nil)
		return;

	ghp = (GREhdr *)(bp->rp);
	ghp->vihl = IP_VER4;

	if(!((GREpriv*)c->p->priv)->raw){
		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->p->f, c->laddr, raddr); /* pick interface closest to dest */
			memmove(ghp->src, c->laddr + IPv4off, IPv4addrlen);
		}
		hnputs(ghp->eproto, c->rport);
	}

	ghp->proto = IP_GREPROTO;
	ghp->frag[0] = 0;
	ghp->frag[1] = 0;

	ipoput4(c->p->f, bp, 0, c->ttl, c->tos, nil);
}
예제 #4
0
파일: udp.c 프로젝트: dhootha/akaros
void udpkick(void *x, struct block *bp)
{
	struct conv *c = x;
	Udp4hdr *uh4;
	Udp6hdr *uh6;
	uint16_t rport;
	uint8_t laddr[IPaddrlen], raddr[IPaddrlen];
	Udpcb *ucb;
	int dlen, ptcllen;
	Udppriv *upriv;
	struct Fs *f;
	int version;
	struct conv *rc;

	upriv = c->p->priv;
	assert(upriv);
	f = c->p->f;

	netlog(c->p->f, Logudp, "udp: kick\n");
	if (bp == NULL)
		return;

	ucb = (Udpcb *) c->ptcl;
	switch (ucb->headers) {
		case 7:
			/* get user specified addresses */
			bp = pullupblock(bp, UDP_USEAD7);
			if (bp == NULL)
				return;
			ipmove(raddr, bp->rp);
			bp->rp += IPaddrlen;
			ipmove(laddr, bp->rp);
			bp->rp += IPaddrlen;
			/* pick interface closest to dest */
			if (ipforme(f, laddr) != Runi)
				findlocalip(f, laddr, raddr);
			bp->rp += IPaddrlen;	/* Ignore ifc address */
			rport = nhgets(bp->rp);
			bp->rp += 2 + 2;	/* Ignore local port */
			break;
		case 6:
			/* get user specified addresses */
			bp = pullupblock(bp, UDP_USEAD6);
			if (bp == NULL)
				return;
			ipmove(raddr, bp->rp);
			bp->rp += IPaddrlen;
			ipmove(laddr, bp->rp);
			bp->rp += IPaddrlen;
			/* pick interface closest to dest */
			if (ipforme(f, laddr) != Runi)
				findlocalip(f, laddr, raddr);
			rport = nhgets(bp->rp);
			bp->rp += 2 + 2;	/* Ignore local port */
			break;
		default:
			rport = 0;
			break;
	}

	if (ucb->headers) {
		if (memcmp(laddr, v4prefix, IPv4off) == 0 ||
			ipcmp(laddr, IPnoaddr) == 0)
			version = V4;
		else
			version = V6;
	} else {
		if ((memcmp(c->raddr, v4prefix, IPv4off) == 0 &&
			 memcmp(c->laddr, v4prefix, IPv4off) == 0)
			|| ipcmp(c->raddr, IPnoaddr) == 0)
			version = V4;
		else
			version = V6;
	}

	dlen = blocklen(bp);

	/* fill in pseudo header and compute checksum */
	switch (version) {
		case V4:
			bp = padblock(bp, UDP4_IPHDR_SZ + UDP_UDPHDR_SZ);
			if (bp == NULL)
				return;

			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) {
				v6tov4(uh4->udpdst, raddr);
				hnputs(uh4->udpdport, rport);
				v6tov4(uh4->udpsrc, laddr);
				rc = NULL;
			} 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);
				rc = c;
			}
			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, UDP4_PHDR_SZ));
			bp->checksum_start = UDP4_IPHDR_SZ;
			bp->checksum_offset = uh4->udpcksum - uh4->udpsport;
			bp->flag |= Budpck;
			uh4->vihl = IP_VER4;
			ipoput4(f, bp, 0, c->ttl, c->tos, rc);
			break;

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

			// 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) {
				ipmove(uh6->udpdst, raddr);
				hnputs(uh6->udpdport, rport);
				ipmove(uh6->udpsrc, laddr);
				rc = NULL;
			} 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);
				rc = c;
			}
			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;
			ipoput6(f, bp, 0, c->ttl, c->tos, rc);
			break;

		default:
			panic("udpkick: version %d", version);
	}
	upriv->ustats.udpOutDatagrams++;
}
예제 #5
0
파일: devip.c 프로젝트: 99years/plan9
/*
 *  set local address to be that of the ifc closest to remote address
 */
static void
setladdr(Conv* c)
{
	findlocalip(c->p->f, c->laddr, c->raddr);
}
예제 #6
0
파일: rudp.c 프로젝트: Shamar/harvey
void
rudpkick(void *x)
{
	Proc *up = externup();
	Conv *c = x;
	Udphdr *uh;
	uint16_t rport;
	uint8_t laddr[IPaddrlen], raddr[IPaddrlen];
	Block *bp;
	Rudpcb *ucb;
	Rudphdr *rh;
	Reliable *r;
	int dlen, ptcllen;
	Rudppriv *upriv;
	Fs *f;

	upriv = c->p->priv;
	f = c->p->f;

	netlog(c->p->f, Logrudp, "rudp: kick\n");
	bp = qget(c->wq);
	if(bp == nil)
		return;

	ucb = (Rudpcb*)c->ptcl;
	switch(ucb->headers) {
	case 7:
		/* get user specified addresses */
		bp = pullupblock(bp, UDP_USEAD7);
		if(bp == nil)
			return;
		ipmove(raddr, bp->rp);
		bp->rp += IPaddrlen;
		ipmove(laddr, bp->rp);
		bp->rp += IPaddrlen;
		/* pick interface closest to dest */
		if(ipforme(f, laddr) != Runi)
			findlocalip(f, laddr, raddr);
		bp->rp += IPaddrlen;		/* Ignore ifc address */
		rport = nhgets(bp->rp);
		bp->rp += 2+2;			/* Ignore local port */
		break;
	default:
		ipmove(raddr, c->raddr);
		ipmove(laddr, c->laddr);
		rport = c->rport;
		break;
	}

	dlen = blocklen(bp);

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

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

	rh = (Rudphdr*)uh;

	ptcllen = dlen + (UDP_RHDRSIZE-UDP_PHDRSIZE);
	uh->Unused = 0;
	uh->udpproto = IP_UDPPROTO;
	uh->frag[0] = 0;
	uh->frag[1] = 0;
	hnputs(uh->udpplen, ptcllen);
	switch(ucb->headers){
	case 7:
		v6tov4(uh->udpdst, raddr);
		hnputs(uh->udpdport, rport);
		v6tov4(uh->udpsrc, laddr);
		break;
	default:
		v6tov4(uh->udpdst, c->raddr);
		hnputs(uh->udpdport, c->rport);
		if(ipcmp(c->laddr, IPnoaddr) == 0)
			findlocalip(f, c->laddr, c->raddr);
		v6tov4(uh->udpsrc, c->laddr);
		break;
	}
	hnputs(uh->udpsport, c->lport);
	hnputs(uh->udplen, ptcllen);
	uh->udpcksum[0] = 0;
	uh->udpcksum[1] = 0;

	qlock(&ucb->ql);
	r = relstate(ucb, raddr, rport, "kick");
	r->sndseq = NEXTSEQ(r->sndseq);
	hnputl(rh->relseq, r->sndseq);
	hnputl(rh->relsgen, r->sndgen);

	hnputl(rh->relack, r->rcvseq);  /* ACK last rcvd packet */
	hnputl(rh->relagen, r->rcvgen);

	if(r->rcvseq != r->acksent)
		r->acksent = r->rcvseq;

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

	relackq(r, bp);
	qunlock(&ucb->ql);

	upriv->ustats.rudpOutDatagrams++;

	DPRINT("sent: %lud/%lud, %lud/%lud\n",
		r->sndseq, r->sndgen, r->rcvseq, r->rcvgen);

	doipoput(c, f, bp, 0, c->ttl, c->tos);

	if(waserror()) {
		relput(r);
		qunlock(&r->lock);
		nexterror();
	}

	/* flow control of sorts */
	qlock(&r->lock);
	if(UNACKED(r) > Maxunacked){
		r->blocked = 1;
		sleep(&r->vous, flow, r);
		r->blocked = 0;
	}

	qunlock(&r->lock);
	relput(r);
	poperror();
}