URI:
       tBSD.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       tBSD.c (2994B)
       ---
            1 #include <u.h>
            2 /* #include <everything_but_the_kitchen_sink.h> */
            3 #include <sys/socket.h>
            4 #include <netinet/in.h>
            5 #include <net/if.h>
            6 #include <sys/ioctl.h>
            7 #include <sys/sysctl.h>
            8 #include <net/ethernet.h>
            9 #include <net/if.h>
           10 #include <net/if_var.h>
           11 #include <net/if_dl.h>
           12 #include <net/if_types.h>
           13 #include <net/route.h>
           14 #include <netinet/in.h>
           15 #include <netinet/in_var.h>
           16 #include <arpa/inet.h>
           17 #include <netdb.h>
           18 #include <libc.h>
           19 #include <ip.h>
           20 
           21 static void
           22 sockaddr2ip(uchar *ip, struct sockaddr *sa)
           23 {
           24         struct sockaddr_in *sin;
           25 
           26         sin = (struct sockaddr_in*)sa;
           27         memmove(ip, v4prefix, IPaddrlen);
           28         memmove(ip+IPv4off, &sin->sin_addr, 4);
           29 }
           30 
           31 Ipifc*
           32 readipifc(char *net, Ipifc *ifc, int index)
           33 {
           34         char *p, *ep, *q, *bp;
           35         int i, mib[6];
           36         size_t n;
           37         Ipifc *list, **last;
           38         Iplifc *lifc, **lastlifc;
           39         struct if_msghdr *mh, *nmh;
           40         struct ifa_msghdr *ah;
           41         struct sockaddr *sa;
           42         struct sockaddr_dl *sdl;
           43         uchar ip[IPaddrlen];
           44 
           45         USED(net);
           46 
           47         free(ifc);
           48         ifc = nil;
           49         list = nil;
           50         last = &list;
           51 
           52         /*
           53          * Does not handle IPv6 yet.
           54          */
           55 
           56         mib[0] = CTL_NET;
           57         mib[1] = PF_ROUTE;
           58         mib[2] = 0;
           59         mib[3] = 0;
           60         mib[4] = NET_RT_IFLIST;
           61         mib[5] = 0;
           62 
           63         n = 0;
           64         if(sysctl(mib, 6, nil, &n, nil, 0) < 0)
           65                 return nil;
           66         bp = mallocz(n, 1);
           67         if(bp == nil)
           68                 return nil;
           69         if(sysctl(mib, 6, bp, &n, nil, 0) < 0){
           70                 free(bp);
           71                 return nil;
           72         }
           73 
           74         p = bp;
           75         ep = p+n;
           76         while(p < ep){
           77                 mh = (struct if_msghdr*)p;
           78                 p += mh->ifm_msglen;
           79                 if(mh->ifm_type != RTM_IFINFO)
           80                         continue;
           81                 ifc = mallocz(sizeof *ifc, 1);
           82                 if(ifc == nil)
           83                         break;
           84                 *last = ifc;
           85                 last = &ifc->next;
           86                 sdl = (struct sockaddr_dl*)(mh+1);
           87                 n = sdl->sdl_nlen;
           88                 if(n >= sizeof ifc->dev)
           89                         n = sizeof ifc->dev - 1;
           90                 memmove(ifc->dev, sdl->sdl_data, n);
           91                 ifc->dev[n] = 0;
           92                 ifc->rp.linkmtu = mh->ifm_data.ifi_mtu;
           93                 lastlifc = &ifc->lifc;
           94 
           95                 if(sdl->sdl_type == IFT_ETHER && sdl->sdl_alen == 6)
           96                         memmove(ifc->ether, LLADDR(sdl), 6);
           97 
           98                 while(p < ep){
           99                         ah = (struct ifa_msghdr*)p;
          100                         nmh = (struct if_msghdr*)p;
          101                         if(nmh->ifm_type != RTM_NEWADDR)
          102                                 break;
          103                         p += nmh->ifm_msglen;
          104                         lifc = nil;
          105                         for(i=0, q=(char*)(ah+1); i<RTAX_MAX && q<p; i++){
          106                                 if(!(ah->ifam_addrs & (1<<i)))
          107                                         continue;
          108                                 sa = (struct sockaddr*)q;
          109                                 q += (sa->sa_len+sizeof(long)-1) & ~(sizeof(long)-1);
          110                                 if(sa->sa_family != AF_INET)
          111                                         continue;
          112                                 if(lifc == nil){
          113                                         lifc = mallocz(sizeof *lifc, 1);
          114                                         if(lifc == nil)
          115                                                 continue;
          116                                         *lastlifc = lifc;
          117                                         lastlifc = &lifc->next;
          118                                 }
          119                                 sockaddr2ip(ip, sa);
          120                                 switch(i){
          121                                 case RTAX_IFA:
          122                                         ipmove(lifc->ip, ip);
          123                                         break;
          124                                 case RTAX_NETMASK:
          125                                         memset(ip, 0xFF, IPv4off);
          126                                         ipmove(lifc->mask, ip);
          127                                         break;
          128                                 case RTAX_BRD:
          129                                         if(mh->ifm_flags & IFF_POINTOPOINT)
          130                                                 /* ipmove(lifc->remote, ip) */ ;
          131                                         if(mh->ifm_flags & IFF_BROADCAST)
          132                                                 /* ipmove(lifc->bcast, ip) */ ;
          133                                         break;
          134                                 case RTAX_GATEWAY:
          135                                         break;
          136                                 case RTAX_DST:
          137                                         break;
          138                                 }
          139                         }
          140                         if(lifc)
          141                                 maskip(lifc->ip, lifc->mask, lifc->net);
          142                 }
          143         }
          144         free(bp);
          145         return list;
          146 }