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

📄 pcap-new.c

📁 用来监视网络通信数据的源代码和应用程序,方便网络程序底层开发.
💻 C
📖 第 1 页 / 共 4 页
字号:
			if ( (nread+= sock_recv(sockctrl, dev->description, findalldevs_if.desclen, errbuf) ) == -1)
				goto error;
			dev->description[findalldevs_if.desclen]= 0;
		}
		else
			dev->description= NULL;

		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), errbuf) ) == -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) == 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) )
			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, fakeerrbuf) == 1)
			return -1;
	}

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

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

	return -1;
}




/*! \ingroup remote_func
	\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 to create 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.
	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 following values:
	- PCAP_SRC_FILE: if we want a local file
	- PCAP_SRC_IFLOCAL: if we want a local interface
	- PCAP_SRC_IFREMOTE: if we want a remote interface

	\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").

	\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_KEY, 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_KEY, 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;
			}
			else
			{
				snprintf(errbuf, PCAP_ERRBUF_SIZE, "The interface name cannot be NULL.");
				return -1;
			}
		}
		case PCAP_SRC_IFLOCAL:
		{
			strncpy(source, PCAP_SRC_IF_KEY, PCAP_BUF_SIZE);
			if ((name) && (*name) )
			{
				strncat(source, name, PCAP_BUF_SIZE);
				return 0;
			}
			else
			{
				snprintf(errbuf, PCAP_ERRBUF_SIZE, "The interface name cannot be NULL.");
				return -1;
			}
		}
		default:
		{
			snprintf(errbuf, PCAP_ERRBUF_SIZE, "The interface type is not valid.");
			return -1;
		}
	}
}




/*! \ingroup remote_func
	\brief Parses the source string and returns the pieces in which the source can be split.

	This call is the other way round of pcap_createsrcstr().
	It accepts a null-terminated string and it returns the parameters related 
	to the source. This includes:
	- the type of the source (file, winpcap on a remote adapter, winpcap on local adapter),
	which is determined by the source prefix (PCAP_SRC_IF_KEY and so on)
	- the host on which the capture has to be started (only for remote captures)
	- the 'raw' name of the source (file name, name of the remote adapter, name 
	of the local adapter), without the source prefix. The string returned does not 
	include the type of the source itself (i.e. the string returned does not include "file://" 
	or rpcap:// or such).

	The user can omit some parameters in case it is not interested in them.

	\param source: a null-terminated string containing the WinPcap source

	\param type: pointer to an integer, which is used to return the code corrisponding to the 
	selected source. The code will be one of the following:
		- PCAP_SRC_FILE
		- PCAP_SRC_IFLOCAL
		- PCAP_SRC_IFREMOTE
	In case the source string does not exists (i.e. 'source == NULL') or it is empty
	('*source == NULL'), it returns PCAP_SRC_IF_LOCAL (i.e. you are ready to 
	call pcap_open_live() ). This behavior is kept only for compatibility with older 
	applications (e.g. tcpdump); therefore we suggest to move to the new syntax for sources.

	This parameter can be NULL in case the user is not interested in that.

	\param host: user-allocated buffer (of size PCAP_BUF_SIZE) that is used to return 
	the host name on which the capture has to be started.
	This value is meaningful only in case of remote capture; otherwise, the returned 
	string will be empty ("").
	This parameter can be NULL in case the user is not interested in that.

	\param port: user-allocated buffer (of size PCAP_BUF_SIZE) that is used to return 
	the port that has to be used by the RPCAP protocol to contact the other host.
	This value is meaningful only in case of remote capture and if the user wants to use
	a non-standard port; otherwise, the returned string will be empty ("").
	In case of remote capture, an emply string means "use the standard RPCAP port".
	This parameter can be NULL in case the user is not interested in that.

	\param name: user-allocated buffer (of size PCAP_BUF_SIZE) that is used to return 
	the source name, without the source prefix.
	If the name does not exist (for example because source contains 'rpcap://' that means 
	'default local adapter'), it returns NULL.
	This parameter can be NULL in case the user is not interested in that.

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

	\return '0' if everything is fine, '-1' if some errors occurred. The requested values
	(host name, network port, type of the source) are returned into the proper variables
	passed by reference.
*/
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_KEY)) != NULL)
	{
		ptr+= strlen(PCAP_SRC_IF_KEY);

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

⌨️ 快捷键说明

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