📄 if.c
字号:
/* * * bootpd_nis: simple BOOTP server with NIS maps support * Copyright (C) 2005 <bfleisch@users.sourceforge.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * * $Id: if.c,v 1.2 2005/03/02 20:57:24 bfleisch Exp $ * */#include "if.h"#define NETWORK_ADDR(addr, netmask) ( ((in_addr_t)(addr.s_addr)) & ((in_addr_t)(netmask.s_addr)))#define ON_SAME_NETWORK(addr1, addr2, netmask) ( (NETWORK_ADDR((addr1), (netmask)) == NETWORK_ADDR((addr2),(netmask))))#define MAX_NETWORK_INTERFACES 20static struct ifreq ireqs[MAX_NETWORK_INTERFACES];/* * lookup which network interface matches to given IP address * * WARNING: static structure returned. */struct ifreq*get_if_by_addr(const struct in_addr *addr){ struct ifconf iconf; struct ifreq *ireq; int fd; int pos; int idx; struct in_addr if_addr; struct in_addr if_netmask; iconf.ifc_len = sizeof (ireqs); iconf.ifc_req = ireqs; fd = socket(AF_INET, SOCK_DGRAM, 0); if (fd < 0) return NULL; if (ioctl(fd, SIOCGIFCONF, &iconf) <0) { perror("ioctl(SIOCGIFCONF)"); close(fd); return NULL; } pos=0; idx=0; while (pos < iconf.ifc_len) { ireq = &iconf.ifc_req[idx]; pos += sizeof(struct ifreq); idx++; if ( ireq->ifr_addr.sa_family != AF_INET) continue; memcpy ( &if_addr, &((struct sockaddr_in*)&ireq->ifr_addr)->sin_addr, sizeof(struct in_addr)); if (ioctl(fd, SIOCGIFNETMASK , ireq) !=0) { perror("ioctl(SIOCGIFNETMASK)"); continue; } memcpy ( &if_netmask, &((struct sockaddr_in*)&ireq->ifr_addr)->sin_addr, sizeof(struct in_addr)); if (ON_SAME_NETWORK(if_addr, *addr, if_netmask)) { close(fd); return ireq; } } close(fd); return NULL; /* no match */}/* * return interface information in if_info strucutre * * Warning: static structure returned */struct if_info*get_if_info(const char* if_name){ static struct if_info if_info; struct ifconf iconf; struct ifreq* ireq; int ifs; char iconf_buf[8192]; int n; struct sockaddr_in *addr; memset(&if_info, 0, sizeof( struct if_info)); ifs = socket(PF_INET, SOCK_STREAM, 0); if (ifs <=0) { log_perror(LOG_NOTICE, "socket()"); return NULL; } iconf.ifc_len = sizeof (iconf_buf); iconf.ifc_buf = iconf_buf; if (ioctl( ifs, SIOCGIFCONF, &iconf) != 0) { log_perror(LOG_NOTICE, "ioctl(SIOCGIFCONF)"); exit (1); } n=0; do { ireq= (struct ifreq*) (iconf.ifc_buf + n); n += sizeof (struct ifreq); addr = (struct sockaddr_in*) &ireq->ifr_addr; if (addr->sin_family != AF_INET) continue; if ( strcmp(ireq->ifr_name, if_name)!=0) continue; /* * interface address */ memcpy(&(if_info.if_addr), &(addr->sin_addr), sizeof(struct in_addr)); /* * interface netmask */ if (ioctl (ifs, SIOCGIFNETMASK, ireq) !=0) log_perror(LOG_NOTICE, "ioctl(SIOCGIFFLAGS)"); else { addr = (struct sockaddr_in*) &ireq->ifr_addr; memcpy(&(if_info.if_netmask), &(addr->sin_addr), sizeof(struct in_addr)); } /* * interface broadcast address */ if (ioctl (ifs, SIOCGIFBRDADDR, ireq) !=0) log_perror(LOG_NOTICE, "ioctl(SIOCGIFBRDADDR)"); else { addr = (struct sockaddr_in*) &ireq->ifr_addr; memcpy(&(if_info.if_broadcast), &(addr->sin_addr), sizeof(struct in_addr)); } n=0; break; } while (n< iconf.ifc_len); close(ifs); return (n == 0) ? &if_info : NULL;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -