inet.c

来自「Ubuntu packages of security software。 相」· C语言 代码 · 共 794 行 · 第 1/2 页

C
794
字号
/* -*- 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.66.2.6 2007/06/11 09:52:04 guy Exp $ (LBL)";#endif#ifdef HAVE_CONFIG_H#include "config.h"#endif#ifdef WIN32#include <pcap-stdinc.h>#else /* WIN32 */#include <sys/param.h>#ifndef MSDOS#include <sys/file.h>#endif#include <sys/ioctl.h>#include <sys/socket.h>#ifdef HAVE_SYS_SOCKIO_H#include <sys/sockio.h>#endifstruct 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>#if !defined(WIN32) && !defined(__BORLANDC__)#include <unistd.h>#endif /* !WIN32 && !__BORLANDC__ */#ifdef HAVE_LIMITS_H#include <limits.h>#else#define INT_MAX		2147483647#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_t *p;	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.		 *		 * Can we open this interface for live capture?		 *		 * We do this check so that interfaces that are		 * supplied by the interface enumeration mechanism		 * we're using but that don't support packet capture		 * aren't included in the list.  Loopback interfaces		 * on Solaris are an example of this; we don't just		 * omit loopback interfaces on all platforms because		 * you *can* capture on loopback interfaces on some		 * OSes.		 *		 * On OS X, we don't do this check if the device		 * name begins with "wlt"; at least some versions		 * of OS X offer monitor mode capturing by having		 * a separate "monitor mode" device for each wireless		 * adapter, rather than by implementing the ioctls		 * that {Free,Net,Open,DragonFly}BSD provide.		 * Opening that device puts the adapter into monitor		 * mode, which, at least for some adapters, causes		 * them to deassociate from the network with which		 * they're associated.		 *		 * Instead, we try to open the corresponding "en"		 * device (so that we don't end up with, for users		 * without sufficient privilege to open capture		 * devices, a list of adapters that only includes		 * the wlt devices).		 */#ifdef __APPLE__		if (strncmp(name, "wlt", 3) == 0) {			char *en_name;			size_t en_name_len;			/*			 * Try to allocate a buffer for the "en"			 * device's name.			 */			en_name_len = strlen(name) - 1;			en_name = malloc(en_name_len + 1);			if (en_name == NULL) {				(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,				    "malloc: %s", pcap_strerror(errno));				return (-1);			}			strcpy(en_name, "en");			strcat(en_name, name + 3);			p = pcap_open_live(en_name, 68, 0, 0, errbuf);			free(en_name);		} else#endif /* __APPLE */		p = pcap_open_live(name, 68, 0, 0, errbuf);		if (p == NULL) {			/*			 * No.  Don't bother including it.			 * Don't treat this as an error, though.			 */			*curdev_ret = NULL;			return (0);		}		pcap_close(p);		/*		 * Yes, we can open 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 = strdup(name);		if (curdev->name == NULL) {			(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,			    "malloc: %s", pcap_strerror(errno));			free(curdev);			return (-1);		}		if (description != NULL) {			/*			 * We have a description for this interface.			 */			curdev->description = strdup(description);			if (curdev->description == NULL) {				(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,				    "malloc: %s", pcap_strerror(errno));				free(curdev->name);				free(curdev);				return (-1);			}		} 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, const 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;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?