コード例 #1
0
ファイル: ipifc.c プロジェクト: qioixiy/harvey
/*
 *  attach a device (or pkt driver) to the interface.
 *  called with c locked
 */
static char*
ipifcbind(Conv *c, char **argv, int argc)
{
	Proc *up = externup();
	Ipifc *ifc;
	Medium *medium;

	if(argc < 2)
		return Ebadarg;

	ifc = (Ipifc*)c->ptcl;

	/* bind the device to the interface */
	medium = ipfindmedium(argv[1]);
	if(medium == nil)
		return "unknown interface type";

	wlock(ifc);
	if(ifc->medium != nil){
		wunlock(ifc);
		return "interface already bound";
	}
	if(waserror()){
		wunlock(ifc);
		nexterror();
	}

	/* do medium specific binding */
	(*medium->bind)(ifc, argc, argv);

	/* set the bound device name */
	if(argc > 2)
		strncpy(ifc->dev, argv[2], sizeof(ifc->dev));
	else
		snprint(ifc->dev, sizeof ifc->dev, "%s%d", medium->name, c->x);
	ifc->dev[sizeof(ifc->dev)-1] = 0;

	/* set up parameters */
	ifc->medium = medium;
	ifc->mintu = ifc->medium->mintu;
	ifc->maxtu = ifc->medium->maxtu;
	if(ifc->medium->unbindonclose == 0)
		ifc->conv->inuse++;
	ifc->rp.mflag = 0;		/* default not managed */
	ifc->rp.oflag = 0;
	ifc->rp.maxraint = 600000;	/* millisecs */
	ifc->rp.minraint = 200000;
	ifc->rp.linkmtu = 0;		/* no mtu sent */
	ifc->rp.reachtime = 0;
	ifc->rp.rxmitra = 0;
	ifc->rp.ttl = MAXTTL;
	ifc->rp.routerlt = 3 * ifc->rp.maxraint;

	/* any ancillary structures (like routes) no int32_ter pertain */
	ifc->ifcid++;

	/* reopen all the queues closed by a previous unbind */
	qreopen(c->rq);
	qreopen(c->eq);
	qreopen(c->sq);

	wunlock(ifc);
	poperror();

	return nil;
}
コード例 #2
0
ファイル: arp.c プロジェクト: GanShun/akaros
int arpwrite(struct Fs *fs, char *s, long len)
{
	int n;
	struct route *r;
	struct arp *arp;
	struct block *bp;
	struct arpent *a, *fl, **l;
	struct medium *m;
	char *f[4], buf[256];
	uint8_t ip[IPaddrlen], mac[MAClen];

	arp = fs->arp;

	if (len <= 0)
		error(EINVAL, ERROR_FIXME);
	if (len > sizeof(buf))
		len = sizeof(buf);
	strlcpy(buf, s, sizeof(buf));
	if (len > 0 && buf[len - 2] == '\n')
		buf[len - 2] = 0;

	n = getfields(buf, f, 4, 1, " ");
	if (strcmp(f[0], "flush") == 0) {
		qlock(&arp->qlock);
		for (a = arp->cache; a < &arp->cache[NCACHE]; a++) {
			memset(a->ip, 0, sizeof(a->ip));
			memset(a->mac, 0, sizeof(a->mac));
			a->hash = NULL;
			a->state = 0;
			a->utime = 0;
			while (a->hold != NULL) {
				bp = a->hold->list;
				freeblist(a->hold);
				a->hold = bp;
			}
		}
		memset(arp->hash, 0, sizeof(arp->hash));
		/* clear all pkts on these lists (rxmt, dropf/l) */
		arp->rxmt = NULL;
		arp->dropf = NULL;
		arp->dropl = NULL;
		qunlock(&arp->qlock);
	} else if (strcmp(f[0], "add") == 0) {
		switch (n) {
			default:
				error(EINVAL, ERROR_FIXME);
			case 3:
				parseip(ip, f[1]);
				if (isv4(ip))
					r = v4lookup(fs, ip + IPv4off, NULL);
				else
					r = v6lookup(fs, ip, NULL);
				if (r == NULL)
					error(EHOSTUNREACH, "Destination unreachable");
				m = r->rt.ifc->m;
				n = parsemac(mac, f[2], m->maclen);
				break;
			case 4:
				m = ipfindmedium(f[1]);
				if (m == NULL)
					error(EINVAL, ERROR_FIXME);
				parseip(ip, f[2]);
				n = parsemac(mac, f[3], m->maclen);
				break;
		}

		if (m->ares == NULL)
			error(EINVAL, ERROR_FIXME);

		m->ares(fs, V6, ip, mac, n, 0);
	} else if (strcmp(f[0], "del") == 0) {
		if (n != 2)
			error(EINVAL, ERROR_FIXME);

		parseip(ip, f[1]);
		qlock(&arp->qlock);

		l = &arp->hash[haship(ip)];
		for (a = *l; a; a = a->hash) {
			if (memcmp(ip, a->ip, sizeof(a->ip)) == 0) {
				*l = a->hash;
				break;
			}
			l = &a->hash;
		}

		if (a) {
			/* take out of re-transmit chain */
			l = &arp->rxmt;
			for (fl = *l; fl; fl = fl->nextrxt) {
				if (fl == a) {
					*l = a->nextrxt;
					break;
				}
				l = &fl->nextrxt;
			}

			a->nextrxt = NULL;
			a->hash = NULL;
			a->hold = NULL;
			a->last = NULL;
			a->ifc = NULL;
			memset(a->ip, 0, sizeof(a->ip));
			memset(a->mac, 0, sizeof(a->mac));
		}
		qunlock(&arp->qlock);
	} else
		error(EINVAL, ERROR_FIXME);

	return len;
}
コード例 #3
0
ファイル: ipifc.c プロジェクト: 7perl/akaros
/*
 *  attach a device (or pkt driver) to the interface.
 *  called with c locked
 */
static char *ipifcbind(struct conv *c, char **argv, int argc)
{
	ERRSTACK(1);
	struct Ipifc *ifc;
	struct medium *m;

	if (argc < 2)
		return Ebadarg;

	ifc = (struct Ipifc *)c->ptcl;

	/* bind the device to the interface */
	m = ipfindmedium(argv[1]);
	if (m == NULL)
		return "unknown interface type";

	wlock(&ifc->rwlock);
	if (ifc->m != NULL) {
		wunlock(&ifc->rwlock);
		return "interface already bound";
	}
	if (waserror()) {
		wunlock(&ifc->rwlock);
		nexterror();
	}

	/* do medium specific binding */
	(*m->bind) (ifc, argc, argv);

	/* set the bound device name */
	if (argc > 2)
		strncpy(ifc->dev, argv[2], sizeof(ifc->dev));
	else
		snprintf(ifc->dev, sizeof ifc->dev, "%s%d", m->name, c->x);
	ifc->dev[sizeof(ifc->dev) - 1] = 0;

	/* set up parameters */
	ifc->m = m;
	ifc->mintu = ifc->m->mintu;
	ifc->maxtu = ifc->m->maxtu;
	if (ifc->m->unbindonclose == 0)
		ifc->conv->inuse++;
	ifc->rp.mflag = 0;	// default not managed
	ifc->rp.oflag = 0;
	ifc->rp.maxraint = 600000;	// millisecs
	ifc->rp.minraint = 200000;
	ifc->rp.linkmtu = 0;	// no mtu sent
	ifc->rp.reachtime = 0;
	ifc->rp.rxmitra = 0;
	ifc->rp.ttl = MAXTTL;
	ifc->rp.routerlt = 3 * (ifc->rp.maxraint);

	/* any ancillary structures (like routes) no longer pertain */
	ifc->ifcid++;

	/* reopen all the queues closed by a previous unbind */
	qreopen(c->rq);
	qreopen(c->eq);
	qreopen(c->sq);

	wunlock(&ifc->rwlock);
	poperror();

	return NULL;
}