Import sources from 2011-03-30 iso image

This commit is contained in:
Taru Karttunen 2011-03-30 15:46:40 +03:00
commit e5888a1ffd
7810 changed files with 2489717 additions and 0 deletions

77
sys/src/libip/bo.c Executable file
View file

@ -0,0 +1,77 @@
#include <u.h>
#include <libc.h>
#include <ip.h>
void
hnputv(void *p, uvlong v)
{
uchar *a;
a = p;
a[0] = v>>56;
a[1] = v>>48;
a[2] = v>>40;
a[3] = v>>32;
a[4] = v>>24;
a[5] = v>>16;
a[6] = v>>8;
a[7] = v;
}
void
hnputl(void *p, uint v)
{
uchar *a;
a = p;
a[0] = v>>24;
a[1] = v>>16;
a[2] = v>>8;
a[3] = v;
}
void
hnputs(void *p, ushort v)
{
uchar *a;
a = p;
a[0] = v>>8;
a[1] = v;
}
uvlong
nhgetv(void *p)
{
uchar *a;
uvlong v;
a = p;
v = (uvlong)a[0]<<56;
v |= (uvlong)a[1]<<48;
v |= (uvlong)a[2]<<40;
v |= (uvlong)a[3]<<32;
v |= a[4]<<24;
v |= a[5]<<16;
v |= a[6]<<8;
v |= a[7]<<0;
return v;
}
uint
nhgetl(void *p)
{
uchar *a;
a = p;
return (a[0]<<24)|(a[1]<<16)|(a[2]<<8)|(a[3]<<0);
}
ushort
nhgets(void *p)
{
uchar *a;
a = p;
return (a[0]<<8)|(a[1]<<0);
}

86
sys/src/libip/classmask.c Executable file
View file

@ -0,0 +1,86 @@
#include <u.h>
#include <libc.h>
#include <ip.h>
static uchar classmask[4][16] = {
0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0x00,0x00,0x00,
0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0x00,0x00,0x00,
0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0x00,0x00,
0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0x00,
};
static uchar v6loopback[IPaddrlen] = {
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0x01
};
static uchar v6linklocal[IPaddrlen] = {
0xfe, 0x80, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0
};
static uchar v6linklocalmask[IPaddrlen] = {
0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff,
0, 0, 0, 0,
0, 0, 0, 0
};
static int v6llpreflen = 8; /* link-local prefix length in bytes */
static uchar v6multicast[IPaddrlen] = {
0xff, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0
};
static uchar v6multicastmask[IPaddrlen] = {
0xff, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0
};
static int v6mcpreflen = 1; /* multicast prefix length */
static uchar v6solicitednode[IPaddrlen] = {
0xff, 0x02, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0x01,
0xff, 0, 0, 0
};
static uchar v6solicitednodemask[IPaddrlen] = {
0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff,
0xff, 0x0, 0x0, 0x0
};
static int v6snpreflen = 13;
uchar*
defmask(uchar *ip)
{
if(isv4(ip))
return classmask[ip[IPv4off]>>6];
else {
if(ipcmp(ip, v6loopback) == 0)
return IPallbits;
else if(memcmp(ip, v6linklocal, v6llpreflen) == 0)
return v6linklocalmask;
else if(memcmp(ip, v6solicitednode, v6snpreflen) == 0)
return v6solicitednodemask;
else if(memcmp(ip, v6multicast, v6mcpreflen) == 0)
return v6multicastmask;
return IPallbits;
}
}
void
maskip(uchar *from, uchar *mask, uchar *to)
{
int i;
for(i = 0; i < IPaddrlen; i++)
to[i] = from[i] & mask[i];
}

109
sys/src/libip/eipfmt.c Executable file
View file

