rsc | 1237836 | 2005-12-31 20:02:45 +0000 | [diff] [blame] | 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 | } |