📄 libnet_if_addr.c
字号:
/* * $Id: libnet_if_addr.c,v 1.9 2003/10/18 17:33:10 mike Exp $ * * libnet * libnet_if_addr.c - interface selection code * * Copyright (c) 1998 - 2003 Mike D. Schiffman <mike@infonexus.com> * Originally pulled from traceroute sources. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * */#if (HAVE_CONFIG_H)#include "../include/config.h"#endif#if (!(_WIN32) || (__CYGWIN__))
#include "../include/libnet.h"
#else
#include "../include/win32/libnet.h"
#endif#ifdef HAVE_SYS_SOCKIO_H#include <sys/sockio.h>#endif#include "../include/ifaddrlist.h"#define MAX_IPADDR 32#if !(__WIN32__)/* * Return the interface list */intlibnet_ifaddrlist(register struct libnet_ifaddr_list **ipaddrp, int8_t *dev, register int8_t *errbuf){ register int fd, nipaddr;#ifdef HAVE_SOCKADDR_SA_LEN register int n;#endif register struct ifreq *ifrp, *ifend, *ifnext, *mp; register struct sockaddr_in *sin; register struct libnet_ifaddr_list *al; struct ifconf ifc; struct ifreq ibuf[MAX_IPADDR], ifr; int8_t device[sizeof(ifr.ifr_name)]; static struct libnet_ifaddr_list ifaddrlist[MAX_IPADDR]; fd = socket(AF_INET, SOCK_DGRAM, 0); if (fd < 0) { snprintf(errbuf, LIBNET_ERRBUF_SIZE, "socket: %s", strerror(errno)); return (-1); } memset(&ifc, 0, sizeof(ifc)); ifc.ifc_len = sizeof(ibuf); ifc.ifc_buf = (caddr_t)ibuf; if (ioctl(fd, SIOCGIFCONF, (int8_t *)&ifc) < 0 || ifc.ifc_len < sizeof(struct ifreq)) { snprintf(errbuf, LIBNET_ERRBUF_SIZE, "SIOCGIFCONF: %s", strerror(errno)); close(fd); return (-1); } ifrp = ibuf; ifend = (struct ifreq *)((int8_t *)ibuf + ifc.ifc_len); al = ifaddrlist; mp = NULL; nipaddr = 0; for (; ifrp < ifend; ifrp = ifnext) {#ifdef HAVE_SOCKADDR_SA_LEN n = ifrp->ifr_addr.sa_len + sizeof(ifrp->ifr_name); if (n < sizeof(*ifrp)) { ifnext = ifrp + 1; } else { ifnext = (struct ifreq *)((int8_t *)ifrp + n); } if (ifrp->ifr_addr.sa_family != AF_INET) continue;#else ifnext = ifrp + 1;#endif /* * Need a template to preserve address info that is * used below to locate the next entry. (Otherwise, * SIOCGIFFLAGS stomps over it because the requests * are returned in a union.) */ strncpy(ifr.ifr_name, ifrp->ifr_name, sizeof(ifr.ifr_name) -1); ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = '\0'; if (ioctl(fd, SIOCGIFFLAGS, (int8_t *)&ifr) < 0) { if (errno == ENXIO) continue; snprintf(errbuf, LIBNET_ERRBUF_SIZE, "SIOCGIFFLAGS: %.*s: %s", (int)sizeof(ifr.ifr_name), ifr.ifr_name, strerror(errno)); close(fd); return (-1); } /* first make sure it's up */ if ((ifr.ifr_flags & IFF_UP) == 0) { continue; } /* then we'll ignore loopback if device was NULL */ if (dev == NULL && LIBNET_ISLOOPBACK(&ifr)) { continue; } strncpy(device, ifr.ifr_name, sizeof(ifr.ifr_name) -1); device[sizeof(device) - 1] = '\0'; if (ioctl(fd, SIOCGIFADDR, (int8_t *)&ifr) < 0) { snprintf(errbuf, LIBNET_ERRBUF_SIZE, "SIOCGIFADDR: %s: %s", device, strerror(errno)); close(fd); return (-1); } sin = (struct sockaddr_in *)&ifr.ifr_addr; al->addr = sin->sin_addr.s_addr; /* * Replaced savestr() with strdup(). -- MDS */ al->device = strdup(device); ++al; ++nipaddr; } close(fd); *ipaddrp = ifaddrlist; return (nipaddr);}#else
/* From tcptraceroute, convert a numeric IP address to a string */
#define IPTOSBUFFERS 12
int8_t *iptos(u_int32_t in)
{
static int8_t output[IPTOSBUFFERS][3*4+3+1];
static int16_t which;
u_int8_t *p;
p = (u_int8_t *)∈
which = (which + 1 == IPTOSBUFFERS ? 0 : which + 1);
snprintf(output[which],IPTOSBUFFERS, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
return output[which];
}
intlibnet_ifaddrlist(register struct libnet_ifaddr_list **ipaddrp, int8_t *dev, register int8_t *errbuf){
int nipaddr = 0;
int i = 0;
static struct libnet_ifaddr_list ifaddrlist[MAX_IPADDR];
pcap_if_t *alldevs;
pcap_if_t *d;
int8_t err[PCAP_ERRBUF_SIZE];
/* Retrieve the interfaces list */
if (pcap_findalldevs(&alldevs, err) == -1)
{
snprintf(errbuf, LIBNET_ERRBUF_SIZE, "Error in pcap_findalldevs: %s", err);
return(-1);
}
/* Scan the list printing every entry */
for(d=alldevs;d;d=d->next)
{
if (d->addresses->addr->sa_family != AF_INET)
{
continue;
}
if (d->flags & PCAP_IF_LOOPBACK)
{
continue;
}
ifaddrlist[i].device = strdup(d->name);
ifaddrlist[i].addr = strdup(iptos(((struct sockaddr_in *)d->addresses->addr)->sin_addr.s_addr));
++i;
++nipaddr;
}
*ipaddrp = ifaddrlist;
return (nipaddr);}#endif /* __WIN32__ */intlibnet_select_device(libnet_t *l){ int c, i; int8_t err_buf[LIBNET_ERRBUF_SIZE]; struct libnet_ifaddr_list *address_list, *al; u_int32_t addr; if (l == NULL) { return (-1); } /* * Number of interfaces. */ c = libnet_ifaddrlist(&address_list, l->device, err_buf); if (c < 0) { snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "ifaddrlist : %s\n", err_buf); return (-1); } else if (c == 0) { snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "No network interfaces found.\n"); return (-1); } al = address_list; if (l->device) { /* * If the device was specified as an IP address, find the first * device that matches it. */ if (isdigit(l->device[0])) { /* on error this will be -1 */ addr = libnet_name2addr4(l, l->device, 0); } else { addr = -1; } for (i = c; i; --i, ++address_list) { if (((addr == -1) && !(strncmp(l->device, address_list->device, strlen(l->device)))) || (address_list->addr == addr)) { /* free the "user supplied device" - see libnet_init() */ free(l->device); l->device = strdup(address_list->device); goto good; } } if (i <= 0) { snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): can't find interface %s\n", __func__, l->device); goto bad; } } else { l->device = strdup(address_list->device); }good: for (i = 0; i < c; i++) { free(al[i].device); } return (1);bad: for (i = 0; i < c; i++) { free(al[i].device); } return (-1);}/* EOF */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -