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

📄 pcap-new.c

📁 Windows XP下的抓包程序实现
💻 C
📖 第 1 页 / 共 3 页
字号:
			case -1:	// The other endpoint has a version number that is not compatible with our
				break;

			case RPCAP_MSG_ERROR:		// The other endpoint reported an error
				break;

			default:
			{
				snprintf(errbuf, PCAP_ERRBUF_SIZE, "Internal error");
				break;
			};
		}

		if (!active)
			sock_close(sockctrl, NULL, 0);

		return -1;
	}

	// read the number of interfaces
	nif= ntohs(header.value);

	// loop until all interfaces have been received
	for (i= 0; i < nif; i++)
	{
	struct rpcap_findalldevs_if findalldevs_if;
	char tmpstring2[PCAP_BUF_SIZE + 1];		// Needed to convert names and descriptions from 'old' syntax to the 'new' one
	int stringlen;

		tmpstring2[PCAP_BUF_SIZE]= 0;

		// receive the findalldevs structure from remote hsot
		if ( (nread+= sock_recv(sockctrl, (char *) &findalldevs_if, 
			sizeof(struct rpcap_findalldevs_if), SOCK_RECEIVEALL_YES, errbuf, PCAP_ERRBUF_SIZE) ) == -1)
			goto error;

		findalldevs_if.namelen= ntohs(findalldevs_if.namelen);
		findalldevs_if.desclen= ntohs(findalldevs_if.desclen);
		findalldevs_if.naddr= ntohs(findalldevs_if.naddr);

		// allocate the main structure
		if (i == 0)
		{
			(*alldevs)= (pcap_if_t *) malloc(sizeof(pcap_if_t) );
			dev= (*alldevs);
		}
		else
		{
			dev->next= (pcap_if_t *) malloc(sizeof(pcap_if_t) );
			dev= dev->next;
		}

		// check that the malloc() didn't fail
		if (dev == NULL)
		{
			snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc() failed: %s", pcap_strerror(errno));
			goto error;
		}

		// Initialize the structure to 'zero'
		memset(dev, 0, sizeof(pcap_if_t) );

		// allocate mem for name and description
		if (findalldevs_if.namelen)
		{

			if (findalldevs_if.namelen >= sizeof(tmpstring) )
			{
				snprintf(errbuf, PCAP_ERRBUF_SIZE, "Interface name too long");
				goto error;
			}

			// Retrieve adapter name
			if ( (nread+= sock_recv(sockctrl, tmpstring, findalldevs_if.namelen, SOCK_RECEIVEALL_YES, errbuf, PCAP_ERRBUF_SIZE) ) == -1)
				goto error;

			tmpstring[findalldevs_if.namelen]= 0;

			// Create the new device identifier
			if (pcap_createsrcstr(tmpstring2, PCAP_SRC_IFREMOTE, host, port, tmpstring, errbuf) == -1)
				return -1;

			stringlen= strlen(tmpstring2);

			dev->name= (char *) malloc(stringlen + 1);
			if (dev->name == NULL)
			{
				snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc() failed: %s", pcap_strerror(errno));
				goto error;
			}

			// Copy the new device name into the correct memory location
			strncpy(dev->name, tmpstring2, stringlen + 1);
		}

		if (findalldevs_if.desclen)
		{
			if (findalldevs_if.desclen >= sizeof(tmpstring) )
			{
				snprintf(errbuf, PCAP_ERRBUF_SIZE, "Interface description too long");
				goto error;
			}

			// Retrieve adapter description
			if ( (nread+= sock_recv(sockctrl, tmpstring, findalldevs_if.desclen, SOCK_RECEIVEALL_YES, errbuf, PCAP_ERRBUF_SIZE) ) == -1)
				goto error;

			tmpstring[findalldevs_if.desclen]= 0;


			snprintf(tmpstring2, sizeof(tmpstring2) - 1, "%s '%s' %s %s", PCAP_TEXT_SOURCE_ADAPTER, 
				tmpstring, PCAP_TEXT_SOURCE_ON_REMOTE_HOST, host);

			stringlen= strlen(tmpstring2);

			dev->description= (char *) malloc(stringlen + 1);

			if (dev->description == NULL)
			{
				snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc() failed: %s", pcap_strerror(errno));
				goto error;
			}

			// Copy the new device description into the correct memory location
			strncpy(dev->description, tmpstring2, stringlen + 1);
		}

		dev->flags= ntohl(findalldevs_if.flags);

		naddr= 0;
		// loop until all addresses have been received
		for (j= 0; j < findalldevs_if.naddr; j++)
		{
		struct rpcap_findalldevs_ifaddr ifaddr;

			// Retrieve the interface addresses
			if (  (nread+= sock_recv(sockctrl, (char *) &ifaddr, 
				sizeof(struct rpcap_findalldevs_ifaddr), SOCK_RECEIVEALL_YES, errbuf, PCAP_ERRBUF_SIZE) ) == -1)
				goto error;

			// WARNING libpcap bug: the address listing is available only for AF_INET
			if ( ntohs(ifaddr.addr.ss_family) == AF_INET)
			{
			struct pcap_addr *addr;

				if (naddr == 0)
				{
					dev->addresses= (struct pcap_addr *) malloc ( sizeof(struct pcap_addr) );
					addr= dev->addresses;
				}
				else
				{
					addr->next= (struct pcap_addr *) malloc ( sizeof(struct pcap_addr) );
					addr= addr->next;
				}
				naddr++;

				if (addr == NULL)
				{
					snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc() failed: %s", pcap_strerror(errno));
					goto error;
				}
				addr->next= NULL;

				if (rpcap_deseraddr( (struct sockaddr_storage *) &ifaddr.addr, 
					(struct sockaddr_storage **) &addr->addr, errbuf) == -1)
					goto error;
				if (rpcap_deseraddr( (struct sockaddr_storage *) &ifaddr.netmask, 
					(struct sockaddr_storage **) &addr->netmask, errbuf) == -1)
					goto error;
				if (rpcap_deseraddr( (struct sockaddr_storage *) &ifaddr.broadaddr, 
					(struct sockaddr_storage **) &addr->broadaddr, errbuf) == -1)
					goto error;
				if (rpcap_deseraddr( (struct sockaddr_storage *) &ifaddr.dstaddr, 
					(struct sockaddr_storage **) &addr->dstaddr, errbuf) == -1)
					goto error;

				if ( (addr->addr == NULL) && (addr->netmask == NULL) && 
					(addr->broadaddr == NULL) && (addr->dstaddr == NULL) )
				{
					free(addr);
					addr= NULL;
					if (naddr == 1)
						naddr= 0;	// the first item of the list had NULL addresses
				}
			}
		}
	}

	// Checks if all the data has been read; if not, discard the data in excess
	if (nread != ntohl(header.plen))
	{
		if (sock_discard(sockctrl, ntohl(header.plen) - nread, errbuf, PCAP_ERRBUF_SIZE) == 1)
			return -1;
	}

	// Control connection has to be closed only in case the remote machine is in passive mode
	if (!active)
	{
		// DO not send RPCAP_CLOSE, since we did not open a pcap_t; no need to free resources
		if ( sock_close(sockctrl, errbuf, PCAP_ERRBUF_SIZE) )
			return -1;
	}

	// To avoid inconsistencies in the number of sock_init()
	sock_cleanup();

	return 0;

error:
	// In case there has been an error, I don't want to overwrite it with a new one
	// if the following call fails. I want to return always the original error.
	//
	// Take care: this connection can already be closed when we try to close it.
	// This happens because a previous error in the rpcapd, which requested to
	// closed the connection. In that case, we already recognized that into the
	// rpspck_isheaderok() and we already acknowledged the closing.
	// In that sense, this call is useless here (however it is needed in case
	// the client generates the error).

	// Checks if all the data has been read; if not, discard the data in excess
	if (nread != ntohl(header.plen))
	{
		if (sock_discard(sockctrl, ntohl(header.plen) - nread, NULL, 0) == 1)
			return -1;
	}

	// Control connection has to be closed only in case the remote machine is in passive mode
	if (!active)
		sock_close(sockctrl, NULL, 0);

	// To avoid inconsistencies in the number of sock_init()
	sock_cleanup();

	return -1;
}


int pcap_createsrcstr(char *source, int type, const char *host, const char *port, const char *name, char *errbuf)
{
	switch (type)
	{
		case PCAP_SRC_FILE:
		{
			strncpy(source, PCAP_SRC_FILE_STRING, PCAP_BUF_SIZE);
			if ((name) && (*name) )
			{
				strncat(source, name, PCAP_BUF_SIZE);
				return 0;
			}
			else
			{
				snprintf(errbuf, PCAP_ERRBUF_SIZE, "The file name cannot be NULL.");
				return -1;
			}
		}

		case PCAP_SRC_IFREMOTE:
		{
			strncpy(source, PCAP_SRC_IF_STRING, PCAP_BUF_SIZE);
			if ((host) && (*host) )
			{
				if ( (strcspn(host, "aAbBcCdDeEfFgGhHjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ")) == strlen(host) )
				{
					// the host name does not contains alphabetic chars. So, it is a numeric address
					// In this case we have to include it between square brackets
					strncat(source, "[", PCAP_BUF_SIZE);
					strncat(source, host, PCAP_BUF_SIZE);
					strncat(source, "]", PCAP_BUF_SIZE);
				}
				else
					strncat(source, host, PCAP_BUF_SIZE);

				if ((port) && (*port) )
				{
					strncat(source, ":", PCAP_BUF_SIZE);
					strncat(source, port, PCAP_BUF_SIZE);
				}

				strncat(source, "/", PCAP_BUF_SIZE);
			}
			else
			{
				snprintf(errbuf, PCAP_ERRBUF_SIZE, "The host name cannot be NULL.");
				return -1;
			}

			if ((name) && (*name) )
				strncat(source, name, PCAP_BUF_SIZE);

			return 0;
		}

		case PCAP_SRC_IFLOCAL:
		{
			strncpy(source, PCAP_SRC_IF_STRING, PCAP_BUF_SIZE);

			if ((name) && (*name) )
				strncat(source, name, PCAP_BUF_SIZE);

			return 0;
		}

		default:
		{
			snprintf(errbuf, PCAP_ERRBUF_SIZE, "The interface type is not valid.");
			return -1;
		}
	}
}


int pcap_parsesrcstr(const char *source, int *type, char *host, char *port, char *name, char *errbuf)
{
char *ptr;
int ntoken;
char tmpname[PCAP_BUF_SIZE];
char tmphost[PCAP_BUF_SIZE];
char tmpport[PCAP_BUF_SIZE];
int tmptype;

	// Initialization stuff
	tmpname[0]= 0;
	tmphost[0]= 0;
	tmpport[0]= 0;

	if (host)
		*host= 0;
	if (port) 
		*port= 0;
	if (name)
		*name= 0;

	// Look for a 'rpcap://' identifier
	if ( (ptr= strstr(source, PCAP_SRC_IF_STRING)) != NULL)
	{
		if (strlen(PCAP_SRC_IF_STRING) == strlen(source) )
		{
			// The source identifier contains only the 'rpcap://' string.
			// So, this is a local capture.
			*type= PCAP_SRC_IFLOCAL;
			return 0;
		}

		ptr+= strlen(PCAP_SRC_IF_STRING);

		if (strchr(ptr, '[')) // This is probably a numeric address
		{
			ntoken= sscanf(ptr, "[%[1234567890:.]]:%[^/]/%s", tmphost, tmpport, tmpname);

			if (ntoken == 1)	// probably the port is missing
				ntoken= sscanf(ptr, "[%[1234567890:.]]/%s", tmphost, tmpname);

			tmptype= PCAP_SRC_IFREMOTE;
		}
		else
		{
			ntoken= sscanf(ptr, "%[^/:]:%[^/]/%s", tmphost, tmpport, tmpname);

			if (ntoken == 1)
			{
				// This can be due to two reasons:
				// - we want a remote capture, but the network port is missing
				// - we want to do a local capture
				// To distinguish between the two, we look for the '/' char
				if (strchr(ptr, '/'))
				{
					// We're on a remote capture
					sscanf(ptr, "%[^/]/%s", tmphost, tmpname);
					tmptype= PCAP_SRC_IFREMOTE;
				}
				else
				{
					// We're on a local capture
					if (*ptr)
						strncpy(tmpname, ptr, PCAP_BUF_SIZE);

					// Clean the host name, since it is a remote capture
					// NOTE: the host name has been assigned in the previous "ntoken= sscanf(...)" line
					tmphost[0]= 0;

					tmptype= PCAP_SRC_IFLOCAL;
				}
			}
			else
				tmptype= PCAP_SRC_IFREMOTE;
		}

		if (host)
			strcpy(host, tmphost);
		if (port) 
			strcpy(port, tmpport);
		if (type)
			*type= tmptype;

		if (name)
		{
			// If the user wants the host name, but it cannot be located into the source string, return error
			// However, if the user is not interested in the interface name (e.g. if we're called by 
			// pcap_findalldevs_ex(), which does not have interface name, do not return error
			if (tmpname[0])
			{
				strcpy(name, tmpname);
			}
			else
			{
				if (errbuf)
					snprintf(errbuf, PCAP_ERRBUF_SIZE, "The interface name has not been specified in the source string.");

				return -1;

⌨️ 快捷键说明

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