|
|
Plan 9 NeXT
#include "u.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "../port/error.h"
#include "arp.h"
#include "../port/ipdat.h"
#include "devtab.h"
static Streamput icmpoput;
static Streamopen icmpstopen;
static Streamclose icmpstclose;
static void icmprcvmsg(Ipifc*, Block*);
Qinfo icmpinfo = { 0, icmpoput, icmpstopen, icmpstclose, "icmp" };
static struct {
QLock;
Queue *rq;
Ipifc *ifc;
} icmp;
Ipifc *ipifc[];
/*
* device interface
*/
Dirtab icmptab[]={
"icmp", {Sdataqid}, 0, 0666,
};
#define Nicmptab (sizeof(icmptab)/sizeof(Dirtab))
void
icmpreset(void)
{
}
void
icmpinit(void)
{
Ipifc **p;
/* add into protocol list */
for(p = ipifc; *p; p++)
;
icmp.ifc = *p = xalloc(sizeof(Ipifc));
icmp.ifc->name = "icmp";
}
Chan *
icmpattach(char *spec)
{
return devattach('Q', spec);
}
Chan *
icmpclone(Chan *c, Chan *nc)
{
return devclone(c, nc);
}
int
icmpwalk(Chan *c, char *name)
{
return devwalk(c, name, icmptab, (long)Nicmptab, devgen);
}
void
icmpstat(Chan *c, char *db)
{
devstat(c, db, icmptab, (long)Nicmptab, devgen);
}
Chan *
icmpopen(Chan *c, int omode)
{
if(c->qid.path == CHDIR){
if(omode != OREAD)
error(Eperm);
} else
streamopen(c, &icmpinfo);
c->mode = openmode(omode);
c->flag |= COPEN;
c->offset = 0;
return c;
}
void
icmpcreate(Chan *c, char *name, int omode, ulong perm)
{
USED(c, name, omode, perm);
error(Eperm);
}
void
icmpremove(Chan *c)
{
USED(c);
error(Eperm);
}
void
icmpwstat(Chan *c, char *dp)
{
USED(c, dp);
error(Eperm);
}
void
icmpclose(Chan *c)
{
if((c->qid.path&CHDIR) == 0)
streamclose(c);
}
long
icmpread(Chan *c, void *a, long n, ulong offset)
{
USED(offset);
if(c->qid.path&CHDIR)
return devdirread(c, a, n, icmptab, Nicmptab, devgen);
return streamread(c, a, n);
}
long
icmpwrite(Chan *c, char *a, long n, ulong offset)
{
USED(offset);
return streamwrite(c, a, n, 1);
}
static void
icmpstclose(Queue *q)
{
USED(q);
qlock(&icmp);
icmp.rq = 0;
qunlock(&icmp);
}
static void
icmpstopen(Queue *q, Stream *s)
{
USED(s);
initipifc(icmp.ifc, IP_ICMPPROTO, icmprcvmsg);
icmp.rq = q;
}
static void
icmprcvmsg(Ipifc *ifc, Block *bp)
{
USED(ifc);
qlock(&icmp);
if(icmp.rq == 0 || QFULL(icmp.rq->next))
freeb(bp);
else
PUTNEXT(icmp.rq, bp);
qunlock(&icmp);
}
static void
icmpoput(Queue *q, Block *bp)
{
USED(q);
ipmuxoput(0, bp);
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.