@ -0,0 +1,109 @@
#include <u.h>
#include <libc.h>
#include <ip.h>
enum
{
Isprefix= 16,
};
uchar prefixvals[256] =
{
[0x00] 0 | Isprefix,
[0x80] 1 | Isprefix,
[0xC0] 2 | Isprefix,
[0xE0] 3 | Isprefix,
[0xF0] 4 | Isprefix,
[0xF8] 5 | Isprefix,
[0xFC] 6 | Isprefix,
[0xFE] 7 | Isprefix,
[0xFF] 8 | Isprefix,
};
int
eipfmt(Fmt *f)
{
char buf[5*8];
static char *efmt = "%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux";
static char *ifmt = "%d.%d.%d.%d";
uchar *p, ip[16];
ulong *lp;
ushort s;
int i, j, n, eln, eli;
switch(f->r) {
case 'E': /* Ethernet address */
p = va_arg(f->args, uchar*);
snprint(buf, sizeof buf, efmt, p[0], p[1], p[2], p[3], p[4], p[5]);
return fmtstrcpy(f, buf);
case 'I': /* Ip address */
p = va_arg(f->args, uchar*);
common:
if(memcmp(p, v4prefix, 12) == 0){
snprint(buf, sizeof buf, ifmt, p[12], p[13], p[14], p[15]);
return fmtstrcpy(f, buf);
}
/* find longest elision */
eln = eli = -1;
for(i = 0; i < 16; i += 2){
for(j = i; j < 16; j += 2)
if(p[j] != 0 || p[j+1] != 0)
break;
if(j > i && j - i > eln){
eli = i;
eln = j - i;
}
}
/* print with possible elision */
n = 0;
for(i = 0; i < 16; i += 2){
if(i == eli){
n += sprint(buf+n, "::");
i += eln;
if(i >= 16)
break;
} else if(i != 0)
n += sprint(buf+n, ":");
s = (p[i]<<8) + p[i+1];
n += sprint(buf+n, "%ux", s);
}
return fmtstrcpy(f, buf);
case 'i': /* v6 address as 4 longs */
lp = va_arg(f->args, ulong*);
for(i = 0; i < 4; i++)
hnputl(ip+4*i, *lp++);
p = ip;
goto common;
case 'V': /* v4 ip address */
p = va_arg(f->args, uchar*);
snprint(buf, sizeof buf, ifmt, p[0], p[1], p[2], p[3]);
return fmtstrcpy(f, buf);
case 'M': /* ip mask */
p = va_arg(f->args, uchar*);
/* look for a prefix mask */
for(i = 0; i < 16; i++)
if(p[i] != 0xff)
break;
if(i < 16){
if((prefixvals[p[i]] & Isprefix) == 0)
goto common;
for(j = i+1; j < 16; j++)
if(p[j] != 0)
goto common;
n = 8*i + (prefixvals[p[i]] & ~Isprefix);
} else
n = 8*16;
/* got one, use /xx format */
snprint(buf, sizeof buf, "/%d", n);
return fmtstrcpy(f, buf);
}
return fmtstrcpy(f, "(eipfmt)");
}

25
sys/src/libip/equivip.c Executable file
View file

@ -0,0 +1,25 @@
#include <u.h>
#include <libc.h>
#include <ip.h>
int
equivip4(uchar *a, uchar *b)
{
int i;
for(i = 0; i < 4; i++)
if(a[i] != b[i])
return 0;
return 1;
}
int
equivip6(uchar *a, uchar *b)
{
int i;
for(i = 0; i < IPaddrlen; i++)
if(a[i] != b[i])
return 0;
return 1;
}

102
sys/src/libip/ipaux.c Executable file
View file

@ -0,0 +1,102 @@
#include <u.h>
#include <libc.h>
#include <ip.h>
/*
* well known IP addresses
*/
uchar IPv4bcast[IPaddrlen] = {
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff
};
uchar IPv4allsys[IPaddrlen] = {
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0xff, 0xff,
0xe0, 0, 0, 0x01
};
uchar IPv4allrouter[IPaddrlen] = {
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0xff, 0xff,
0xe0, 0, 0, 0x02
};
uchar IPallbits[IPaddrlen] = {
0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff
};
uchar IPnoaddr[IPaddrlen];
/*
* prefix of all v4 addresses
*/
uchar v4prefix[IPaddrlen] = {
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0xff, 0xff,
0, 0, 0, 0
};
int
isv4(uchar *ip)
{
return memcmp(ip, v4prefix, IPv4off) == 0;
}
/*
* the following routines are unrolled with no memset's to speed
* up the usual case
*/
void
v4tov6(uchar *v6, uchar *v4)
{
v6[0] = 0;
v6[1] = 0;
v6[2] = 0;
v6[3] = 0;
v6[4] = 0;
v6[5] = 0;
v6[6] = 0;
v6[7] = 0;
v6[8] = 0;
v6[9] = 0;
v6[10] = 0xff;
v6[11] = 0xff;
v6[12] = v4[0];
v6[13] = v4[1];
v6[14] = v4[2];
v6[15] = v4[3];
}
int
v6tov4(uchar *v4, uchar *v6)
{
if(v6[0] == 0
&& v6[1] == 0
&& v6[2] == 0
&& v6[3] == 0
&& v6[4] == 0
&& v6[5] == 0
&& v6[6] == 0
&& v6[7] == 0
&& v6[8] == 0
&& v6[9] == 0
&& v6[10] == 0xff
&& v6[11] == 0xff)
{
v4[0] = v6[12];
v4[1] = v6[13];
v4[2] = v6[14];
v4[3] = v6[15];
return 0;
} else {
memset(v4, 0, 4);
if(memcmp(v6, IPnoaddr, IPaddrlen) == 0)
return 0;
return -1;
}
}

26
sys/src/libip/mkfile Executable file
View file

@ -0,0 +1,26 @@
</$objtype/mkfile
LIB=/$objtype/lib/libip.a
OFILES=\
eipfmt.$O\
equivip.$O\
parseip.$O\
parseether.$O\
myetheraddr.$O\
myipaddr.$O\
classmask.$O\
bo.$O\
readipifc.$O\
ipaux.$O\
ptclbsum.$O\
HFILES=\
/sys/include/ip.h
UPDATE=\
mkfile\
$HFILES\
${OFILES:%.$O=%.c}\
${LIB:/$objtype/%=/386/%}\
</sys/src/cmd/mksyslib

28
sys/src/libip/myetheraddr.c Executable file
View file

@ -0,0 +1,28 @@
#include <u.h>
#include <libc.h>
#include <ip.h>
int
myetheraddr(uchar *to, char *dev)
{
int n, fd;
char buf[256];
if(*dev == '/')
sprint(buf, "%s/addr", dev);
else
sprint(buf, "/net/%s/addr", dev);
fd = open(buf, OREAD);
if(fd < 0)
return -1;
n = read(fd, buf, sizeof buf -1 );
close(fd);
if(n <= 0)
return -1;
buf[n] = 0;
parseether(to, buf);
return 0;
}

42
sys/src/libip/myipaddr.c Executable file
View file

@ -0,0 +1,42 @@
#include <u.h>
#include <libc.h>
#include <ip.h>
static uchar loopbacknet[IPaddrlen] = {
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0xff, 0xff,
127, 0, 0, 0
};
static uchar loopbackmask[IPaddrlen] = {
0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff,
0xff, 0, 0, 0
};
// find first ip addr that isn't the friggin loopback address
// unless there are no others
int
myipaddr(uchar *ip, char *net)
{
Ipifc *nifc;
Iplifc *lifc;
static Ipifc *ifc;
uchar mynet[IPaddrlen];
ifc = readipifc(net, ifc, -1);
for(nifc = ifc; nifc; nifc = nifc->next)
for(lifc = nifc->lifc; lifc; lifc = lifc->next){
maskip(lifc->ip, loopbackmask, mynet);
if(ipcmp(mynet, loopbacknet) == 0){
continue;
}
if(ipcmp(lifc->ip, IPnoaddr) != 0){
ipmove(ip, lifc->ip);
return 0;
}
}
ipmove(ip, IPnoaddr);
return -1;
}

25
sys/src/libip/parseether.c Executable file
View file

@ -0,0 +1,25 @@
#include <u.h>
#include <libc.h>
int
parseether(uchar *to, char *from)
{
char nip[4];
char *p;
int i;
p = from;
for(i = 0; i < 6; i++){
if(*p == 0)
return -1;
nip[0] = *p++;
if(*p == 0)
return -1;
nip[1] = *p++;
nip[2] = 0;
to[i] = strtoul(nip, 0, 16);
if(*p == ':')
p++;
}
return 0;
}

184
sys/src/libip/parseip.c Executable file
View file

