⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 intf.c

📁 Ubuntu packages of security software。 相当不错的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * intf.c * * Copyright (c) 2001 Dug Song <dugsong@monkey.org> * * $Id: intf.c,v 1.55 2005/02/10 16:57:35 dugsong Exp $ */#ifdef _WIN32#include "dnet_winconfig.h"#else#include "config.h"#endif#include <sys/param.h>#include <sys/types.h>#include <sys/ioctl.h>#include <sys/socket.h>#ifdef HAVE_SYS_SOCKIO_H# include <sys/sockio.h>#endif/* XXX - AIX */#ifndef IP_MULTICAST# define IP_MULTICAST#endif#include <net/if.h>#ifdef HAVE_NET_IF_VAR_H# include <net/if_var.h>#endif#undef IP_MULTICAST/* XXX - IPv6 ioctls */#ifdef HAVE_NETINET_IN_VAR_H# include <netinet/in.h># include <netinet/in_var.h>#endif#include <errno.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include "dnet.h"/* XXX - Tru64 */#if defined(SIOCRIPMTU) && defined(SIOCSIPMTU)# define SIOCGIFMTU	SIOCRIPMTU# define SIOCSIFMTU	SIOCSIPMTU#endif/* XXX - HP-UX */#if defined(SIOCADDIFADDR) && defined(SIOCDELIFADDR)# define SIOCAIFADDR	SIOCADDIFADDR# define SIOCDIFADDR	SIOCDELIFADDR#endif/* XXX - HP-UX, Solaris */#if !defined(ifr_mtu) && defined(ifr_metric)# define ifr_mtu	ifr_metric#endif#ifdef HAVE_SOCKADDR_SA_LEN# define NEXTIFR(i)	((struct ifreq *)((u_char *)&i->ifr_addr + \				(i->ifr_addr.sa_len ? i->ifr_addr.sa_len : \				 sizeof(i->ifr_addr))))#else# define NEXTIFR(i)	(i + 1)#endif/* XXX - superset of ifreq, for portable SIOC{A,D}IFADDR */struct dnet_ifaliasreq {	char		ifra_name[IFNAMSIZ];	struct sockaddr ifra_addr;	struct sockaddr ifra_brdaddr;	struct sockaddr ifra_mask;	int		ifra_cookie;	/* XXX - IRIX!@#$ */};struct intf_handle {	int		fd;	int		fd6;	struct ifconf	ifc;	u_char		ifcbuf[4192];};static intintf_flags_to_iff(u_short flags, int iff){	if (flags & INTF_FLAG_UP)		iff |= IFF_UP;	else		iff &= ~IFF_UP;	if (flags & INTF_FLAG_NOARP)		iff |= IFF_NOARP;	else		iff &= ~IFF_NOARP;		return (iff);}static u_intintf_iff_to_flags(int iff){	u_int n = 0;	if (iff & IFF_UP)		n |= INTF_FLAG_UP;		if (iff & IFF_LOOPBACK)		n |= INTF_FLAG_LOOPBACK;	if (iff & IFF_POINTOPOINT)		n |= INTF_FLAG_POINTOPOINT;	if (iff & IFF_NOARP)		n |= INTF_FLAG_NOARP;	if (iff & IFF_BROADCAST)		n |= INTF_FLAG_BROADCAST;	if (iff & IFF_MULTICAST)		n |= INTF_FLAG_MULTICAST;	return (n);}intf_t *intf_open(void){	intf_t *intf;	int one = 1;	if ((intf = calloc(1, sizeof(*intf))) != NULL) {		intf->fd = intf->fd6 = -1;				if ((intf->fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)			return (intf_close(intf));		setsockopt(intf->fd, SOL_SOCKET, SO_BROADCAST, 			   (const char *) &one, sizeof(one));#ifdef SIOCGIFNETMASK_IN6		if ((intf->fd6 = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {#  ifdef EPROTONOSUPPORT			if (errno != EPROTONOSUPPORT)#  endif				return (intf_close(intf));		}#endif	}	return (intf);}static int_intf_delete_addrs(intf_t *intf, struct intf_entry *entry){#if defined(SIOCDIFADDR)	struct dnet_ifaliasreq ifra;		memset(&ifra, 0, sizeof(ifra));	strlcpy(ifra.ifra_name, entry->intf_name, sizeof(ifra.ifra_name));	if (entry->intf_addr.addr_type == ADDR_TYPE_IP) {		addr_ntos(&entry->intf_addr, &ifra.ifra_addr);		ioctl(intf->fd, SIOCDIFADDR, &ifra);	}	if (entry->intf_dst_addr.addr_type == ADDR_TYPE_IP) {		addr_ntos(&entry->intf_dst_addr, &ifra.ifra_addr);		ioctl(intf->fd, SIOCDIFADDR, &ifra);	}#elif defined(SIOCLIFREMOVEIF)	struct ifreq ifr;	memset(&ifr, 0, sizeof(ifr));	strlcpy(ifr.ifr_name, entry->intf_name, sizeof(ifr.ifr_name));	/* XXX - overloading Solaris lifreq with ifreq */	ioctl(intf->fd, SIOCLIFREMOVEIF, &ifr);#endif	return (0);}static int_intf_delete_aliases(intf_t *intf, struct intf_entry *entry){	int i;#if defined(SIOCDIFADDR) && !defined(__linux__)	/* XXX - see Linux below */	struct dnet_ifaliasreq ifra;		memset(&ifra, 0, sizeof(ifra));	strlcpy(ifra.ifra_name, entry->intf_name, sizeof(ifra.ifra_name));		for (i = 0; i < (int)entry->intf_alias_num; i++) {		addr_ntos(&entry->intf_alias_addrs[i], &ifra.ifra_addr);		ioctl(intf->fd, SIOCDIFADDR, &ifra);	}#else	struct ifreq ifr;		for (i = 0; i < entry->intf_alias_num; i++) {		snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s:%d",		    entry->intf_name, i + 1);# ifdef SIOCLIFREMOVEIF		/* XXX - overloading Solaris lifreq with ifreq */		ioctl(intf->fd, SIOCLIFREMOVEIF, &ifr);# else		/* XXX - only need to set interface down on Linux */		ifr.ifr_flags = 0;		ioctl(intf->fd, SIOCSIFFLAGS, &ifr);# endif	}#endif	return (0);}static int_intf_add_aliases(intf_t *intf, const struct intf_entry *entry){	int i;#ifdef SIOCAIFADDR	struct dnet_ifaliasreq ifra;	struct addr bcast;		memset(&ifra, 0, sizeof(ifra));	strlcpy(ifra.ifra_name, entry->intf_name, sizeof(ifra.ifra_name));		for (i = 0; i < (int)entry->intf_alias_num; i++) {		if (entry->intf_alias_addrs[i].addr_type != ADDR_TYPE_IP)			continue;				if (addr_ntos(&entry->intf_alias_addrs[i],		    &ifra.ifra_addr) < 0)			return (-1);		addr_bcast(&entry->intf_alias_addrs[i], &bcast);		addr_ntos(&bcast, &ifra.ifra_brdaddr);		addr_btos(entry->intf_alias_addrs[i].addr_bits,		    &ifra.ifra_mask);				if (ioctl(intf->fd, SIOCAIFADDR, &ifra) < 0)			return (-1);	}#else	struct ifreq ifr;	int n = 1;		for (i = 0; i < entry->intf_alias_num; i++) {		if (entry->intf_alias_addrs[i].addr_type != ADDR_TYPE_IP)			continue;				snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s:%d",		    entry->intf_name, n++);# ifdef SIOCLIFADDIF		if (ioctl(intf->fd, SIOCLIFADDIF, &ifr) < 0)			return (-1);# endif		if (addr_ntos(&entry->intf_alias_addrs[i], &ifr.ifr_addr) < 0)			return (-1);		if (ioctl(intf->fd, SIOCSIFADDR, &ifr) < 0)			return (-1);	}	strlcpy(ifr.ifr_name, entry->intf_name, sizeof(ifr.ifr_name));#endif	return (0);}intintf_set(intf_t *intf, const struct intf_entry *entry){	struct ifreq ifr;	struct intf_entry *orig;	struct addr bcast;	u_char buf[BUFSIZ];		orig = (struct intf_entry *)buf;	orig->intf_len = sizeof(buf);	strcpy(orig->intf_name, entry->intf_name);		if (intf_get(intf, orig) < 0)		return (-1);		/* Delete any existing aliases. */	if (_intf_delete_aliases(intf, orig) < 0)		return (-1);	/* Delete any existing addrs. */	if (_intf_delete_addrs(intf, orig) < 0)		return (-1);		memset(&ifr, 0, sizeof(ifr));	strlcpy(ifr.ifr_name, entry->intf_name, sizeof(ifr.ifr_name));		/* Set interface MTU. */	if (entry->intf_mtu != 0) {		ifr.ifr_mtu = entry->intf_mtu;#ifdef SIOCSIFMTU		if (ioctl(intf->fd, SIOCSIFMTU, &ifr) < 0)#endif			return (-1);	}	/* Set interface address. */	if (entry->intf_addr.addr_type == ADDR_TYPE_IP) {#ifdef BSD		/* XXX - why must this happen before SIOCSIFADDR? */		if (addr_btos(entry->intf_addr.addr_bits,		    &ifr.ifr_addr) == 0) {			if (ioctl(intf->fd, SIOCSIFNETMASK, &ifr) < 0)				return (-1);		}#endif		if (addr_ntos(&entry->intf_addr, &ifr.ifr_addr) < 0)			return (-1);		if (ioctl(intf->fd, SIOCSIFADDR, &ifr) < 0 && errno != EEXIST)			return (-1);				if (addr_btos(entry->intf_addr.addr_bits, &ifr.ifr_addr) == 0#ifdef __linux__		    && entry->intf_addr.addr_ip != 0#endif		    ) {			if (ioctl(intf->fd, SIOCSIFNETMASK, &ifr) < 0)				return (-1);		}		if (addr_bcast(&entry->intf_addr, &bcast) == 0) {			if (addr_ntos(&bcast, &ifr.ifr_broadaddr) == 0) {				/* XXX - ignore error from non-broadcast ifs */				ioctl(intf->fd, SIOCSIFBRDADDR, &ifr);			}		}	}	/* Set link-level address. */	if (entry->intf_link_addr.addr_type == ADDR_TYPE_ETH &&	    addr_cmp(&entry->intf_link_addr, &orig->intf_link_addr) != 0) {#if defined(SIOCSIFHWADDR)		if (addr_ntos(&entry->intf_link_addr, &ifr.ifr_hwaddr) < 0)			return (-1);		if (ioctl(intf->fd, SIOCSIFHWADDR, &ifr) < 0)			return (-1);#elif defined (SIOCSIFLLADDR)		memcpy(ifr.ifr_addr.sa_data, &entry->intf_link_addr.addr_eth,		    ETH_ADDR_LEN);		ifr.ifr_addr.sa_len = ETH_ADDR_LEN;		if (ioctl(intf->fd, SIOCSIFLLADDR, &ifr) < 0)			return (-1);#else		eth_t *eth;		if ((eth = eth_open(entry->intf_name)) == NULL)			return (-1);		if (eth_set(eth, &entry->intf_link_addr.addr_eth) < 0) {			eth_close(eth);			return (-1);		}		eth_close(eth);#endif	}	/* Set point-to-point destination. */	if (entry->intf_dst_addr.addr_type == ADDR_TYPE_IP) {		if (addr_ntos(&entry->intf_dst_addr, &ifr.ifr_dstaddr) < 0)			return (-1);		if (ioctl(intf->fd, SIOCSIFDSTADDR, &ifr) < 0 &&		    errno != EEXIST)			return (-1);	}	/* Add aliases. */	if (_intf_add_aliases(intf, entry) < 0)		return (-1);		/* Set interface flags. */	if (ioctl(intf->fd, SIOCGIFFLAGS, &ifr) < 0)		return (-1);		ifr.ifr_flags = intf_flags_to_iff(entry->intf_flags, ifr.ifr_flags);		if (ioctl(intf->fd, SIOCSIFFLAGS, &ifr) < 0)		return (-1);		return (0);}/* XXX - this is total crap. how to do this without walking ifnet? */static void_intf_set_type(struct intf_entry *entry){	if ((entry->intf_flags & INTF_FLAG_BROADCAST) != 0)

⌨️ 快捷键说明

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