[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

SourceForge.net Logo

osi-open source certified logo

Splash - Documentation

SNMP Plus a Lightweight API for SNAP Handling

Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals  

snap-1.1-wjdb/lib/interface.c

Go 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 }