@ -0,0 +1,184 @@
#include <u.h>
#include <libc.h>
#include <ctype.h>
#include <ip.h>
char*
v4parseip(uchar *to, char *from)
{
int i;
char *p;
p = from;
for(i = 0; i < 4 && *p; i++){
to[i] = strtoul(p, &p, 0);
if(*p == '.')
p++;
}
switch(CLASS(to)){
case 0: /* class A - 1 uchar net */
case 1:
if(i == 3){
to[3] = to[2];
to[2] = to[1];
to[1] = 0;
} else if (i == 2){
to[3] = to[1];
to[1] = 0;
}
break;
case 2: /* class B - 2 uchar net */
if(i == 3){
to[3] = to[2];
to[2] = 0;
}
break;
}
return p;
}
static int
ipcharok(int c)
{
return c == '.' || c == ':' || isascii(c) && isxdigit(c);
}
static int
delimchar(int c)
{
if(c == '\0')
return 1;
if(c == '.' || c == ':' || isascii(c) && isalnum(c))
return 0;
return 1;
}
/*
* `from' may contain an address followed by other characters,
* at least in /boot, so we permit whitespace (and more) after the address.
* we do ensure that "delete" cannot be parsed as "de::".
*
* some callers don't check the return value for errors, so
* set `to' to something distinctive in the case of a parse error.
*/
vlong
parseip(uchar *to, char *from)
{
int i, elipsis = 0, v4 = 1;
ulong x;
char *p, *op;
memset(to, 0, IPaddrlen);
p = from;
for(i = 0; i < IPaddrlen && ipcharok(*p); i+=2){
op = p;
x = strtoul(p, &p, 16);
if(*p == '.' || (*p == 0 && i == 0)){ /* ends with v4? */
p = v4parseip(to+i, op);
i += 4;
break;
}
/* v6: at most 4 hex digits, followed by colon or delim */
if(x != (ushort)x || *p != ':' && !delimchar(*p)) {
memset(to, 0, IPaddrlen);
return -1; /* parse error */
}
to[i] = x>>8;
to[i+1] = x;
if(*p == ':'){
v4 = 0;
if(*++p == ':'){ /* :: is elided zero short(s) */
if (elipsis) {
memset(to, 0, IPaddrlen);
return -1; /* second :: */
}
elipsis = i+2;
p++;
}
} else if (p == op) /* strtoul made no progress? */
break;
}
if (p == from || !delimchar(*p)) {
memset(to, 0, IPaddrlen);
return -1; /* parse error */
}
if(i < IPaddrlen){
memmove(&to[elipsis+IPaddrlen-i], &to[elipsis], i-elipsis);
memset(&to[elipsis], 0, IPaddrlen-i);
}
if(v4){
to[10] = to[11] = 0xff;
return nhgetl(to + IPv4off);
} else
return 6;
}
/*
* hack to allow ip v4 masks to be entered in the old
* style
*/
vlong
parseipmask(uchar *to, char *from)
{
int i, w;
vlong x;
uchar *p;
if(*from == '/'){
/* as a number of prefix bits */
i = atoi(from+1);
if(i < 0)
i = 0;
if(i > 128)
i = 128;
w = i;
memset(to, 0, IPaddrlen);
for(p = to; i >= 8; i -= 8)
*p++ = 0xff;
if(i > 0)
*p = ~((1<<(8-i))-1);
x = nhgetl(to+IPv4off);
/*
* identify as ipv6 if the mask is inexpressible as a v4 mask
* (because it has too few mask bits). Arguably, we could
* always return 6 here.
*/
if (w < 8*(IPaddrlen-IPv4addrlen))
return 6;
} else {
/* as a straight v4 bit mask */
x = parseip(to, from);
if (x != -1)
x = (ulong)nhgetl(to + IPv4off);
if(memcmp(to, v4prefix, IPv4off) == 0)
memset(to, 0xff, IPv4off);
}
return x;
}
/*
* parse a v4 ip address/mask in cidr format
*/
char*
v4parsecidr(uchar *addr, uchar *mask, char *from)
{
int i;
char *p;
uchar *a;
p = v4parseip(addr, from);
if(*p == '/'){
/* as a number of prefix bits */
i = strtoul(p+1, &p, 0);
if(i > 32)
i = 32;
memset(mask, 0, IPv4addrlen);
for(a = mask; i >= 8; i -= 8)
*a++ = 0xff;
if(i > 0)
*a = ~((1<<(8-i))-1);
} else
memcpy(mask, defmask(addr), IPv4addrlen);
return p;
}

68
sys/src/libip/ptclbsum.c Executable file
View file

@ -0,0 +1,68 @@
#include <u.h>
#include <libc.h>
#include <ip.h>
static short endian = 1;
static uchar* aendian = (uchar*)&endian;
#define LITTLE *aendian
ushort
ptclbsum(uchar *addr, int len)
{
ulong losum, hisum, mdsum, x;
ulong t1, t2;
losum = 0;
hisum = 0;
mdsum = 0;
x = 0;
if((uintptr)addr & 1) {
if(len) {
hisum += addr[0];
len--;
addr++;
}
x = 1;
}
while(len >= 16) {
t1 = *(ushort*)(addr+0);
t2 = *(ushort*)(addr+2); mdsum += t1;
t1 = *(ushort*)(addr+4); mdsum += t2;
t2 = *(ushort*)(addr+6); mdsum += t1;
t1 = *(ushort*)(addr+8); mdsum += t2;
t2 = *(ushort*)(addr+10); mdsum += t1;
t1 = *(ushort*)(addr+12); mdsum += t2;
t2 = *(ushort*)(addr+14); mdsum += t1;
mdsum += t2;
len -= 16;
addr += 16;
}
while(len >= 2) {
mdsum += *(ushort*)addr;
len -= 2;
addr += 2;
}
if(x) {
if(len)
losum += addr[0];
if(LITTLE)
losum += mdsum;
else
hisum += mdsum;
} else {
if(len)
hisum += addr[0];
if(LITTLE)
hisum += mdsum;
else
losum += mdsum;
}
losum += hisum >> 8;
losum += (hisum & 0xff) << 8;
while(hisum = losum>>16)
losum = hisum + (losum & 0xffff);
return losum & 0xffff;
}

201
sys/src/libip/readipifc.c Executable file
View file

@ -0,0 +1,201 @@
#include <u.h>
#include <libc.h>
#include <ctype.h>
#include <ip.h>
static Ipifc**
_readoldipifc(char *buf, Ipifc **l, int index)
{
char *f[200];
int i, n;
Ipifc *ifc;
Iplifc *lifc, **ll;
/* allocate new interface */
*l = ifc = mallocz(sizeof(Ipifc), 1);
if(ifc == nil)
return l;
l = &ifc->next;
ifc->index = index;
n = tokenize(buf, f, nelem(f));
if(n < 2)
return l;
strncpy(ifc->dev, f[0], sizeof ifc->dev);
ifc->dev[sizeof(ifc->dev) - 1] = 0;
ifc->mtu = strtoul(f[1], nil, 10);
ll = &ifc->lifc;
for(i = 2; n-i >= 7; i += 7){
/* allocate new local address */
*ll = lifc = mallocz(sizeof(Iplifc), 1);
ll = &lifc->next;
parseip(lifc->ip, f[i]);
parseipmask(lifc->mask, f[i+1]);
parseip(lifc->net, f[i+2]);
ifc->pktin = strtoul(f[i+3], nil, 10);
ifc->pktout = strtoul(f[i+4], nil, 10);
ifc->errin = strtoul(f[i+5], nil, 10);
ifc->errout = strtoul(f[i+6], nil, 10);
}
return l;
}
static char*
findfield(char *name, char **f, int n)
{
int i;
for(i = 0; i < n-1; i++)
if(strcmp(f[i], name) == 0)
return f[i+1];
return "";
}
static Ipifc**
_readipifc(char *file, Ipifc **l, int index)
{
int i, n, fd, lines;
char buf[4*1024];
char *line[32];
char *f[64];
Ipifc *ifc, **l0;
Iplifc *lifc, **ll;
/* read the file */
fd = open(file, OREAD);
if(fd < 0)
return l;
n = 0;
while((i = read(fd, buf+n, sizeof(buf)-1-n)) > 0 && n < sizeof(buf) - 1)
n += i;
buf[n] = 0;
close(fd);
if(strncmp(buf, "device", 6) != 0)
return _readoldipifc(buf, l, index);
/* ignore ifcs with no associated device */
if(strncmp(buf+6, " ", 2) == 0)
return l;
/* allocate new interface */
*l = ifc = mallocz(sizeof(Ipifc), 1);
if(ifc == nil)
return l;
l0 = l;
l = &ifc->next;
ifc->index = index;
lines = getfields(buf, line, nelem(line), 1, "\n");
/* pick off device specific info(first line) */
n = tokenize(line[0], f, nelem(f));
if(n%2 != 0)
goto lose;
strncpy(ifc->dev, findfield("device", f, n), sizeof(ifc->dev));
ifc->dev[sizeof(ifc->dev)-1] = 0;
if(ifc->dev[0] == 0){
lose:
free(ifc);
*l0 = nil;
return l;
}
ifc->mtu = strtoul(findfield("maxtu", f, n), nil, 10);
ifc->sendra6 = atoi(findfield("sendra", f, n));
ifc->recvra6 = atoi(findfield("recvra", f, n));
ifc->rp.mflag = atoi(findfield("mflag", f, n));
ifc->rp.oflag = atoi(findfield("oflag", f, n));
ifc->rp.maxraint = atoi(findfield("maxraint", f, n));
ifc->rp.minraint = atoi(findfield("minraint", f, n));
ifc->rp.linkmtu = atoi(findfield("linkmtu", f, n));
ifc->rp.reachtime = atoi(findfield("reachtime", f, n));
ifc->rp.rxmitra = atoi(findfield("rxmitra", f, n));
ifc->rp.ttl = atoi(findfield("ttl", f, n));
ifc->rp.routerlt = atoi(findfield("routerlt", f, n));
ifc->pktin = strtoul(findfield("pktin", f, n), nil, 10);
ifc->pktout = strtoul(findfield("pktout", f, n), nil, 10);
ifc->errin = strtoul(findfield("errin", f, n), nil, 10);
ifc->errout = strtoul(findfield("errout", f, n), nil, 10);
/* now read the addresses */
ll = &ifc->lifc;
for(i = 1; i < lines; i++){
n = tokenize(line[i], f, nelem(f));
if(n < 5)
break;
/* allocate new local address */
*ll = lifc = mallocz(sizeof(Iplifc), 1);
ll = &lifc->next;
parseip(lifc->ip, f[0]);
parseipmask(lifc->mask, f[1]);
parseip(lifc->net, f[2]);
lifc->validlt = strtoul(f[3], nil, 10);
lifc->preflt = strtoul(f[4], nil, 10);
}
return l;
}
static void
_freeifc(Ipifc *ifc)
{
Ipifc *next;
Iplifc *lnext, *lifc;
if(ifc == nil)
return;
for(; ifc; ifc = next){
next = ifc->next;
for(lifc = ifc->lifc; lifc; lifc = lnext){
lnext = lifc->next;
free(lifc);
}
free(ifc);
}
}
Ipifc*
readipifc(char *net, Ipifc *ifc, int index)
{
int fd, i, n;
Dir *dir;
char directory[128];
char buf[128];
Ipifc **l;
_freeifc(ifc);
l = &ifc;
ifc = nil;
if(net == 0)
net = "/net";
snprint(directory, sizeof(directory), "%s/ipifc", net);
if(index >= 0){
snprint(buf, sizeof(buf), "%s/%d/status", directory, index);
_readipifc(buf, l, index);
} else {
fd = open(directory, OREAD);
if(fd < 0)
return nil;
n = dirreadall(fd, &dir);
close(fd);
for(i = 0; i < n; i++){
if(strcmp(dir[i].name, "clone") == 0)
continue;
if(strcmp(dir[i].name, "stats") == 0)
continue;
snprint(buf, sizeof(buf), "%s/%s/status", directory, dir[i].name);
l = _readipifc(buf, l, atoi(dir[i].name));
}
free(dir);
}
return ifc;
}

21
sys/src/libip/testreadipifc.c Executable file
View file

@ -0,0 +1,21 @@
#include <u.h>
#include <libc.h>
#include <ip.h>
void
main(void)
{
Ipifc *ifc, *list;
Iplifc *lifc;
int i;
fmtinstall('I', eipfmt);
fmtinstall('M', eipfmt);
list = readipifc("/net", nil, -1);
for(ifc = list; ifc; ifc = ifc->next){
print("ipifc %s %d\n", ifc->dev, ifc->mtu);
for(lifc = ifc->lifc; lifc; lifc = lifc->next)
print("\t%I %M %I\n", lifc->ip, lifc->mask, lifc->net);
}
}