new
This commit is contained in:
parent
9fe7e1a14c
commit
9aec88f29c
12 changed files with 493 additions and 232 deletions
1
src/libip/Darwin.c
Normal file
1
src/libip/Darwin.c
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
#include "none.c"
|
||||||
144
src/libip/FreeBSD.c
Normal file
144
src/libip/FreeBSD.c
Normal file
|
|
@ -0,0 +1,144 @@
|
||||||
|
#include <u.h>
|
||||||
|
/* #include <everything_but_the_kitchen_sink.h> */
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <net/if.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/module.h>
|
||||||
|
#include <sys/sysctl.h>
|
||||||
|
#include <net/ethernet.h>
|
||||||
|
#include <net/if.h>
|
||||||
|
#include <net/if_var.h>
|
||||||
|
#include <net/if_dl.h>
|
||||||
|
#include <net/if_types.h>
|
||||||
|
#include <net/route.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <netinet/in_var.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#include <ip.h>
|
||||||
|
|
||||||
|
static void
|
||||||
|
sockaddr2ip(uchar *ip, struct sockaddr *sa)
|
||||||
|
{
|
||||||
|
struct sockaddr_in *sin;
|
||||||
|
|
||||||
|
sin = (struct sockaddr_in*)sa;
|
||||||
|
memmove(ip, v4prefix, IPaddrlen);
|
||||||
|
memmove(ip+IPv4off, &sin->sin_addr, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ipifc*
|
||||||
|
readipifc(char *net, Ipifc *ifc, int index)
|
||||||
|
{
|
||||||
|
char *p, *ep, *q;
|
||||||
|
int i, mib[6], n, alloc;
|
||||||
|
Ipifc *list, **last;
|
||||||
|
Iplifc *lifc, **lastlifc;
|
||||||
|
struct if_msghdr *mh, *nmh;
|
||||||
|
struct ifa_msghdr *ah;
|
||||||
|
struct sockaddr *sa;
|
||||||
|
struct sockaddr_dl *sdl;
|
||||||
|
uchar ip[IPaddrlen];
|
||||||
|
|
||||||
|
USED(net);
|
||||||
|
|
||||||
|
free(ifc);
|
||||||
|
ifc = nil;
|
||||||
|
list = nil;
|
||||||
|
last = &list;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Does not handle IPv6 yet.
|
||||||
|
*/
|
||||||
|
|
||||||
|
mib[0] = CTL_NET;
|
||||||
|
mib[1] = PF_ROUTE;
|
||||||
|
mib[2] = 0;
|
||||||
|
mib[3] = 0;
|
||||||
|
mib[4] = NET_RT_IFLIST;
|
||||||
|
mib[5] = 0;
|
||||||
|
|
||||||
|
if(sysctl(mib, 6, nil, &n, nil, 0) < 0)
|
||||||
|
return nil;
|
||||||
|
p = mallocz(n, 1);
|
||||||
|
if(p == nil)
|
||||||
|
return nil;
|
||||||
|
if(sysctl(mib, 6, p, &n, nil, 0) < 0){
|
||||||
|
free(p);
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
ep = p+n;
|
||||||
|
while(p < ep){
|
||||||
|
mh = (struct if_msghdr*)p;
|
||||||
|
p += mh->ifm_msglen;
|
||||||
|
if(mh->ifm_type != RTM_IFINFO)
|
||||||
|
continue;
|
||||||
|
ifc = mallocz(sizeof *ifc, 1);
|
||||||
|
if(ifc == nil)
|
||||||
|
break;
|
||||||
|
*last = ifc;
|
||||||
|
last = &ifc->next;
|
||||||
|
sdl = (struct sockaddr_dl*)(mh+1);
|
||||||
|
n = sdl->sdl_nlen;
|
||||||
|
if(n >= sizeof ifc->dev)
|
||||||
|
n = sizeof ifc->dev - 1;
|
||||||
|
memmove(ifc->dev, sdl->sdl_data, n);
|
||||||
|
ifc->dev[n] = 0;
|
||||||
|
ifc->rp.linkmtu = mh->ifm_data.ifi_mtu;
|
||||||
|
lastlifc = &ifc->lifc;
|
||||||
|
|
||||||
|
while(p < ep){
|
||||||
|
ah = (struct ifa_msghdr*)p;
|
||||||
|
nmh = (struct if_msghdr*)p;
|
||||||
|
if(nmh->ifm_type != RTM_NEWADDR)
|
||||||
|
break;
|
||||||
|
p += nmh->ifm_msglen;
|
||||||
|
alloc = 0;
|
||||||
|
for(i=0, q=(char*)(ah+1); i<RTAX_MAX && q<p; i++){
|
||||||
|
if(!(ah->ifam_addrs & (1<<i)))
|
||||||
|
continue;
|
||||||
|
sa = (struct sockaddr*)q;
|
||||||
|
q += (sa->sa_len+sizeof(long)-1) & ~(sizeof(long)-1);
|
||||||
|
|
||||||
|
if(sa->sa_family == AF_LINK && i == RTAX_IFA){
|
||||||
|
struct sockaddr_dl *e;
|
||||||
|
|
||||||
|
if(e->sdl_type == IFT_ETHER && e->sdl_alen == 6)
|
||||||
|
memmove(ifc->ether, LLADDR(e), 6);
|
||||||
|
}
|
||||||
|
if(sa->sa_family != AF_INET)
|
||||||
|
continue;
|
||||||
|
if(alloc == 0){
|
||||||
|
alloc = 1;
|
||||||
|
lifc = mallocz(sizeof *lifc, 1);
|
||||||
|
*lastlifc = lifc;
|
||||||
|
lastlifc = &lifc->next;
|
||||||
|
}
|
||||||
|
sockaddr2ip(ip, sa);
|
||||||
|
switch(i){
|
||||||
|
case RTAX_IFA:
|
||||||
|
ipmove(lifc->ip, ip);
|
||||||
|
break;
|
||||||
|
case RTAX_NETMASK:
|
||||||
|
memset(ip, 0xFF, IPv4off);
|
||||||
|
ipmove(lifc->mask, ip);
|
||||||
|
break;
|
||||||
|
case RTAX_BRD:
|
||||||
|
if(mh->ifm_flags & IFF_POINTOPOINT)
|
||||||
|
/* ipmove(lifc->remote, ip) */ ;
|
||||||
|
if(mh->ifm_flags & IFF_BROADCAST)
|
||||||
|
/* ipmove(lifc->bcast, ip) */ ;
|
||||||
|
break;
|
||||||
|
case RTAX_GATEWAY:
|
||||||
|
break;
|
||||||
|
case RTAX_DST:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
maskip(lifc->ip, lifc->mask, lifc->net);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
254
src/libip/Linux.c
Normal file
254
src/libip/Linux.c
Normal file
|
|
@ -0,0 +1,254 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <asm/types.h>
|
||||||
|
#include <net/if_arp.h>
|
||||||
|
#include <linux/netlink.h>
|
||||||
|
#include <linux/rtnetlink.h>
|
||||||
|
#include <net/if.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#include <ip.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Use netlink sockets to find interfaces.
|
||||||
|
* Thanks to Erik Quanstrom.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
netlinkrequest(int fd, int type, int (*fn)(struct nlmsghdr *h, Ipifc**, int),
|
||||||
|
Ipifc **ifc, int index)
|
||||||
|
{
|
||||||
|
char buf[1024];
|
||||||
|
int n;
|
||||||
|
struct sockaddr_nl nl;
|
||||||
|
struct {
|
||||||
|
struct nlmsghdr nlh;
|
||||||
|
struct rtgenmsg g;
|
||||||
|
} req;
|
||||||
|
struct nlmsghdr *h;
|
||||||
|
|
||||||
|
memset(&nl, 0, sizeof nl);
|
||||||
|
nl.nl_family = AF_NETLINK;
|
||||||
|
|
||||||
|
memset(&req, 0, sizeof req);
|
||||||
|
req.nlh.nlmsg_len = sizeof req;
|
||||||
|
req.nlh.nlmsg_type = type;
|
||||||
|
req.nlh.nlmsg_flags = NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST;
|
||||||
|
req.nlh.nlmsg_pid = 0;
|
||||||
|
req.nlh.nlmsg_seq = 1;
|
||||||
|
req.g.rtgen_family = AF_NETLINK;
|
||||||
|
|
||||||
|
if(sendto(fd, (void*)&req, sizeof req, 0, (struct sockaddr*)&nl, sizeof nl) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
while((n=read(fd, buf, sizeof buf)) > 0){
|
||||||
|
for(h=(struct nlmsghdr*)buf; NLMSG_OK(h, n); h = NLMSG_NEXT(h, n)){
|
||||||
|
if(h->nlmsg_type == NLMSG_DONE)
|
||||||
|
return 0;
|
||||||
|
if(h->nlmsg_type == NLMSG_ERROR){
|
||||||
|
werrstr("netlink error");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if(fn(h, ifc, index) < 0)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
werrstr("netlink error");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
devsocket(void)
|
||||||
|
{
|
||||||
|
/* we couldn't care less which one; just want to talk to the kernel! */
|
||||||
|
static int dumb[3] = { AF_INET, AF_PACKET, AF_INET6 };
|
||||||
|
int i, fd;
|
||||||
|
|
||||||
|
for(i=0; i<nelem(dumb); i++)
|
||||||
|
if((fd = socket(dumb[i], SOCK_DGRAM, 0)) >= 0)
|
||||||
|
return fd;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
parsertattr(struct rtattr **dst, int ndst, struct nlmsghdr *h, int type, int skip)
|
||||||
|
{
|
||||||
|
struct rtattr *src;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
len = h->nlmsg_len - NLMSG_LENGTH(skip);
|
||||||
|
if(len < 0 || h->nlmsg_type != type){
|
||||||
|
werrstr("attrs too short");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
src = (struct rtattr*)((char*)NLMSG_DATA(h) + NLMSG_ALIGN(skip));
|
||||||
|
|
||||||
|
memset(dst, 0, ndst*sizeof dst[0]);
|
||||||
|
for(; RTA_OK(src, len); src = RTA_NEXT(src, len))
|
||||||
|
if(src->rta_type < ndst)
|
||||||
|
dst[src->rta_type] = src;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
rta2ip(int af, uchar *ip, struct rtattr *rta)
|
||||||
|
{
|
||||||
|
memset(ip, 0, IPaddrlen);
|
||||||
|
|
||||||
|
switch(af){
|
||||||
|
case AF_INET:
|
||||||
|
memmove(ip, v4prefix, IPv4off);
|
||||||
|
memmove(ip+IPv4off, RTA_DATA(rta), IPv4addrlen);
|
||||||
|
break;
|
||||||
|
case AF_INET6:
|
||||||
|
memmove(ip, RTA_DATA(rta), IPaddrlen);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
getlink(struct nlmsghdr *h, Ipifc **ipifclist, int index)
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
int fd;
|
||||||
|
struct rtattr *attr[IFLA_MAX+1];
|
||||||
|
struct ifinfomsg *ifi;
|
||||||
|
Ipifc *ifc;
|
||||||
|
|
||||||
|
ifi = (struct ifinfomsg*)NLMSG_DATA(h);
|
||||||
|
if(index >= 0 && ifi->ifi_index != index)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
ifc = mallocz(sizeof *ifc, 1);
|
||||||
|
if(ifc == nil)
|
||||||
|
return -1;
|
||||||
|
ifc->index = ifi->ifi_index;
|
||||||
|
|
||||||
|
while(*ipifclist)
|
||||||
|
ipifclist = &(*ipifclist)->next;
|
||||||
|
*ipifclist = ifc;
|
||||||
|
|
||||||
|
if(parsertattr(attr, nelem(attr), h, RTM_NEWLINK, sizeof(struct ifinfomsg)) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if(attr[IFLA_IFNAME])
|
||||||
|
p = (char*)RTA_DATA(attr[IFLA_IFNAME]);
|
||||||
|
else
|
||||||
|
p = "nil";
|
||||||
|
strecpy(ifc->dev, ifc->dev+sizeof ifc->dev, p);
|
||||||
|
|
||||||
|
if(attr[IFLA_MTU])
|
||||||
|
ifc->mtu = *(int*)RTA_DATA(attr[IFLA_MTU]);
|
||||||
|
|
||||||
|
if(attr[IFLA_STATS]){
|
||||||
|
struct rtnl_link_stats *s;
|
||||||
|
|
||||||
|
s = RTA_DATA(attr[IFLA_STATS]);
|
||||||
|
ifc->pktin = s->rx_packets;
|
||||||
|
ifc->pktout = s->tx_packets;
|
||||||
|
ifc->errin = s->rx_errors;
|
||||||
|
ifc->errout = s->tx_errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((fd = devsocket()) > 0){
|
||||||
|
struct ifreq ifr;
|
||||||
|
|
||||||
|
memset(&ifr, 0, sizeof ifr);
|
||||||
|
strncpy(ifr.ifr_name, p, IFNAMSIZ);
|
||||||
|
ifr.ifr_mtu = 0;
|
||||||
|
if(ioctl(fd, SIOCGIFMTU, &ifr) >= 0)
|
||||||
|
ifc->rp.linkmtu = ifr.ifr_mtu;
|
||||||
|
|
||||||
|
memset(&ifr, 0, sizeof ifr);
|
||||||
|
strncpy(ifr.ifr_name, p, IFNAMSIZ);
|
||||||
|
if(ioctl(fd, SIOCGIFHWADDR, &ifr) >= 0
|
||||||
|
&& ifr.ifr_hwaddr.sa_family == ARPHRD_ETHER)
|
||||||
|
memmove(ifc->ether, ifr.ifr_hwaddr.sa_data, 6);
|
||||||
|
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
getaddr(struct nlmsghdr *h, Ipifc **ipifclist, int index)
|
||||||
|
{
|
||||||
|
int mask;
|
||||||
|
Ipifc *ifc;
|
||||||
|
Iplifc *lifc, **l;
|
||||||
|
struct ifaddrmsg *ifa;
|
||||||
|
struct rtattr *attr[IFA_MAX+1];
|
||||||
|
|
||||||
|
USED(index);
|
||||||
|
|
||||||
|
ifa = (struct ifaddrmsg*)NLMSG_DATA(h);
|
||||||
|
for(ifc=*ipifclist; ifc; ifc=ifc->next)
|
||||||
|
if(ifc->index == ifa->ifa_index)
|
||||||
|
break;
|
||||||
|
if(ifc == nil)
|
||||||
|
return 0;
|
||||||
|
if(parsertattr(attr, nelem(attr), h, RTM_NEWADDR, sizeof(struct ifaddrmsg)) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
lifc = mallocz(sizeof *lifc, 1);
|
||||||
|
if(lifc == nil)
|
||||||
|
return -1;
|
||||||
|
for(l=&ifc->lifc; *l; l=&(*l)->next)
|
||||||
|
;
|
||||||
|
*l = lifc;
|
||||||
|
|
||||||
|
if(attr[IFA_ADDRESS] == nil)
|
||||||
|
attr[IFA_ADDRESS] = attr[IFA_LOCAL];
|
||||||
|
if(attr[IFA_ADDRESS] == nil)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
rta2ip(ifa->ifa_family, lifc->ip, attr[IFA_ADDRESS]);
|
||||||
|
|
||||||
|
mask = ifa->ifa_prefixlen/8;
|
||||||
|
if(ifa->ifa_family == AF_INET)
|
||||||
|
mask += IPv4off;
|
||||||
|
memset(lifc->mask, 0xFF, mask);
|
||||||
|
memmove(lifc->net, lifc->ip, mask);
|
||||||
|
|
||||||
|
if(attr[IFA_CACHEINFO]){
|
||||||
|
struct ifa_cacheinfo *ci;
|
||||||
|
|
||||||
|
ci = RTA_DATA(attr[IFA_CACHEINFO]);
|
||||||
|
lifc->preflt = ci->ifa_prefered;
|
||||||
|
lifc->validlt = ci->ifa_valid;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ipifc*
|
||||||
|
readipifc(char *net, Ipifc *ifc, int index)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
USED(net);
|
||||||
|
freeipifc(ifc);
|
||||||
|
ifc = nil;
|
||||||
|
|
||||||
|
fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
|
||||||
|
if(fd < 0)
|
||||||
|
return nil;
|
||||||
|
ifc = nil;
|
||||||
|
if(netlinkrequest(fd, RTM_GETLINK, getlink, &ifc, index) < 0
|
||||||
|
|| netlinkrequest(fd, RTM_GETADDR, getaddr, &ifc, index) < 0){
|
||||||
|
close(fd);
|
||||||
|
freeipifc(ifc);
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
close(fd);
|
||||||
|
return ifc;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
_myetheraddr(uchar *to, char *dev)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
struct ifreq ifr;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
1
src/libip/NetBSD.c
Normal file
1
src/libip/NetBSD.c
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
#include "none.c"
|
||||||
1
src/libip/OpenBSD.c
Normal file
1
src/libip/OpenBSD.c
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
#include "none.c"
|
||||||
1
src/libip/SunOS.c
Normal file
1
src/libip/SunOS.c
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
#include "none.c"
|
||||||
20
src/libip/freeipifc.c
Normal file
20
src/libip/freeipifc.c
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#include <ip.h>
|
||||||
|
|
||||||
|
void
|
||||||
|
freeipifc(Ipifc *i)
|
||||||
|
{
|
||||||
|
Ipifc *next;
|
||||||
|
Iplifc *l, *lnext;
|
||||||
|
|
||||||
|
for(; i; i=next){
|
||||||
|
next = i->next;
|
||||||
|
for(l=i->lifc; l; l=lnext){
|
||||||
|
lnext = l->next;
|
||||||
|
free(l);
|
||||||
|
}
|
||||||
|
free(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -5,14 +5,14 @@ OFILES=\
|
||||||
bo.$O\
|
bo.$O\
|
||||||
classmask.$O\
|
classmask.$O\
|
||||||
eipfmt.$O\
|
eipfmt.$O\
|
||||||
|
freeipifc.$O\
|
||||||
ipaux.$O\
|
ipaux.$O\
|
||||||
myetheraddr.$O\
|
|
||||||
myipaddr.$O\
|
myipaddr.$O\
|
||||||
parseether.$O\
|
parseether.$O\
|
||||||
parseip.$O\
|
parseip.$O\
|
||||||
ptclbsum.$O\
|
ptclbsum.$O\
|
||||||
readipifc.$O\
|
|
||||||
udp.$O\
|
udp.$O\
|
||||||
|
$SYSNAME.$O\
|
||||||
|
|
||||||
HFILES=\
|
HFILES=\
|
||||||
ip.h
|
ip.h
|
||||||
|
|
|
||||||
|
|
@ -2,40 +2,25 @@
|
||||||
#include <libc.h>
|
#include <libc.h>
|
||||||
#include <ip.h>
|
#include <ip.h>
|
||||||
|
|
||||||
|
static char zea[6];
|
||||||
|
|
||||||
int
|
int
|
||||||
myetheraddr(uchar *to, char *dev)
|
myetheraddr(uchar *to, char *dev)
|
||||||
{
|
{
|
||||||
int n, fd;
|
Ipifc *ifclist, *ifc;
|
||||||
char buf[256], *ptr;
|
|
||||||
|
ifclist = readipifc(nil, nil, -1);
|
||||||
/* Make one exist */
|
for(ifc=ifclist; ifc; ifc=ifc->next){
|
||||||
if(*dev == '/')
|
if(dev && strcmp(ifc->dev) != 0)
|
||||||
sprint(buf, "%s/clone", dev);
|
continue;
|
||||||
else
|
if(memcmp(zea, ifc->ether, 6) == 0)
|
||||||
sprint(buf, "/net/%s/clone", dev);
|
continue;
|
||||||
fd = open(buf, ORDWR);
|
memmove(to, ifc->ether, 6);
|
||||||
if(fd >= 0)
|
freeipifc(ifclist);
|
||||||
close(fd);
|
return 0;
|
||||||
|
}
|
||||||
if(*dev == '/')
|
freeipifc(ifclist);
|
||||||
sprint(buf, "%s/0/stats", dev);
|
werrstr("no ethernet devices");
|
||||||
else
|
return -1;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,20 +2,44 @@
|
||||||
#include <libc.h>
|
#include <libc.h>
|
||||||
#include <ip.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
|
int
|
||||||
myipaddr(uchar *ip, char *net)
|
myipaddr(uchar *ip, char *net)
|
||||||
{
|
{
|
||||||
Ipifc *nifc;
|
Ipifc *nifc;
|
||||||
Iplifc *lifc;
|
Iplifc *lifc;
|
||||||
static Ipifc *ifc;
|
Ipifc *ifc;
|
||||||
|
uchar mynet[IPaddrlen];
|
||||||
|
|
||||||
ifc = readipifc(net, ifc, -1);
|
ifc = readipifc(net, nil, -1);
|
||||||
for(nifc = ifc; nifc; nifc = nifc->next)
|
for(nifc = ifc; nifc; nifc = nifc->next)
|
||||||
for(lifc = nifc->lifc; lifc; lifc = lifc->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){
|
if(ipcmp(lifc->ip, IPnoaddr) != 0){
|
||||||
ipmove(ip, lifc->ip);
|
ipmove(ip, lifc->ip);
|
||||||
|
freeipifc(ifc);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
ipmove(ip, IPnoaddr);
|
ipmove(ip, IPnoaddr);
|
||||||
|
freeipifc(ifc);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
24
src/libip/none.c
Normal file
24
src/libip/none.c
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#include <ip.h>
|
||||||
|
|
||||||
|
Ipifc*
|
||||||
|
readipifc(char *net, Ipifc *ipifc, int index)
|
||||||
|
{
|
||||||
|
USED(net);
|
||||||
|
USED(ipifc);
|
||||||
|
USED(index);
|
||||||
|
|
||||||
|
werrstr("not implemented");
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
myetheraddr(uchar *to, char *dev)
|
||||||
|
{
|
||||||
|
USED(to);
|
||||||
|
USED(dev);
|
||||||
|
|
||||||
|
werrstr("not implemented");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
@ -1,194 +0,0 @@
|
||||||
#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;
|
|
||||||
}
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue