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

📄 addr.c

📁 Ubuntu packages of security software。 相当不错的源码
💻 C
字号:
/* * addr.c * * Network address operations. * * Copyright (c) 2000 Dug Song <dugsong@monkey.org> * * $Id: addr.c,v 1.33 2005/01/23 07:36:54 dugsong Exp $ */#ifdef _WIN32#include "dnet_winconfig.h"#else#include "config.h"#endif#include <sys/types.h>#ifdef HAVE_NET_IF_H# include <sys/socket.h># include <net/if.h>#endif#ifdef HAVE_NET_IF_DL_H# include <net/if_dl.h>#endif#ifdef HAVE_NET_RAW_H# include <net/raw.h>#endif#include <ctype.h>#include <errno.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include "dnet.h"#ifndef MAXHOSTNAMELEN# define MAXHOSTNAMELEN	256#endifunion sockunion {#ifdef HAVE_NET_IF_DL_H	struct sockaddr_dl	sdl;#endif	struct sockaddr_in	sin;#ifdef HAVE_SOCKADDR_IN6	struct sockaddr_in6	sin6;#endif	struct sockaddr		sa;#ifdef AF_RAW	struct sockaddr_raw	sr;#endif};intaddr_cmp(const struct addr *a, const struct addr *b){	int i, j, k;	/* XXX */	if ((i = a->addr_type - b->addr_type) != 0)		return (i);		/* XXX - 10.0.0.1 is "smaller" than 10.0.0.0/8? */	if ((i = a->addr_bits - b->addr_bits) != 0)		return (i);		j = b->addr_bits / 8;	for (i = 0; i < j; i++) {		if ((k = a->addr_data8[i] - b->addr_data8[i]) != 0)			return (k);	}	if ((k = b->addr_bits % 8) == 0)		return (0);	k = ~0 << (8 - k);	i = b->addr_data8[j] & k;	j = a->addr_data8[j] & k;		return (j - i);}intaddr_net(const struct addr *a, struct addr *b){	uint32_t mask;	int i, j;	if (a->addr_type == ADDR_TYPE_IP) {		addr_btom(a->addr_bits, &mask, IP_ADDR_LEN);		b->addr_type = ADDR_TYPE_IP;		b->addr_bits = IP_ADDR_BITS;		b->addr_ip = a->addr_ip & mask;	} else if (a->addr_type == ADDR_TYPE_ETH) {		memcpy(b, a, sizeof(*b));		if (a->addr_data8[0] & 0x1)			memset(b->addr_data8 + 3, 0, 3);		b->addr_bits = ETH_ADDR_BITS;	} else if (a->addr_type == ADDR_TYPE_IP6) {		b->addr_type = ADDR_TYPE_IP6;		b->addr_bits = IP6_ADDR_BITS;		memset(&b->addr_ip6, 0, IP6_ADDR_LEN);				switch ((i = a->addr_bits / 32)) {		case 4: b->addr_data32[3] = a->addr_data32[3];		case 3: b->addr_data32[2] = a->addr_data32[2];		case 2: b->addr_data32[1] = a->addr_data32[1];		case 1: b->addr_data32[0] = a->addr_data32[0];		}		if ((j = a->addr_bits % 32) > 0) {			addr_btom(j, &mask, sizeof(mask));			b->addr_data32[i] = a->addr_data32[i] & mask;		}	} else		return (-1);		return (0);}intaddr_bcast(const struct addr *a, struct addr *b){	struct addr mask;		if (a->addr_type == ADDR_TYPE_IP) {		addr_btom(a->addr_bits, &mask.addr_ip, IP_ADDR_LEN);		b->addr_type = ADDR_TYPE_IP;		b->addr_bits = IP_ADDR_BITS;		b->addr_ip = (a->addr_ip & mask.addr_ip) |		    (~0L & ~mask.addr_ip);	} else if (a->addr_type == ADDR_TYPE_ETH) {		b->addr_type = ADDR_TYPE_ETH;		b->addr_bits = ETH_ADDR_BITS;		memcpy(&b->addr_eth, ETH_ADDR_BROADCAST, ETH_ADDR_LEN);	} else {		/* XXX - no broadcast addresses in IPv6 */		errno = EINVAL;		return (-1);	}	return (0);}char *addr_ntop(const struct addr *src, char *dst, size_t size){	if (src->addr_type == ADDR_TYPE_IP && size >= 20) {		if (ip_ntop(&src->addr_ip, dst, size) != NULL) {			if (src->addr_bits != IP_ADDR_BITS)				sprintf(dst + strlen(dst), "/%d",				    src->addr_bits);			return (dst);		}	} else if (src->addr_type == ADDR_TYPE_IP6 && size >= 42) {		if (ip6_ntop(&src->addr_ip6, dst, size) != NULL) {			if (src->addr_bits != IP6_ADDR_BITS)				sprintf(dst + strlen(dst), "/%d",				    src->addr_bits);			return (dst);		}	} else if (src->addr_type == ADDR_TYPE_ETH && size >= 18) {		if (src->addr_bits == ETH_ADDR_BITS)			return (eth_ntop(&src->addr_eth, dst, size));	}	errno = EINVAL;	return (NULL);}intaddr_pton(const char *src, struct addr *dst){	struct hostent *hp;	char *ep, tmp[300];	long bits = -1;	int i;		for (i = 0; i < (int)sizeof(tmp) - 1; i++) {		if (src[i] == '/') {			tmp[i] = '\0';			if (strchr(&src[i + 1], '.')) {				uint32_t m;				uint16_t b;				/* XXX - mask is specified like /255.0.0.0 */				if (ip_pton(&src[i + 1], &m) != 0) {					errno = EINVAL;					return (-1);				}				addr_mtob(&m, sizeof(m), &b);				bits = b;			} else {				bits = strtol(&src[i + 1], &ep, 10);				if (ep == src || *ep != '\0' || bits < 0) {					errno = EINVAL;					return (-1);				}			}			break;		} else if ((tmp[i] = src[i]) == '\0')			break;	}	if (ip_pton(tmp, &dst->addr_ip) == 0) {		dst->addr_type = ADDR_TYPE_IP;		dst->addr_bits = IP_ADDR_BITS;	} else if (eth_pton(tmp, &dst->addr_eth) == 0) {		dst->addr_type = ADDR_TYPE_ETH;		dst->addr_bits = ETH_ADDR_BITS;	} else if (ip6_pton(tmp, &dst->addr_ip6) == 0) {		dst->addr_type = ADDR_TYPE_IP6;		dst->addr_bits = IP6_ADDR_BITS;	} else if ((hp = gethostbyname(tmp)) != NULL) {		memcpy(&dst->addr_ip, hp->h_addr, IP_ADDR_LEN);		dst->addr_type = ADDR_TYPE_IP;		dst->addr_bits = IP_ADDR_BITS;	} else {		errno = EINVAL;		return (-1);	}	if (bits >= 0) {		if (bits > dst->addr_bits) {			errno = EINVAL;			return (-1);		}		dst->addr_bits = (uint16_t)bits;	}	return (0);}char *addr_ntoa(const struct addr *a){	static char *p, buf[BUFSIZ];	char *q = NULL;		if (p == NULL || p > buf + sizeof(buf) - 64 /* XXX */)		p = buf;		if (addr_ntop(a, p, (buf + sizeof(buf)) - p) != NULL) {		q = p;		p += strlen(p) + 1;	}	return (q);}intaddr_ntos(const struct addr *a, struct sockaddr *sa){	union sockunion *so = (union sockunion *)sa;		switch (a->addr_type) {	case ADDR_TYPE_ETH:#ifdef HAVE_NET_IF_DL_H		memset(&so->sdl, 0, sizeof(so->sdl));#ifdef HAVE_SOCKADDR_SA_LEN		so->sdl.sdl_len = sizeof(so->sdl);#endif		so->sdl.sdl_family = AF_LINK;		so->sdl.sdl_alen = ETH_ADDR_LEN;		memcpy(LLADDR(&so->sdl), &a->addr_eth, ETH_ADDR_LEN);#else		memset(sa, 0, sizeof(*sa));		sa->sa_family = AF_UNSPEC;		memcpy(sa->sa_data, &a->addr_eth, ETH_ADDR_LEN);#endif		break;#ifdef HAVE_SOCKADDR_IN6	case ADDR_TYPE_IP6:		memset(&so->sin6, 0, sizeof(so->sin6));#ifdef HAVE_SOCKADDR_SA_LEN		so->sin6.sin6_len = sizeof(so->sin6);#endif		so->sin6.sin6_family = AF_INET6;		memcpy(&so->sin6.sin6_addr, &a->addr_ip6, IP6_ADDR_LEN);		break;#endif	case ADDR_TYPE_IP:		memset(&so->sin, 0, sizeof(so->sin));#ifdef HAVE_SOCKADDR_SA_LEN		so->sin.sin_len = sizeof(so->sin);#endif		so->sin.sin_family = AF_INET;		so->sin.sin_addr.s_addr = a->addr_ip;		break;	default:		errno = EINVAL;		return (-1);	}	return (0);}intaddr_ston(const struct sockaddr *sa, struct addr *a){	union sockunion *so = (union sockunion *)sa;		memset(a, 0, sizeof(*a));		switch (sa->sa_family) {#ifdef HAVE_NET_IF_DL_H	case AF_LINK:		if (so->sdl.sdl_alen != ETH_ADDR_LEN) {			errno = EINVAL;			return (-1);		}		a->addr_type = ADDR_TYPE_ETH;		a->addr_bits = ETH_ADDR_BITS;		memcpy(&a->addr_eth, LLADDR(&so->sdl), ETH_ADDR_LEN);		break;#endif	case AF_UNSPEC:	case ARP_HRD_ETH:	/* XXX- Linux arp(7) */		a->addr_type = ADDR_TYPE_ETH;		a->addr_bits = ETH_ADDR_BITS;		memcpy(&a->addr_eth, sa->sa_data, ETH_ADDR_LEN);		break;		#ifdef AF_RAW	case AF_RAW:		/* XXX - IRIX raw(7f) */		a->addr_type = ADDR_TYPE_ETH;		a->addr_bits = ETH_ADDR_BITS;		memcpy(&a->addr_eth, so->sr.sr_addr, ETH_ADDR_LEN);		break;#endif#ifdef HAVE_SOCKADDR_IN6	case AF_INET6:		a->addr_type = ADDR_TYPE_IP6;		a->addr_bits = IP6_ADDR_BITS;		memcpy(&a->addr_ip6, &so->sin6.sin6_addr, IP6_ADDR_LEN);		break;#endif	case AF_INET:		a->addr_type = ADDR_TYPE_IP;		a->addr_bits = IP_ADDR_BITS;		a->addr_ip = so->sin.sin_addr.s_addr;		break;	default:		errno = EINVAL;		return (-1);	}	return (0);}intaddr_btos(uint16_t bits, struct sockaddr *sa){	union sockunion *so = (union sockunion *)sa;#ifdef HAVE_SOCKADDR_IN6	if (bits > IP_ADDR_BITS && bits <= IP6_ADDR_BITS) {		memset(&so->sin6, 0, sizeof(so->sin6));#ifdef HAVE_SOCKADDR_SA_LEN		so->sin6.sin6_len = IP6_ADDR_LEN + (bits / 8) + (bits % 8);#endif		so->sin6.sin6_family = AF_INET6;		return (addr_btom(bits, &so->sin6.sin6_addr, IP6_ADDR_LEN));	} else#endif	if (bits <= IP_ADDR_BITS) {		memset(&so->sin, 0, sizeof(so->sin));#ifdef HAVE_SOCKADDR_SA_LEN		so->sin.sin_len = IP_ADDR_LEN + (bits / 8) + (bits % 8);#endif		so->sin.sin_family = AF_INET;		return (addr_btom(bits, &so->sin.sin_addr, IP_ADDR_LEN));	}	errno = EINVAL;	return (-1);}intaddr_stob(const struct sockaddr *sa, uint16_t *bits){	union sockunion *so = (union sockunion *)sa;	int i, j, len;	uint16_t n;	u_char *p;#ifdef HAVE_SOCKADDR_IN6	if (sa->sa_family == AF_INET6) {		len = IP6_ADDR_LEN;		p = (u_char *)&so->sin6.sin6_addr;	} else#endif	{#ifdef HAVE_SOCKADDR_SA_LEN		if ((len = sa->sa_len - IP_ADDR_LEN) > IP_ADDR_LEN)#endif		len = IP_ADDR_LEN;		p = (u_char *)&so->sin.sin_addr.s_addr;	}	for (n = i = 0; i < len; i++, n += 8) {		if (p[i] != 0xff)			break;	}	if (i != len && p[i]) {		for (j = 7; j > 0; j--, n++) {			if ((p[i] & (1 << j)) == 0)				break;		}	}	*bits = n;		return (0);}	intaddr_btom(uint16_t bits, void *mask, size_t size){	int net, host;	u_char *p;	if (size == IP_ADDR_LEN) {		if (bits > IP_ADDR_BITS) {			errno = EINVAL;			return (-1);		}		*(uint32_t *)mask = bits ?		    htonl(~0 << (IP_ADDR_BITS - bits)) : 0;	} else {		if (size * 8 < bits) {			errno = EINVAL;			return (-1);		}		p = (u_char *)mask;				if ((net = bits / 8) > 0)			memset(p, 0xff, net);				if ((host = bits % 8) > 0) {			p[net] = 0xff << (8 - host);			memset(&p[net + 1], 0, size - net - 1);		} else			memset(&p[net], 0, size - net);	}	return (0);}intaddr_mtob(const void *mask, size_t size, uint16_t *bits){	uint16_t n;	u_char *p;	int i, j;	p = (u_char *)mask;		for (n = i = 0; i < (int)size; i++, n += 8) {		if (p[i] != 0xff)			break;	}	if (i != (int)size && p[i]) {		for (j = 7; j > 0; j--, n++) {			if ((p[i] & (1 << j)) == 0)				break;		}	}	*bits = n;	return (0);}

⌨️ 快捷键说明

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