--- epplets/net.c.orig Tue Jul 31 23:50:29 2001 +++ epplets/net.c Fri Aug 10 14:54:32 2001 @@ -35,6 +35,22 @@ # include # include #endif + +#ifdef __FreeBSD__ + +#include +#include + +#include +#include +#include +#include + +#include +#include + +#endif + #include "epplet.h" #include "net.h" @@ -51,6 +67,18 @@ char buff[256], **names = NULL, *s; unsigned long i; +#ifdef __FreeBSD__ + + kvm_t *kd; + struct nlist magicsymbol[] = { {"_ifnet"}, {""} }; + char name[32], type[16]; + int num; + unsigned long ifnetaddr; + struct ifnet ifnet; + struct ifnethead ifnethead; + +#endif + names = (char **) malloc(sizeof(char *)); memset(names, 0, sizeof(char *)); @@ -80,6 +108,66 @@ return (names); #elif defined(__sun__) return ((char **) NULL); +#elif defined(__FreeBSD__) + + if((kd = kvm_open(NULL, NULL, NULL, O_RDONLY, NULL)) == NULL) + { + perror("kvm_open()"); + return NULL; + } + + if(kvm_nlist(kd, magicsymbol) == -1) + { + perror("kvm_nlist()"); + kvm_close(kd); + return NULL; + } + + if(kvm_read(kd, magicsymbol[0].n_value, &ifnethead, sizeof(ifnethead)) == -1) + { + perror("kread magic"); + kvm_close(kd); + return NULL; + } + + ifnetaddr = (unsigned long)TAILQ_FIRST(&ifnethead); + + if(kvm_read(kd, ifnetaddr, &ifnet, sizeof(ifnet)) == -1) + { + perror("kvm_read ifnet\n"); + kvm_close(kd); + return NULL; + } + + num = 0; + while(ifnetaddr) + { + if(kvm_read(kd, ifnetaddr, &ifnet, sizeof(ifnet)) == -1 || + kvm_read(kd, (long)ifnet.if_name, type, 16) == -1) + { + break; + } + + type[15] = '\0'; + ifnetaddr = (unsigned long)TAILQ_NEXT(&ifnet, if_link); + + snprintf(name, 32, "%s%d", type, ifnet.if_unit); + + if((names = (char **)realloc(names, (++num + 1)*sizeof(char *))) == NULL) + return NULL; + + asprintf(&names[num-1], "%s", name); + + names[num] = NULL; + } + + kvm_close(kd); + + if(count) + *count = num; + + return names; + #else return ((char **) NULL); #endif @@ -97,6 +185,21 @@ unsigned char match = 0; FILE *fp; char buff[256], *colon = NULL, dev[64], in_str[64], out_str[64]; +#elif defined(__FreeBSD__) + + kvm_t *kd; + struct nlist magicsymbol[] = { {"_ifnet"}, {""} }; + char name[32], tname[16]; + int match, net_layer; + struct sockaddr *sa; + unsigned long ifaddraddr, ifnetaddr, ifnetfound; + struct ifnet ifnet; + struct ifnethead ifnethead; + union { + struct ifaddr ifa; + struct in_ifaddr in; + } ifaddr; + #endif if (device == NULL) { @@ -151,6 +254,104 @@ } fclose(fp); return ((match) ? (0) : (ENODEV)); +#elif defined(__FreeBSD__) + + if((kd = kvm_open(NULL, NULL, NULL, O_RDONLY, NULL)) == NULL) + { + perror("kvm_open()"); + return ENOENT; + } + + if(kvm_nlist(kd, magicsymbol) == -1) + { + perror("kvm_nlist()"); + kvm_close(kd); + return ENOENT; + } + + if(kvm_read(kd, magicsymbol[0].n_value, &ifnethead, sizeof(ifnethead)) == -1) + { + perror("kread magic"); + kvm_close(kd); + return ENOENT; + } + + ifnetaddr = (unsigned long)TAILQ_FIRST(&ifnethead); + + if(kvm_read(kd, ifnetaddr, &ifnet, sizeof(ifnet)) == -1) + { + perror("kvm_read ifnet\n"); + kvm_close(kd); + return ENOENT; + } + + ifaddraddr = 0; + while(ifnetaddr || ifaddraddr) + { + if(ifaddraddr == 0) + { + ifnetfound = ifnetaddr; + if(kvm_read(kd, ifnetaddr, &ifnet, sizeof(ifnet)) == -1 || + kvm_read(kd, (long)ifnet.if_name, tname, 16) == -1) + { + perror("kread ifnet.if_name\n"); + kvm_close(kd); + return ENOENT; + } + + tname[15] = '\0'; + ifnetaddr = (unsigned long)TAILQ_NEXT(&ifnet, if_link); + snprintf(name, 32, "%s%d", tname, ifnet.if_unit); + + if(strncasecmp(name, device, 16) != 0) + continue; + + ifaddraddr = (unsigned long)TAILQ_FIRST(&ifnet.if_addrhead); + } + + *in_bytes = (double)ifnet.if_ibytes; + *out_bytes = (double)ifnet.if_obytes; + + if(kvm_read(kd, ifaddraddr, &ifaddr, sizeof(ifaddr)) == -1) + { + printf("kread ifaddr\n"); + ifaddraddr=0; + continue; + } + + match = 1; + + sa = (struct sockaddr *)((char *)ifaddr.ifa.ifa_addr - + (char *)ifaddraddr + (char *)&ifaddr); + + switch(sa->sa_family) + { + case AF_INET: + net_layer = 1; + break; +#ifdef AF_INET6 + case AF_INET6: + net_layer = 1; + break; +#endif + default: + net_layer = 0; + } + + if(net_layer) + { + *in_bytes = (double)ifaddr.in.ia_ifa.if_ibytes; + *out_bytes = (double)ifaddr.in.ia_ifa.if_obytes; + } + + break; + } + + kvm_close(kd); + + /* XXX: errno=ENODEV; return -1; ??? */ + return (match ? 0 : ENODEV); + #else /* Unsupported platform. */ if (in_bytes != NULL) {