#include <u.h>
#include <libc.h>
#include <ip.h>
#define NODEFINE
#include <9pm/u.h>
#include <9pm/libc.h>
#include <9pm/ns.h>
#undef NODEFINE
#include <9pm/devip.h>
static long
netread(Conv *c, void *data, long ndata)
{
long n;
if((n=read(c->sfd, data, ndata)) < 0)
pm_oserror();
return n;
}
static long
netwrite(Conv *c, void *data, long ndata)
{
long n;
if((n=write(c->sfd, data, ndata)) < 0){
pm_oserror();
pm_nexterror();
}
return n;
}
static void
netopen(Conv *c, int fd)
{
int n;
char buf[64], num[12];
c->cfd = fd;
c->sfd = -1;
if((n=read(fd, num, sizeof(num)-1)) <= 0){
pm_oserror();
c->cfd = -1;
close(fd);
pm_nexterror();
}
num[n] = '\0';
c->dirno = atoi(num);
sprint(buf, "/net/%s/%d/data", c->p->name, c->dirno);
if((fd = open(buf, ORDWR)) < 0){
pm_oserror();
close(c->cfd);
c->cfd = -1;
pm_nexterror();
}
c->sfd = fd;
}
static void
netclone(Conv *c)
{
int fd;
char buf[64];
sprint(buf, "/net/%s/clone", c->p->name);
if((fd = open(buf, ORDWR)) < 0){
pm_oserror();
pm_nexterror();
}
netopen(c, fd);
}
static void
netconnect(Conv *c)
{
uchar ip[4];
hnputl(ip, c->raddr);
if(c->lport) {
if(fprint(c->cfd, "connect %L %d", ip, c->rport, c->lport) < 0) {
pm_oserror();
pm_nexterror();
}
} else {
if(fprint(c->cfd, "connect %L", ip, c->rport) < 0) {
pm_oserror();
pm_nexterror();
}
}
}
static void
netannounce(Conv *c)
{
uchar ip[4];
hnputl(ip, c->raddr);
if(fprint(c->cfd, "announce %L", ip, c->rport) < 0) {
pm_oserror();
pm_nexterror();
}
}
static void
netlisten(Conv *c, Conv *oc)
{
char buf[64];
int lfd;
sprint(buf, "/net/%s/%d/listen", oc->p->name, oc->dirno);
if((lfd = open(buf, OREAD)) < 0) {
pm_oserror();
pm_nexterror();
}
netopen(c, lfd);
}
static void
netclose(Conv *c)
{
close(c->sfd);
c->sfd = -1;
close(c->cfd);
c->cfd = -1;
}
/* takes two arguments (!) */
static int
Lconv(va_list *va, Fconv *fp)
{
uchar* addr;
ushort port;
char buf[40];
addr = va_arg(*va, uchar*);
port = va_arg(*va, int); /* not ushort */
if(addr == 0 && port == 0)
snprint(buf, sizeof buf, "*");
else if(addr == 0)
snprint(buf, sizeof buf, "%d", port);
else if(port == 0)
snprint(buf, sizeof buf, "%V!*", addr);
else
snprint(buf, sizeof buf, "%V!%d", addr, port);
strconv(buf, fp);
return 0;
}
static Proto ilproto = {
"il",
netread,
netwrite,
netclone,
netconnect,
netannounce,
netlisten,
netclose,
40,
};
static Proto udpproto = {
"udp",
netread,
netwrite,
netclone,
netconnect,
netannounce,
netlisten,
netclose,
30,
};
static Proto tcpproto = {
"tcp",
netread,
netwrite,
netclone,
netconnect,
netannounce,
netlisten,
netclose,
40,
};
void
ipinit(void (*inst)(Proto*))
{
fmtinstall('V', eipconv);
fmtinstall('L', Lconv);
(*inst)(&tcpproto);
(*inst)(&udpproto);
(*inst)(&ilproto);
}
syntax highlighted by Code2HTML, v. 0.9.1