add libip
This commit is contained in:
parent
99947423b1
commit
d709423926
13 changed files with 875 additions and 0 deletions
44
src/libip/bo.c
Normal file
44
src/libip/bo.c
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#include <ip.h>
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
25
src/libip/classmask.c
Normal file
25
src/libip/classmask.c
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#include <ip.h>
|
||||||
|
|
||||||
|
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,
|
||||||
|
};
|
||||||
|
|
||||||
|
uchar*
|
||||||
|
defmask(uchar *ip)
|
||||||
|
{
|
||||||
|
return classmask[ip[IPv4off]>>6];
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
maskip(uchar *from, uchar *mask, uchar *to)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for(i = 0; i < IPaddrlen; i++)
|
||||||
|
to[i] = from[i] & mask[i];
|
||||||
|
}
|
||||||
109
src/libip/eipfmt.c
Normal file
109
src/libip/eipfmt.c
Normal 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 = "%.2lux%.2lux%.2lux%.2lux%.2lux%.2lux";
|
||||||
|
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)");
|
||||||
|
}
|
||||||
13
src/libip/equivip.c
Normal file
13
src/libip/equivip.c
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
equivip(uchar *a, uchar *b)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for(i = 0; i < 4; i++)
|
||||||
|
if(a[i] != b[i])
|
||||||
|
return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
77
src/libip/ip.h
Normal file
77
src/libip/ip.h
Normal file
|
|
@ -0,0 +1,77 @@
|
||||||
|
#pragma src "/sys/src/libip"
|
||||||
|
#pragma lib "libip.a"
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
IPaddrlen= 16,
|
||||||
|
IPv4addrlen= 4,
|
||||||
|
IPv4off= 12,
|
||||||
|
IPllen= 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* for reading /net/ipifc
|
||||||
|
*/
|
||||||
|
typedef struct Ipifc Ipifc;
|
||||||
|
typedef struct Ipifcs Ipifcs;
|
||||||
|
|
||||||
|
struct Ipifc
|
||||||
|
{
|
||||||
|
char dev[64];
|
||||||
|
uchar ip[IPaddrlen];
|
||||||
|
uchar mask[IPaddrlen];
|
||||||
|
uchar net[IPaddrlen]; /* ip & mask */
|
||||||
|
Ipifc *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Ipifcs
|
||||||
|
{
|
||||||
|
Ipifc *first;
|
||||||
|
Ipifc *last;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* user level udp headers
|
||||||
|
*/
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
Udphdrsize= 36, /* size of a Udphdr */
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct Udphdr Udphdr;
|
||||||
|
struct Udphdr
|
||||||
|
{
|
||||||
|
uchar raddr[IPaddrlen]; /* remote address and port */
|
||||||
|
uchar laddr[IPaddrlen]; /* local address and port */
|
||||||
|
uchar rport[2];
|
||||||
|
uchar lport[2];
|
||||||
|
};
|
||||||
|
|
||||||
|
uchar* defmask(uchar*);
|
||||||
|
void maskip(uchar*, uchar*, uchar*);
|
||||||
|
int eipconv(va_list*, Fconv*);
|
||||||
|
ulong parseip(uchar*, char*);
|
||||||
|
ulong parseipmask(uchar*, char*);
|
||||||
|
int parseether(uchar*, char*);
|
||||||
|
int myipaddr(uchar*, char*);
|
||||||
|
int myetheraddr(uchar*, char*);
|
||||||
|
|
||||||
|
void readipifc(char*, Ipifcs*);
|
||||||
|
|
||||||
|
void hnputl(void*, uint);
|
||||||
|
void hnputs(void*, ushort);
|
||||||
|
uint nhgetl(void*);
|
||||||
|
ushort nhgets(void*);
|
||||||
|
|
||||||
|
#define ipcmp(x, y) memcmp(x, y, IPaddrlen)
|
||||||
|
#define ipmove(x, y) memmove(x, y, IPaddrlen)
|
||||||
|
|
||||||
|
extern uchar IPv4bcast[IPaddrlen];
|
||||||
|
extern uchar IPv4bcastobs[IPaddrlen];
|
||||||
|
extern uchar IPv4allsys[IPaddrlen];
|
||||||
|
extern uchar IPv4allrouter[IPaddrlen];
|
||||||
|
extern uchar IPnoaddr[IPaddrlen];
|
||||||
|
extern uchar v4prefix[IPaddrlen];
|
||||||
|
extern uchar IPallbits[IPaddrlen];
|
||||||
|
|
||||||
|
#define CLASS(p) ((*(uchar*)(p))>>6)
|
||||||
102
src/libip/ipaux.c
Normal file
102
src/libip/ipaux.c
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
41
src/libip/myetheraddr.c
Normal file
41
src/libip/myetheraddr.c
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#include <ip.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
myetheraddr(uchar *to, char *dev)
|
||||||
|
{
|
||||||
|
int n, fd;
|
||||||
|
char buf[256], *ptr;
|
||||||
|
|
||||||
|
/* Make one exist */
|
||||||
|
if(*dev == '/')
|
||||||
|
sprint(buf, "%s/clone", dev);
|
||||||
|
else
|
||||||
|
sprint(buf, "/net/%s/clone", dev);
|
||||||
|
fd = open(buf, ORDWR);
|
||||||
|
if(fd >= 0)
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
if(*dev == '/')
|
||||||
|
sprint(buf, "%s/0/stats", dev);
|
||||||
|
else
|
||||||
|
sprint(buf, "/net/%s/0/stats", 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;
|
||||||
|
|
||||||
|
ptr = strstr(buf, "addr: ");
|
||||||
|
if(!ptr)
|
||||||
|
return -1;
|
||||||
|
ptr += 6;
|
||||||
|
|
||||||
|
parseether(to, ptr);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
21
src/libip/myipaddr.c
Normal file
21
src/libip/myipaddr.c
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#include <ip.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
myipaddr(uchar *ip, char *net)
|
||||||
|
{
|
||||||
|
Ipifc *nifc;
|
||||||
|
Iplifc *lifc;
|
||||||
|
static Ipifc *ifc;
|
||||||
|
|
||||||
|
ifc = readipifc(net, ifc, -1);
|
||||||
|
for(nifc = ifc; nifc; nifc = nifc->next)
|
||||||
|
for(lifc = nifc->lifc; lifc; lifc = lifc->next)
|
||||||
|
if(ipcmp(lifc->ip, IPnoaddr) != 0){
|
||||||
|
ipmove(ip, lifc->ip);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
ipmove(ip, IPnoaddr);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
25
src/libip/parseether.c
Normal file
25
src/libip/parseether.c
Normal 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;
|
||||||
|
}
|
||||||
135
src/libip/parseip.c
Normal file
135
src/libip/parseip.c
Normal file
|
|
@ -0,0 +1,135 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.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;
|
||||||
|
}
|
||||||
|
|
||||||
|
ulong
|
||||||
|
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 < 16 && *p; i+=2){
|
||||||
|
op = p;
|
||||||
|
x = strtoul(p, &p, 16);
|
||||||
|
if(*p == '.' || (*p == 0 && i == 0)){
|
||||||
|
p = v4parseip(to+i, op);
|
||||||
|
i += 4;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
to[i] = x>>8;
|
||||||
|
to[i+1] = x;
|
||||||
|
if(*p == ':'){
|
||||||
|
v4 = 0;
|
||||||
|
if(*++p == ':'){
|
||||||
|
elipsis = i+2;
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(i < 16){
|
||||||
|
memmove(&to[elipsis+16-i], &to[elipsis], i-elipsis);
|
||||||
|
memset(&to[elipsis], 0, 16-i);
|
||||||
|
}
|
||||||
|
if(v4){
|
||||||
|
to[10] = to[11] = 0xff;
|
||||||
|
return nhgetl(to+12);
|
||||||
|
} else
|
||||||
|
return 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* hack to allow ip v4 masks to be entered in the old
|
||||||
|
* style
|
||||||
|
*/
|
||||||
|
ulong
|
||||||
|
parseipmask(uchar *to, char *from)
|
||||||
|
{
|
||||||
|
ulong x;
|
||||||
|
int i;
|
||||||
|
uchar *p;
|
||||||
|
|
||||||
|
if(*from == '/'){
|
||||||
|
/* as a number of prefix bits */
|
||||||
|
i = atoi(from+1);
|
||||||
|
if(i < 0)
|
||||||
|
i = 0;
|
||||||
|
if(i > 128)
|
||||||
|
i = 128;
|
||||||
|
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);
|
||||||
|
} else {
|
||||||
|
/* as a straight bit mask */
|
||||||
|
x = parseip(to, from);
|
||||||
|
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
src/libip/ptclbsum.c
Normal file
68
src/libip/ptclbsum.c
Normal 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((ulong)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;
|
||||||
|
}
|
||||||
194
src/libip/readipifc.c
Normal file
194
src/libip/readipifc.c
Normal file
|
|
@ -0,0 +1,194 @@
|
||||||
|
#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;
|
||||||
|
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);
|
||||||
|
|
||||||
|
/* allocate new interface */
|
||||||
|
*l = ifc = mallocz(sizeof(Ipifc), 1);
|
||||||
|
if(ifc == nil)
|
||||||
|
return 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));
|
||||||
|
strncpy(ifc->dev, findfield("device", f, n), sizeof(ifc->dev));
|
||||||
|
ifc->dev[sizeof(ifc->dev)-1] = 0;
|
||||||
|
if(ifc->dev[0] == 0){
|
||||||
|
free(ifc);
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
ifc->mtu = strtoul(findfield("maxmtu", 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
src/libip/testreadipifc.c
Normal file
21
src/libip/testreadipifc.c
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue