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

📄 unp.c

📁 TCP/IP商品扫描器 0.1
💻 C
字号:
/* * unp.c -- Unix Network Programming interface. * Created: Xie Han, net lab of Peking University. <e@pku.edu.cn> * * Function "in_chksum" is taken from the book: UNP volume 1. Special * thanks to Richard Stevens. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */#include <errno.h>#include <sys/types.h>#include <sys/ioctl.h>#include <sys/socket.h>#include <sys/un.h>#include <net/if.h>#include <netinet/in.h>#include <netdb.h>#include <unistd.h>#include <stdio.h>#include <string.h>#include "unp.h"unsigned short in_cksum(unsigned short *addr, int len){	int				nleft = len;	int				sum = 0;	unsigned short	*w = addr;	unsigned short	answer = 0;	/*	 * Our algorithm is simple, using a 32 bit accumulator (sum), we add	 * sequential 16 bit words to it, and at the end, fold back all the	 * carry bits from the top 16 bits into the lower 16 bits.	 */	while (nleft > 1)  {		sum += *w++;		nleft -= 2;	}		/* 4mop up an odd byte, if necessary */	if (nleft == 1) {		*(unsigned char *)(&answer) = *(unsigned char *)w ;		sum += answer;	}		/* 4add back carry outs from top 16 bits to low 16 bits */	sum = (sum >> 16) + (sum & 0xffff);	/* add hi 16 to low 16 */	sum += (sum >> 16);			/* add carry */	answer = ~sum;				/* truncate to 16 bits */	return(answer);}inline static int __sockfd_to_family(int sockfd){	union	{		struct sockaddr_un sun;		struct sockaddr sockaddr;	} un;	socklen_t addrlen = sizeof un;	return getsockname(sockfd, &un.sockaddr, &addrlen) >= 0 ?		   un.sockaddr.sa_family : -1;}int mcast_join(int sockfd, const struct sockaddr *sockaddr,socklen_t addrlen,			   unsigned int ifindex, const char *ifname){	switch (sockaddr->sa_family)	{	case AF_INET:		{			struct ip_mreq mreq;			struct ifreq ifreq;			memcpy(&mreq.imr_multiaddr, &((struct sockaddr_in *)sockaddr)->				   sin_addr, sizeof (struct in_addr));			if (ifindex > 0 || ifname)			{				if (ifindex > 0)				{					if (!if_indextoname(ifindex, ifreq.ifr_name))					{						errno = ENXIO;						break;					}				}				else					strncpy(ifreq.ifr_name, ifname, IFNAMSIZ);				if (ioctl(sockfd, SIOCGIFADDR, &ifreq) >= 0)				{					memcpy(&mreq.imr_interface, &((struct sockaddr_in *)&ifreq.						   ifr_addr)->sin_addr, sizeof (struct in_addr));				}				else					break;			}			else				mreq.imr_interface.s_addr = htonl(INADDR_ANY);			return setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq,							  sizeof (struct ip_mreq));		}#ifdef IPV6	case AF_INET6:		{			struct ipv6_mreq mreq6;			memcpy(&mreq6.ipv6mr_multiaddr, &((struct sockaddr_in6 *)				   sockaddr)->sin6_addr, sizeof (struct in6_addr));			if (ifindex > 0)				mreq6.ipv6mr_interface = ifindex;			else if (ifname)			{				if ((mreq6.ipv6mr_interface = if_nametoindex(ifname)) == 0)				{					errno = ENXIO;					break;				}			}			else				mreq6.ipv6mr_interface = 0;			return setsockopt(sockfd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP,							  &mreq6, sizeof (struct ipv6_mreq));		}#endif	default:		errno = EAFNOSUPPORT;		break;	}	return -1;}int mcast_setif(int sockfd, unsigned int ifindex, const char *ifname){	switch (__sockfd_to_family(sockfd))	{	case AF_INET:		{			struct ifreq ifreq;			if (ifindex > 0 || ifname)			{				if (ifindex > 0)				{					if (!if_indextoname(ifindex, ifreq.ifr_name))					{						errno = ENXIO;						break;					}				}				else					strncpy(ifreq.ifr_name, ifname, IFNAMSIZ);				if (ioctl(sockfd, SIOCGIFADDR, &ifreq) < 0)					break;			}			else			{				((struct sockaddr_in *)&ifreq.ifr_addr)->sin_addr.s_addr =					htonl(INADDR_ANY);			}			return setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_IF,							  &((struct sockaddr_in *)&ifreq.ifr_addr)->							  sin_addr, sizeof (struct in_addr));		}#ifdef IPV6	case AF_INET6:		{			if (ifindex == 0 && ifname)			{				if ((ifindex = if_nametoindex(ifname)) == 0)				{					errno = ENXIO;					break;				}			}			return setsockopt(sockfd, IPPROTO_IPV6, IPV6_MULTICAST_IF,							  &ifindex, sizeof (unsigned int));		}#endif	default:		errno = EAFNOSUPPORT;		break;	}	return -1;}int mcast_setloop(int sockfd, int loop){	switch (__sockfd_to_family(sockfd))	{	case AF_INET:		{			unsigned char flag = loop;			return setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_LOOP, &flag,							  sizeof (unsigned char));		}#ifdef IPV6	case AF_INET6:		{			unsigned int flag = loop;			return setsockopt(sockfd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &flag,							  sizeof (unsigned int));		}#endif	default:		errno = EAFNOSUPPORT;		return -1;	}}inline static int __getifaddr_ipv4(int ifindex, const char *ifname,								   struct in_addr *ifaddr){	struct ifreq ifreq;	int sockfd;	int ret = -1;	char ifn[IFNAMSIZ];	if (ifindex > 0)	{		if (!(ifname = if_indextoname(ifindex, ifn)))		{			errno = ENXIO;			return -1;		}	}	if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) >= 0)	{		strncpy(ifreq.ifr_name, ifname, IFNAMSIZ);		if ((ret = ioctl(sockfd, SIOCGIFADDR, &ifreq)) >= 0)			*ifaddr = ((struct sockaddr_in *)&ifreq.ifr_addr)->sin_addr;		close(sockfd);	}	return ret;}#ifdef IPV6#define PROC_IFINET6_PATH	"/proc/net/if_inet6"inline static int __getifaddr_ipv6(unsigned int ifindex, const char *ifname,								   struct in6_addr *ifaddr){	FILE *fp = fopen(PROC_IFINET6_PATH, "r");	char addrstr[INET6_ADDRSTRLEN];	char seg[8][5];	int index, plen, scope, flags;	char ifn[IFNAMSIZ];	int ret = -1;	if (fp)	{		while (fscanf(fp, "%4s%4s%4s%4s%4s%4s%4s%4s %02x %02x %02x %02x %s\n",					  seg[0], seg[1], seg[2], seg[3], seg[4], seg[5], seg[6],					  seg[7], &index, &plen, &scope, &flags, ifn) != EOF)		{			if (ifindex == index || ifindex == 0 && strcmp(ifn, ifname) == 0)			{				sprintf(addrstr, "%s:%s:%s:%s:%s:%s:%s:%s", seg[0], seg[1],						seg[2], seg[3], seg[4], seg[5], seg[6], seg[7]);				ret = inet_pton(AF_INET6, addrstr, ifaddr);				goto out;			}		}		errno = ENXIO;out:		fclose(fp);	}	return ret;}#endifint getifaddr(int family, unsigned int ifindex, const char *ifname,			  void *ifaddr){	switch (family)	{	case AF_INET:		return __getifaddr_ipv4(ifindex, ifname, (struct in_addr *)ifaddr);#ifdef IPV6	case AF_INET6:		return __getifaddr_ipv6(ifindex, ifname, (struct in6_addr *)ifaddr);#endif	default:		errno = EAFNOSUPPORT;		break;	}	return -1;}

⌨️ 快捷键说明

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