@@ 37,14 37,14 @@ enum
Addrlen= 16, // must be long enough of IP addr and ether addr
};
-Dirtab bridgedirtab[]={
+static Dirtab bridgedirtab[]={
"ctl", {Qbctl}, 0, 0666,
"stats", {Qstats}, 0, 0444,
"cache", {Qcache}, 0, 0444,
"log", {Qlog}, 0, 0666,
};
-Dirtab portdirtab[]={
+static Dirtab portdirtab[]={
"ctl", {Qpctl}, 0, 0666,
"local", {Qlocal}, 0, 0444,
"status", {Qstatus}, 0, 0444,
@@ 0,0 1,348 @@
+#include "u.h"
+#include "../port/lib.h"
+#include "mem.h"
+#include "dat.h"
+#include "fns.h"
+#include "../port/netif.h"
+#include "../port/error.h"
+
+#include <libcrypt.h>
+
+typedef struct Sdp Sdp;
+typedef struct Port Port;
+
+enum
+{
+ Qtopdir= 1, /* top level directory */
+
+ Qsdpdir, /* sdp directory */
+ Qclone,
+ Qstats,
+ Qlog,
+
+ Qportdir, /* directory for a protocol */
+ Qctl,
+ Qdata, /* reliable control channel */
+ Qpacket, /* unreliable packet channel */
+ Qerr,
+ Qlisten,
+ Qlocal,
+ Qremote,
+ Qstatus,
+
+ MaxQ,
+
+ Maxport= 256, // power of 2
+ Nfs= 4, // number of file systems
+};
+
+#define TYPE(x) ((x).path & 0xff)
+#define PORT(x) (((x).path >> 8)&(Maxport-1))
+#define QID(x, y) (((x)<<8) | (y))
+
+struct Port {
+ int id;
+ Sdp *sdp;
+ int ref;
+ int closed;
+};
+
+struct Sdp {
+ QLock;
+ Log;
+ int nport;
+ Port *port[Maxport];
+};
+
+static Dirtab sdpdirtab[]={
+ "ctl", {Qctl}, 0, 0666,
+ "stats", {Qstats}, 0, 0444,
+ "log", {Qlog}, 0, 0666,
+};
+
+static Dirtab portdirtab[]={
+ "ctl", {Qctl}, 0, 0666,
+ "data", {Qdata}, 0, 0666,
+ "packet", {Qpacket}, 0, 0666,
+ "listen", {Qlisten}, 0, 0666,
+ "local", {Qlocal}, 0, 0444,
+ "remote", {Qlocal}, 0, 0444,
+ "status", {Qstatus}, 0, 0444,
+};
+
+static int m2p[] = {
+ [OREAD] 4,
+ [OWRITE] 2,
+ [ORDWR] 6
+};
+
+enum {
+ Logcompress= (1<<0),
+ Logauth= (1<<1),
+ Loghmac= (1<<2),
+};
+
+static Logflag logflags[] =
+{
+ { "compress", Logcompress, },
+ { "auth", Logauth, },
+ { "hmac", Loghmac, },
+ { nil, 0, },
+};
+
+static Dirtab *dirtab[MaxQ];
+static Sdp sdptab[Nfs];
+
+static int sdpgen(Chan *c, Dirtab*, int, int s, Dir *dp);
+
+static void
+sdpinit(void)
+{
+ int i;
+ Dirtab *dt;
+
+ // setup dirtab with non directory entries
+ for(i=0; i<nelem(sdpdirtab); i++) {
+ dt = sdpdirtab + i;
+ dirtab[TYPE(dt->qid)] = dt;
+ }
+
+ for(i=0; i<nelem(portdirtab); i++) {
+ dt = portdirtab + i;
+ dirtab[TYPE(dt->qid)] = dt;
+ }
+}
+
+static Chan*
+sdpattach(char* spec)
+{
+ Chan *c;
+ int dev;
+
+ dev = atoi(spec);
+ if(dev<0 || dev >= Nfs)
+ error("bad specification");
+
+ c = devattach('B', spec);
+ c->qid = (Qid){QID(0, Qtopdir)|CHDIR, 0};
+ c->dev = dev;
+
+ return c;
+}
+
+static int
+sdpwalk(Chan *c, char *name)
+{
+ if(strcmp(name, "..") == 0){
+ switch(TYPE(c->qid)){
+ case Qtopdir:
+ case Qsdpdir:
+ c->qid = (Qid){CHDIR|Qtopdir, 0};
+ break;
+ case Qportdir:
+ c->qid = (Qid){CHDIR|Qsdpdir, 0};
+ break;
+ default:
+ panic("sdpwalk %lux", c->qid.path);
+ }
+ return 1;
+ }
+
+ return devwalk(c, name, 0, 0, sdpgen);
+}
+
+static void
+sdpstat(Chan* c, char* db)
+{
+ devstat(c, db, nil, 0, sdpgen);
+}
+
+static Chan*
+sdpopen(Chan* c, int omode)
+{
+ int perm;
+ Sdp *sdp;
+
+ omode &= 3;
+ perm = m2p[omode];
+ USED(perm);
+
+ sdp = sdptab + c->dev;
+
+ switch(TYPE(c->qid)) {
+ default:
+ break;
+ case Qtopdir:
+ case Qsdpdir:
+ case Qportdir:
+ case Qstatus:
+ case Qlocal:
+ case Qstats:
+ if(omode != OREAD)
+ error(Eperm);
+ break;
+ case Qlog:
+ logopen(sdp);
+ break;
+ }
+ c->mode = openmode(omode);
+ c->flag |= COPEN;
+ c->offset = 0;
+ return c;
+}
+
+static void
+sdpclose(Chan* c)
+{
+ Sdp *sdp = sdptab + c->dev;
+
+ switch(TYPE(c->qid)) {
+ case Qlog:
+ if(c->flag & COPEN)
+ logclose(sdp);
+ break;
+ }
+}
+
+static long
+sdpread(Chan *c, void *a, long n, vlong off)
+{
+ char buf[256];
+ Sdp *sdp = sdptab + c->dev;
+ Port *port;
+
+ USED(off);
+ switch(TYPE(c->qid)) {
+ default:
+ error(Eperm);
+ case Qtopdir:
+ case Qsdpdir:
+ case Qportdir:
+ return devdirread(c, a, n, 0, 0, sdpgen);
+ case Qlog:
+ return logread(sdp, a, off, n);
+ case Qstatus:
+ qlock(sdp);
+ port = sdp->port[PORT(c->qid)];
+ if(port == 0)
+ strcpy(buf, "unbound\n");
+ else {
+ }
+ n = readstr(off, a, n, buf);
+ qunlock(sdp);
+ return n;
+ }
+
+}
+
+static long
+sdpwrite(Chan *c, void *a, long n, vlong off)
+{
+ Sdp *sdp = sdptab + c->dev;
+ Cmdbuf *cb;
+ char *arg0;
+ char *p;
+
+ USED(off);
+ switch(TYPE(c->qid)) {
+ default:
+ error(Eperm);
+ case Qctl:
+ cb = parsecmd(a, n);
+ qlock(sdp);
+ if(waserror()) {
+ qunlock(sdp);
+ free(cb);
+ nexterror();
+ }
+ if(cb->nf == 0)
+ error("short write");
+ arg0 = cb->f[0];
+ if(strcmp(arg0, "xxx") == 0) {
+ print("xxx\n");
+ } else
+ error("unknown control request");
+ poperror();
+ qunlock(sdp);
+ free(cb);
+ return n;
+ case Qlog:
+ cb = parsecmd(a, n);
+ p = logctl(sdp, cb->nf, cb->f, logflags);
+ free(cb);
+ if(p != nil)
+ error(p);
+ return n;
+ }
+}
+
+static int
+sdpgen(Chan *c, Dirtab*, int, int s, Dir *dp)
+{
+ Sdp *sdp = sdptab + c->dev;
+ int type = TYPE(c->qid);
+ char buf[32];
+ Dirtab *dt;
+ Qid qid;
+
+ switch(type) {
+ default:
+ // non directory entries end up here
+ if(c->qid.path & CHDIR)
+ panic("sdpgen: unexpected directory");
+ if(s != 0)
+ return -1;
+ dt = dirtab[TYPE(c->qid)];
+ if(dt == nil)
+ panic("sdpgen: unknown type: %d", TYPE(c->qid));
+ devdir(c, c->qid, dt->name, dt->length, eve, dt->perm, dp);
+ return 1;
+ case Qtopdir:
+ if(s != 0)
+ return -1;
+ devdir(c, (Qid){QID(0,Qsdpdir)|CHDIR,0}, "sdp", 0, eve, 0555, dp);
+ return 1;
+ case Qsdpdir:
+ if(s<nelem(sdpdirtab)) {
+ dt = sdpdirtab+s;
+ devdir(c, dt->qid, dt->name, dt->length, eve, dt->perm, dp);
+ return 1;
+ }
+ s -= nelem(sdpdirtab);
+ if(s >= sdp->nport)
+ return -1;
+ qid = (Qid){QID(s,Qportdir)|CHDIR, 0};
+ snprint(buf, sizeof(buf), "%d", s);
+ devdir(c, qid, buf, 0, eve, 0555, dp);
+ return 1;
+ case Qportdir:
+ if(s>=nelem(portdirtab))
+ return -1;
+ dt = portdirtab+s;
+ qid = (Qid){QID(PORT(c->qid),TYPE(dt->qid)),0};
+ devdir(c, qid, dt->name, dt->length, eve, dt->perm, dp);
+ return 1;
+ }
+}
+
+
+Dev sdpdevtab = {
+ 'T',
+ "sdp",
+
+ devreset,
+ sdpinit,
+ sdpattach,
+ devclone,
+ sdpwalk,
+ sdpstat,
+ sdpopen,
+ devcreate,
+ sdpclose,
+ sdpread,
+ devbread,
+ sdpwrite,
+ devbwrite,
+ devremove,
+ devwstat,
+};