[insert project logo here (125x200px max)] Navigator Mailinglists Please report any errors or ommissions you find to our `Help' mailinglist, or post a message in the Forums. Copyright and Licensing Information Snap is (c) Jonathan T. Moore, 1999-2002 and licensed under the GNU General Public License (GPL). All other parts of Splash are (c) Willem de Bruijn, 2002-2003 and licensed under the BSD Open Source License. All sourcecode is made publicly available. Acknowledgement Splash and the Splash website are hosted by SourceForge.net |
Splash - DocumentationSNMP Plus a Lightweight API for SNAP Handlingsnap-1.1-wjdb/lib/interface.cGo to the documentation of this file.00001 /* Code to manipulate interface information, shared between ifconfig and 00002 netstat. */ 00003 00004 #include "config.h" 00005 00006 #include <sys/types.h> 00007 #include <sys/socket.h> 00008 #include <sys/ioctl.h> 00009 #include <netinet/in.h> 00010 #include <net/if.h> 00011 #include <stdio.h> 00012 #include <errno.h> 00013 #include <stdlib.h> 00014 #include <string.h> 00015 #include <unistd.h> 00016 #include <ctype.h> 00017 00018 #if HAVE_AFIPX 00019 #if (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1) 00020 #include <netipx/ipx.h> 00021 #else 00022 #include "ipx.h" 00023 #endif 00024 #endif 00025 00026 #if HAVE_AFECONET 00027 #include <linux/if_ec.h> 00028 #endif 00029 00030 #include "net-support.h" 00031 #include "pathnames.h" 00032 #include "version.h" 00033 00034 #include "interface.h" 00035 #include "sockets.h" 00036 00037 int procnetdev_vsn = 1; 00038 00039 static void 00040 if_getstats(char *ifname, struct interface *ife) 00041 { 00042 FILE *f = fopen(_PATH_PROCNET_DEV, "r"); 00043 char buf[256]; 00044 char *bp; 00045 00046 if (f == NULL) 00047 return; 00048 00049 fgets(buf, 255, f); /* throw away first line of header */ 00050 fgets(buf, 255, f); 00051 00052 if (strstr(buf, "compressed")) 00053 procnetdev_vsn = 3; 00054 else 00055 if (strstr(buf, "bytes")) 00056 procnetdev_vsn = 2; 00057 00058 while (fgets(buf, 255, f)) { 00059 bp=buf; 00060 while(*bp && isspace(*bp)) 00061 bp++; 00062 if (strncmp(bp, ifname, strlen(ifname)) == 0 && 00063 bp[strlen(ifname)] == ':') { 00064 bp = strchr(bp, ':'); 00065 bp++; 00066 switch (procnetdev_vsn) { 00067 case 3: 00068 sscanf(bp, "%ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld", 00069 &ife->stats.rx_bytes, 00070 &ife->stats.rx_packets, 00071 &ife->stats.rx_errors, 00072 &ife->stats.rx_dropped, 00073 &ife->stats.rx_fifo_errors, 00074 &ife->stats.rx_frame_errors, 00075 &ife->stats.rx_compressed, 00076 &ife->stats.rx_multicast, 00077 00078 &ife->stats.tx_bytes, 00079 &ife->stats.tx_packets, 00080 &ife->stats.tx_errors, 00081 &ife->stats.tx_dropped, 00082 &ife->stats.tx_fifo_errors, 00083 &ife->stats.collisions, 00084 &ife->stats.tx_carrier_errors, 00085 &ife->stats.tx_compressed 00086 ); 00087 break; 00088 case 2: 00089 sscanf(bp, "%ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld", 00090 &ife->stats.rx_bytes, 00091 &ife->stats.rx_packets, 00092 &ife->stats.rx_errors, 00093 &ife->stats.rx_dropped, 00094 &ife->stats.rx_fifo_errors, 00095 &ife->stats.rx_frame_errors, 00096 00097 &ife->stats.tx_bytes, 00098 &ife->stats.tx_packets, 00099 &ife->stats.tx_errors, 00100 &ife->stats.tx_dropped, 00101 &ife->stats.tx_fifo_errors, 00102 &ife->stats.collisions, 00103 &ife->stats.tx_carrier_errors 00104 ); 00105 ife->stats.rx_multicast = 0; 00106 break; 00107 case 1: 00108 sscanf(bp, "%ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld", 00109 &ife->stats.rx_packets, 00110 &ife->stats.rx_errors, 00111 &ife->stats.rx_dropped, 00112 &ife->stats.rx_fifo_errors, 00113 &ife->stats.rx_frame_errors, 00114 00115 &ife->stats.tx_packets, 00116 &ife->stats.tx_errors, 00117 &ife->stats.tx_dropped, 00118 &ife->stats.tx_fifo_errors, 00119 &ife->stats.collisions, 00120 &ife->stats.tx_carrier_errors 00121 ); 00122 ife->stats.rx_bytes = 0; 00123 ife->stats.tx_bytes = 0; 00124 ife->stats.rx_multicast = 0; 00125 break; 00126 } 00127 break; 00128 } 00129 } 00130 fclose(f); 00131 } 00132 00133 /* Support for fetching an IPX address */ 00134 00135 #if HAVE_AFIPX 00136 static int ipx_getaddr(int sock, int ft, struct ifreq *ifr) 00137 { 00138 ((struct sockaddr_ipx *)&ifr->ifr_addr)->sipx_type=ft; 00139 return ioctl(sock, SIOCGIFADDR, ifr); 00140 } 00141 #endif 00142 00143 /* Fetch the interface configuration from the kernel. */ 00144 int 00145 if_fetch(char *ifname, struct interface *ife) 00146 { 00147 struct ifreq ifr; 00148 00149 memset((char *) ife, 0, sizeof(struct interface)); 00150 strcpy(ife->name, ifname); 00151 00152 strcpy(ifr.ifr_name, ifname); 00153 if (ioctl(skfd, SIOCGIFFLAGS, &ifr) < 0) return(-1); 00154 ife->flags = ifr.ifr_flags; 00155 00156 strcpy(ifr.ifr_name, ifname); 00157 if (ioctl(skfd, SIOCGIFHWADDR, &ifr) < 0) 00158 memset(ife->hwaddr, 0, 32); 00159 else 00160 memcpy(ife->hwaddr,ifr.ifr_hwaddr.sa_data,8); 00161 00162 ife->type=ifr.ifr_hwaddr.sa_family; 00163 00164 strcpy(ifr.ifr_name, ifname); 00165 if (ioctl(skfd, SIOCGIFMETRIC, &ifr) < 0) 00166 ife->metric = 0; 00167 else 00168 ife->metric = ifr.ifr_metric; 00169 00170 strcpy(ifr.ifr_name, ifname); 00171 if (ioctl(skfd, SIOCGIFMTU, &ifr) < 0) 00172 ife->mtu = 0; 00173 else 00174 ife->mtu = ifr.ifr_mtu; 00175 00176 strcpy(ifr.ifr_name, ifname); 00177 if (ioctl(skfd, SIOCGIFMAP, &ifr) < 0) 00178 memset(&ife->map, 0, sizeof(struct ifmap)); 00179 else 00180 memcpy(&ife->map,&ifr.ifr_map,sizeof(struct ifmap)); 00181 00182 strcpy(ifr.ifr_name, ifname); 00183 if (ioctl(skfd, SIOCGIFMAP, &ifr) < 0) 00184 memset(&ife->map, 0, sizeof(struct ifmap)); 00185 else 00186 ife->map = ifr.ifr_map; 00187 00188 #ifdef HAVE_TXQUEUELEN 00189 strcpy(ifr.ifr_name, ifname); 00190 if (ioctl(skfd, SIOCGIFTXQLEN, &ifr) < 0) 00191 ife->tx_queue_len = -1; /* unknown value */ 00192 else 00193 ife->tx_queue_len = ifr.ifr_qlen; 00194 #else 00195 ife->tx_queue_len = -1; /* unknown value */ 00196 #endif 00197 00198 #if HAVE_AFINET 00199 strcpy(ifr.ifr_name, ifname); 00200 if (inet_sock < 0 || ioctl(inet_sock, SIOCGIFDSTADDR, &ifr) < 0) 00201 memset(&ife->dstaddr, 0, sizeof(struct sockaddr)); 00202 else 00203 ife->dstaddr = ifr.ifr_dstaddr; 00204 00205 strcpy(ifr.ifr_name, ifname); 00206 if (inet_sock < 0 || ioctl(inet_sock, SIOCGIFBRDADDR, &ifr) < 0) 00207 memset(&ife->broadaddr, 0, sizeof(struct sockaddr)); 00208 else 00209 ife->broadaddr = ifr.ifr_broadaddr; 00210 00211 strcpy(ifr.ifr_name, ifname); 00212 if (inet_sock < 0 || ioctl(inet_sock, SIOCGIFNETMASK, &ifr) < 0) 00213 memset(&ife->netmask, 0, sizeof(struct sockaddr)); 00214 else 00215 ife->netmask = ifr.ifr_netmask; 00216 00217 strcpy(ifr.ifr_name, ifname); 00218 if (inet_sock < 0 || ioctl(inet_sock, SIOCGIFADDR, &ifr) < 0) 00219 memset(&ife->addr, 0, sizeof(struct sockaddr)); 00220 else 00221 ife->addr = ifr.ifr_addr; 00222 #endif 00223 00224 #if HAVE_AFATALK 00225 /* DDP address maybe ? */ 00226 strcpy(ifr.ifr_name, ifname); 00227 if (ddp_sock >= 0 && ioctl(ddp_sock, SIOCGIFADDR, &ifr) == 0) { 00228 ife->ddpaddr=ifr.ifr_addr; 00229 ife->has_ddp=1; 00230 } 00231 #endif 00232 00233 #if HAVE_AFIPX 00234 /* Look for IPX addresses with all framing types */ 00235 strcpy(ifr.ifr_name, ifname); 00236 if (ipx_sock >= 0) { 00237 if (!ipx_getaddr(ipx_sock, IPX_FRAME_ETHERII, &ifr)) { 00238 ife->has_ipx_bb=1; 00239 ife->ipxaddr_bb=ifr.ifr_addr; 00240 } 00241 strcpy(ifr.ifr_name, ifname); 00242 if (!ipx_getaddr(ipx_sock, IPX_FRAME_SNAP, &ifr)) { 00243 ife->has_ipx_sn=1; 00244 ife->ipxaddr_sn=ifr.ifr_addr; 00245 } 00246 strcpy(ifr.ifr_name, ifname); 00247 if(!ipx_getaddr(ipx_sock, IPX_FRAME_8023, &ifr)) { 00248 ife->has_ipx_e3=1; 00249 ife->ipxaddr_e3=ifr.ifr_addr; 00250 } 00251 strcpy(ifr.ifr_name, ifname); 00252 if(!ipx_getaddr(ipx_sock, IPX_FRAME_8022, &ifr)) { 00253 ife->has_ipx_e2=1; 00254 ife->ipxaddr_e2=ifr.ifr_addr; 00255 } 00256 } 00257 #endif 00258 00259 #if HAVE_AFECONET 00260 /* Econet address maybe? */ 00261 strcpy(ifr.ifr_name, ifname); 00262 if (ec_sock >= 0 && ioctl(ec_sock, SIOCGIFADDR, &ifr) == 0) { 00263 ife->ecaddr = ifr.ifr_addr; 00264 ife->has_econet = 1; 00265 } 00266 #endif 00267 00268 if_getstats(ifname, ife); 00269 return 0; 00270 } |