📄 inet.c
字号:
/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- *//* * Copyright (c) 1994, 1995, 1996, 1997, 1998 * The Regents of the University of California. 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. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the Computer Systems * Engineering Group at Lawrence Berkeley Laboratory. * 4. Neither the name of the University nor of the Laboratory may be used * to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. */#ifndef lintstatic const char rcsid[] _U_ = "@(#) $Header: /tcpdump/master/libpcap/inet.c,v 1.58.2.1 2003/11/15 23:26:41 guy Exp $ (LBL)";#endif#ifdef HAVE_CONFIG_H#include "config.h"#endif#ifdef WIN32#include <pcap-stdinc.h>#else /* WIN32 */#include <sys/param.h>#include <sys/file.h>#include <sys/ioctl.h>#include <sys/socket.h>#ifdef HAVE_SYS_SOCKIO_H#include <sys/sockio.h>#endif#include <sys/time.h> /* concession to AIX */struct mbuf; /* Squelch compiler warnings on some platforms for */struct rtentry; /* declarations in <net/if.h> */#include <net/if.h>#include <netinet/in.h>#endif /* WIN32 */#include <ctype.h>#include <errno.h>#include <memory.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#ifndef WIN32#include <unistd.h>#endif /* WIN32 */#ifdef HAVE_LIMITS_H#include <limits.h>#else#define INT_MAX 2147483647#endif#ifdef HAVE_IFADDRS_H#include <ifaddrs.h>#endif#include "pcap-int.h"#ifdef HAVE_OS_PROTO_H#include "os-proto.h"#endif/* Not all systems have IFF_LOOPBACK */#ifdef IFF_LOOPBACK#define ISLOOPBACK(name, flags) ((flags) & IFF_LOOPBACK)#else#define ISLOOPBACK(name, flags) ((name)[0] == 'l' && (name)[1] == 'o' && \ (isdigit((unsigned char)((name)[2])) || (name)[2] == '\0'))#endifstruct sockaddr *dup_sockaddr(struct sockaddr *sa, size_t sa_length){ struct sockaddr *newsa; if ((newsa = malloc(sa_length)) == NULL) return (NULL); return (memcpy(newsa, sa, sa_length));}static intget_instance(const char *name){ const char *cp, *endcp; int n; if (strcmp(name, "any") == 0) { /* * Give the "any" device an artificially high instance * number, so it shows up after all other non-loopback * interfaces. */ return INT_MAX; } endcp = name + strlen(name); for (cp = name; cp < endcp && !isdigit((unsigned char)*cp); ++cp) continue; if (isdigit((unsigned char)*cp)) n = atoi(cp); else n = 0; return (n);}intadd_or_find_if(pcap_if_t **curdev_ret, pcap_if_t **alldevs, const char *name, u_int flags, const char *description, char *errbuf){ pcap_if_t *curdev, *prevdev, *nextdev; int this_instance; /* * Is there already an entry in the list for this interface? */ for (curdev = *alldevs; curdev != NULL; curdev = curdev->next) { if (strcmp(name, curdev->name) == 0) break; /* yes, we found it */ } if (curdev == NULL) { /* * No, we didn't find it. * Allocate a new entry. */ curdev = malloc(sizeof(pcap_if_t)); if (curdev == NULL) { (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno)); return (-1); } /* * Fill in the entry. */ curdev->next = NULL; curdev->name = malloc(strlen(name) + 1); strcpy(curdev->name, name); if (description != NULL) { /* * We have a description for this interface. */ curdev->description = malloc(strlen(description) + 1); strcpy(curdev->description, description); } else { /* * We don't. */ curdev->description = NULL; } curdev->addresses = NULL; /* list starts out as empty */ curdev->flags = 0; if (ISLOOPBACK(name, flags)) curdev->flags |= PCAP_IF_LOOPBACK; /* * Add it to the list, in the appropriate location. * First, get the instance number of this interface. */ this_instance = get_instance(name); /* * Now look for the last interface with an instance number * less than or equal to the new interface's instance * number - except that non-loopback interfaces are * arbitrarily treated as having interface numbers less * than those of loopback interfaces, so the loopback * interfaces are put at the end of the list. * * We start with "prevdev" being NULL, meaning we're before * the first element in the list. */ prevdev = NULL; for (;;) { /* * Get the interface after this one. */ if (prevdev == NULL) { /* * The next element is the first element. */ nextdev = *alldevs; } else nextdev = prevdev->next; /* * Are we at the end of the list? */ if (nextdev == NULL) { /* * Yes - we have to put the new entry * after "prevdev". */ break; } /* * Is the new interface a non-loopback interface * and the next interface a loopback interface? */ if (!(curdev->flags & PCAP_IF_LOOPBACK) && (nextdev->flags & PCAP_IF_LOOPBACK)) { /* * Yes, we should put the new entry * before "nextdev", i.e. after "prevdev". */ break; } /* * Is the new interface's instance number less * than the next interface's instance number, * and is it the case that the new interface is a * non-loopback interface or the next interface is * a loopback interface? * * (The goal of both loopback tests is to make * sure that we never put a loopback interface * before any non-loopback interface and that we * always put a non-loopback interface before all * loopback interfaces.) */ if (this_instance < get_instance(nextdev->name) && (!(curdev->flags & PCAP_IF_LOOPBACK) || (nextdev->flags & PCAP_IF_LOOPBACK))) { /* * Yes - we should put the new entry * before "nextdev", i.e. after "prevdev". */ break; } prevdev = nextdev; } /* * Insert before "nextdev". */ curdev->next = nextdev; /* * Insert after "prevdev" - unless "prevdev" is null, * in which case this is the first interface. */ if (prevdev == NULL) { /* * This is the first interface. Pass back a * pointer to it, and put "curdev" before * "nextdev". */ *alldevs = curdev; } else prevdev->next = curdev; } *curdev_ret = curdev; return (0);}intadd_addr_to_iflist(pcap_if_t **alldevs, char *name, u_int flags, struct sockaddr *addr, size_t addr_size, struct sockaddr *netmask, size_t netmask_size, struct sockaddr *broadaddr, size_t broadaddr_size, struct sockaddr *dstaddr, size_t dstaddr_size, char *errbuf){ pcap_if_t *curdev; pcap_addr_t *curaddr, *prevaddr, *nextaddr; if (add_or_find_if(&curdev, alldevs, name, flags, NULL, errbuf) == -1) { /* * Error - give up. */ return (-1); } if (curdev == NULL) { /* * Device wasn't added because it can't be opened. * Not a fatal error. */ return (0); } /* * "curdev" is an entry for this interface; add an entry for this * address to its list of addresses. * * Allocate the new entry and fill it in. */ curaddr = malloc(sizeof(pcap_addr_t)); if (curaddr == NULL) { (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno)); return (-1); } curaddr->next = NULL; if (addr != NULL) { curaddr->addr = dup_sockaddr(addr, addr_size); if (curaddr->addr == NULL) { (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno)); free(curaddr); return (-1); } } else curaddr->addr = NULL; if (netmask != NULL) { curaddr->netmask = dup_sockaddr(netmask, netmask_size); if (curaddr->netmask == NULL) { (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno)); free(curaddr); return (-1); } } else curaddr->netmask = NULL; if (broadaddr != NULL) { curaddr->broadaddr = dup_sockaddr(broadaddr, broadaddr_size); if (curaddr->broadaddr == NULL) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -