📄 interface_ioctl.c
字号:
/* * Interface MIB architecture support * * $Id: interface_ioctl.c,v 1.8 2004/10/17 01:52:52 rstory Exp $ */#include <net-snmp/net-snmp-config.h>#include <net-snmp/net-snmp-includes.h>#include "mibII/mibII_common.h"#include "if-mib/ifTable/ifTable_constants.h"#include <net-snmp/agent/net-snmp-agent-includes.h>#include <net-snmp/data_access/interface.h>#include "if-mib/data_access/interface.h"#ifdef HAVE_NET_IF_H#include <net/if.h>#endif#ifdef HAVE_NET_IF_ARP_H#include <net/if_arp.h>#endif#ifdef HAVE_SYS_IOCTL_H#include <sys/ioctl.h>#endif/** * ioctl wrapper * * @param fd : socket fd to use w/ioctl, or -1 to open/close one * @param ifentry : ifentry to update * * @retval 0 : success * @retval -1 : invalid parameters * @retval -2 : couldn't create socket * @retval -3 : ioctl call failed */static int_ioctl_get(int fd, int which, struct ifreq *ifrq, const char* name){ int ourfd = -1, rc = 0; DEBUGMSGTL(("verbose:access:interface:ioctl", "ioctl %d for %s\n", which, name)); /* * sanity checks */ if(NULL == name) { snmp_log(LOG_ERR, "invalid ifentry\n"); return -1; } /* * create socket for ioctls */ if(fd < 0) { fd = ourfd = socket(AF_INET, SOCK_DGRAM, 0); if(ourfd < 0) { snmp_log(LOG_ERR,"couldn't create socket\n"); return -2; } } strncpy(ifrq->ifr_name, name, sizeof(ifrq->ifr_name)); ifrq->ifr_name[ sizeof(ifrq->ifr_name)-1 ] = 0; rc = ioctl(fd, which, ifrq); if (rc < 0) { snmp_log(LOG_ERR,"ioctl %d returned %d\n", which, rc); rc = -3; } if(ourfd >= 0) close(ourfd); return rc;}#ifdef SIOCGIFHWADDR/** * interface entry physaddr ioctl wrapper * * @param fd : socket fd to use w/ioctl, or -1 to open/close one * @param ifentry : ifentry to update * * @retval 0 : success * @retval -1 : invalid parameters * @retval -2 : couldn't create socket * @retval -3 : ioctl call failed * @retval -4 : malloc error */intnetsnmp_access_interface_ioctl_physaddr_get(int fd, netsnmp_interface_entry *ifentry){ struct ifreq ifrq; int rc = 0; DEBUGMSGTL(("access:interface:ioctl", "physaddr_get\n")); if((NULL != ifentry->paddr) && (ifentry->paddr_len != IFHWADDRLEN)) { SNMP_FREE(ifentry->paddr); } if(NULL == ifentry->paddr) ifentry->paddr = malloc(IFHWADDRLEN); if(NULL == ifentry->paddr) { rc = -4; } else { /* * NOTE: this ioctl does not guarantee 6 bytes of a physaddr. * In particular, a 'sit0' interface only appears to get back * 4 bytes of sa_data. Uncomment this memset, and suddenly * the sit interface will be 0:0:0:0:?:? where ? is whatever was * in the memory before. Not sure if this memset should be done * for every ioctl, as the rest seem to work ok... */ memset(ifrq.ifr_hwaddr.sa_data, (0), IFHWADDRLEN); ifentry->paddr_len = IFHWADDRLEN; rc = _ioctl_get(fd, SIOCGIFHWADDR, &ifrq, ifentry->name); if (rc < 0) { memset(ifentry->paddr, (0), IFHWADDRLEN); rc = -3; /* msg already logged */ } else { memcpy(ifentry->paddr, ifrq.ifr_hwaddr.sa_data, IFHWADDRLEN); /* * arphrd defines vary greatly. ETHER seems to be the only common one */#ifdef ARPHRD_ETHER switch (ifrq.ifr_hwaddr.sa_family) { case ARPHRD_ETHER: ifentry->type = 6; break;#if defined(ARPHRD_TUNNEL) || defined(ARPHRD_IPGRE) || defined(ARPHRD_SIT)#ifdef ARPHRD_TUNNEL case ARPHRD_TUNNEL: case ARPHRD_TUNNEL6:#endif#ifdef ARPHRD_IPGRE case ARPHRD_IPGRE:#endif#ifdef ARPHRD_SIT case ARPHRD_SIT:#endif ifentry->type = 131; break; /* tunnel */#endif#ifdef ARPHRD_SLIP case ARPHRD_SLIP: case ARPHRD_CSLIP: case ARPHRD_SLIP6: case ARPHRD_CSLIP6: ifentry->type = 28; break; /* slip */#endif#ifdef ARPHRD_PPP case ARPHRD_PPP: ifentry->type = 23; break; /* ppp */#endif#ifdef ARPHRD_LOOPBACK case ARPHRD_LOOPBACK: ifentry->type = 24; break; /* softwareLoopback */#endif#ifdef ARPHRD_FDDI case ARPHRD_FDDI: ifentry->type = 15; break;#endif#ifdef ARPHRD_ARCNET case ARPHRD_ARCNET: ifentry->type = 35; break;#endif#ifdef ARPHRD_LOCALTLK case ARPHRD_LOCALTLK: ifentry->type = 42; break;#endif#ifdef ARPHRD_HIPPI case ARPHRD_HIPPI: ifentry->type = 47; break;#endif#ifdef ARPHRD_ATM case ARPHRD_ATM: ifentry->type = 37; break;#endif /* * XXX: more if_arp.h:ARPHRD_xxx to IANAifType mappings... */ default: DEBUGMSGTL(("access:interface:ioctl", "unknown entry type %d\n", ifrq.ifr_hwaddr.sa_family)); } /* switch */#endif /* ARPHRD_LOOPBACK */ } } return rc;}#endif /* SIOCGIFHWADDR */#ifdef SIOCGIFFLAGS/** * interface entry flags ioctl wrapper * * @param fd : socket fd to use w/ioctl, or -1 to open/close one * @param ifentry : ifentry to update * * @retval 0 : success * @retval -1 : invalid parameters * @retval -2 : couldn't create socket * @retval -3 : ioctl call failed */intnetsnmp_access_interface_ioctl_flags_get(int fd, netsnmp_interface_entry *ifentry){ struct ifreq ifrq; int rc = 0; DEBUGMSGTL(("access:interface:ioctl", "flags_get\n")); rc = _ioctl_get(fd, SIOCGIFFLAGS, &ifrq, ifentry->name); if (rc < 0) { ifentry->ns_flags &= ~NETSNMP_INTERFACE_FLAGS_HAS_IF_FLAGS; return rc; /* msg already logged */ } else { ifentry->ns_flags |= NETSNMP_INTERFACE_FLAGS_HAS_IF_FLAGS; ifentry->os_flags = ifrq.ifr_flags; /* * ifOperStatus description: * If ifAdminStatus is down(2) then ifOperStatus should be down(2). */ if(ifentry->os_flags & IFF_UP) { ifentry->admin_status = IFADMINSTATUS_UP; if(ifentry->os_flags & IFF_RUNNING) ifentry->oper_status = IFOPERSTATUS_UP; else ifentry->oper_status = IFOPERSTATUS_DOWN; } else { ifentry->admin_status = IFADMINSTATUS_DOWN; ifentry->oper_status = IFOPERSTATUS_DOWN; } } return rc;}/** * interface entry flags ioctl wrapper * * @param fd : socket fd to use w/ioctl, or -1 to open/close one * @param ifentry : ifentry to update * * @retval 0 : success * @retval -1 : invalid parameters * @retval -2 : couldn't create socket * @retval -3 : ioctl get call failed * @retval -4 : ioctl set call failed */intnetsnmp_access_interface_ioctl_flags_set(int fd, netsnmp_interface_entry *ifentry, unsigned int flags, int and_complement){ struct ifreq ifrq; int ourfd = -1, rc = 0; DEBUGMSGTL(("access:interface:ioctl", "flags_set\n")); /* * sanity checks */ if((NULL == ifentry) || (NULL == ifentry->name)) { snmp_log(LOG_ERR, "invalid ifentry\n"); return -1; } /* * create socket for ioctls */ if(fd < 0) { fd = ourfd = socket(AF_INET, SOCK_DGRAM, 0); if(ourfd < 0) { snmp_log(LOG_ERR,"couldn't create socket\n"); return -2; } } strncpy(ifrq.ifr_name, ifentry->name, sizeof(ifrq.ifr_name)); ifrq.ifr_name[ sizeof(ifrq.ifr_name)-1 ] = 0; rc = ioctl(fd, SIOCGIFFLAGS, &ifrq); if(rc < 0) { snmp_log(LOG_ERR,"error getting flags\n"); close(fd); return -3; } if(0 == and_complement) ifrq.ifr_flags |= flags; else ifrq.ifr_flags &= ~flags; rc = ioctl(fd, SIOCSIFFLAGS, &ifrq); if(rc < 0) { close(fd); snmp_log(LOG_ERR,"error setting flags\n"); ifentry->os_flags = 0; return -4; } if(ourfd >= 0) close(ourfd); ifentry->os_flags = ifrq.ifr_flags; return 0;}#endif /* SIOCGIFFLAGS */#ifdef SIOCGIFMTU/** * interface entry mtu ioctl wrapper * * @param fd : socket fd to use w/ioctl, or -1 to open/close one * @param ifentry : ifentry to update * * @retval 0 : success * @retval -1 : invalid parameters * @retval -2 : couldn't create socket * @retval -3 : ioctl call failed */intnetsnmp_access_interface_ioctl_mtu_get(int fd, netsnmp_interface_entry *ifentry){ struct ifreq ifrq; int rc = 0; DEBUGMSGTL(("access:interface:ioctl", "mtu_get\n")); rc = _ioctl_get(fd, SIOCGIFMTU, &ifrq, ifentry->name); if (rc < 0) { ifentry->mtu = 0; return rc; /* msg already logged */ } else { ifentry->mtu = ifrq.ifr_mtu; } return rc;}#endif /* SIOCGIFMTU *//** * interface entry ifIndex ioctl wrapper * * @param fd : socket fd to use w/ioctl, or -1 to open/close one * @param ifentry : ifentry to update * * @retval 0 : not found * @retval !0 : ifIndex */oidnetsnmp_access_interface_ioctl_ifindex_get(int fd, const char *name){#ifndef SIOCGIFINDEX return 0;#else struct ifreq ifrq; int rc = 0; DEBUGMSGTL(("access:interface:ioctl", "mtu_get\n")); rc = _ioctl_get(fd, SIOCGIFINDEX, &ifrq, name); if (rc < 0) return 0; return ifrq.ifr_ifindex;#endif /* SIOCGIFINDEX */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -