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

📄 pcap-new.c

📁 用来监视网络通信数据的源代码和应用程序,方便网络程序底层开发.
💻 C
📖 第 1 页 / 共 4 页
字号:
#endif

		return 0;
	}

	// If we come here, it is a remote host

	// Retrieve the needed data for getting adapter list
	if (pcap_parsesrcstr(source, &type, host, port, NULL, errbuf) == -1)
		return -1;

	// Warning: this call can be the first one called by the user.
	// For this reason, we have to initialize the WinSock support.
	if (sock_init(errbuf, PCAP_ERRBUF_SIZE) == -1)
		return -1;

	// Check for active mode
	if ( (retval= rpcap_remoteact_getsock(host, errbuf)) == -1)
		return -1;

	if (retval)
	{
		sockctrl= retval;
		active= 1;
	}
	else	// we're not in active mode; let's opening a new control connection (if needed)
	{
		addrinfo= NULL;

		memset(&hints, 0, sizeof(struct addrinfo) );
		hints.ai_family = PF_UNSPEC;
		hints.ai_socktype = SOCK_STREAM;

		if ( (port == NULL) || (port[0] == 0) )
		{
			// the user chose not to specify the port
			if (sock_initaddress(host, RPCAP_DEFAULT_NETPORT, &hints, &addrinfo, errbuf, PCAP_ERRBUF_SIZE) == -1)
				return -1;
		}
		else
		{
			if (sock_initaddress(host, port, &hints, &addrinfo, errbuf, PCAP_ERRBUF_SIZE) == -1)
				return -1;
		}

		if ( (sockctrl= sock_open(addrinfo, SOCKOPEN_CLIENT, 0, errbuf, PCAP_ERRBUF_SIZE)) == -1)
			goto error;

		// addrinfo is no longer used
		freeaddrinfo(addrinfo);
		addrinfo= NULL;

		if ( rpcap_sendauth(sockctrl, auth, errbuf) == -1)
		{
			// Control connection has to be closed only in case the remote machine is in passive mode
			if (!active)
				sock_close(sockctrl, NULL, 0);
			return -1;
		}
	}

	// RPCAP findalldevs command
	rpcap_createhdr(&header, RPCAP_MSG_FINDALLIF_REQ, 0, 0);

	if ( sock_send(sockctrl, (char *) &header, sizeof(struct rpcap_header), errbuf, PCAP_ERRBUF_SIZE) == -1 )
		goto error;

	if ( sock_recv(sockctrl, (char *) &header, sizeof(struct rpcap_header), SOCK_RECEIVEALL_YES, errbuf, PCAP_ERRBUF_SIZE) == -1)
		goto error;

	// Checks if the message is correct
	retval= rpcap_checkmsg(errbuf, sockctrl, &header, RPCAP_MSG_FINDALLIF_REPLY, RPCAP_MSG_ERROR, 0);

	if (retval != RPCAP_MSG_FINDALLIF_REPLY)		// the message is not the one expected
	{
		switch (retval)
		{
			case -3:	// Unrecoverable network error
			case -2:	// The other endpoint send a message that is not allowed here
			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;
}




/*! \ingroup wpcapfunc
	\brief Accepts a set of strings (host name, port, ...), and it returns the complete 
	source string according to the new format (e.g. 'rpcap://1.2.3.4/eth0').

	This function is provided in order to help the user creating the source string
	according to the new format.
	An unique source string is used in order to make easy for old applications to use the
	remote facilities. Think about tcpdump, for example, which has only one way to specify
	the interface on which the capture has to be started.
	However, GUI-based programs can find more useful to specify hostname, port and
	interface name separately. In that case, they can use this function to create the 
	source string before passing it to the pcap_open() function.

	\param source: a user-allocated buffer that will contain the complete source string
	wen the function returns.<br>
	The source will start with an identifier according to the new \link remote_source_string 
	Source Specification Syntax	\endlink.<br>
	This function assumes that the allocated buffer is at least PCAP_BUF_SIZE bytes.

	\param type: its value tells the type of the source we want to create. It can assume 
	the values defined in the \link remote_source_ID Source identification
	Codes \endlink.<br>

	\param host: an user-allocated buffer that keeps the host (e.g. "foo.bar.com") we 
	want to connect to.
	It can be NULL in case we want to open an interface on a local host.

	\param port: an user-allocated buffer that keeps the network port (e.g. "2002") we 
	want to use for the RPCAP protocol.
	It can be NULL in case we want to open an interface on a local host.

	\param name: an user-allocated buffer that keeps the interface name we want to use
	(e.g. "eth0").
	It can be NULL in case the return string (i.e. 'source') has to be used with the
	pcap_findalldevs_ex(), which does not require the interface name.

	\param errbuf: a pointer to a user-allocated buffer (of size PCAP_ERRBUF_SIZE)
	that will contain the error message (in case there is one).

	\return '0' if everything is fine, '-1' if some errors occurred. The string containing
	the complete source is returned in the 'source' variable.

	\warning If the source is longer than PCAP_BUF_SIZE, the excess characters are truncated.
*/
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);
				}

⌨️ 快捷键说明

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