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

📄 pcap-new.c

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

			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 (tmpname[0])
		{
			if (host)
				strcpy(host, tmphost);
			if (port) 
				strcpy(port, tmpport);
			if (name)
				strcpy(name, tmpname);
			if (type)
				*type= tmptype;

			return 0;
		}
		else
		{
			if (errbuf)
				snprintf(errbuf, PCAP_ERRBUF_SIZE, "The interface name has not been specified.");

			return -1;
		}
	}

	// Look for a 'file://' identifier
	if ( (ptr= strstr(source, PCAP_SRC_FILE_KEY)) != NULL)
	{
		ptr+= strlen(PCAP_SRC_FILE_KEY);
		if (*ptr)
		{
			if (name)
				strncpy(name, ptr, PCAP_BUF_SIZE);

			if (type)
				*type= PCAP_SRC_FILE;

			return 0;
		}
		else
		{
			if (errbuf)
				snprintf(errbuf, PCAP_ERRBUF_SIZE, "The file name has not been specified.");

			return -1;
		}

	}

	// Backward compatibility; the user didn't use the 'rpcap://, file://'  specifiers
	if ( (source) && (*source) )
	{
		if (name)
			strncpy(name, source, PCAP_BUF_SIZE);

		if (type)
			*type= PCAP_SRC_IFLOCAL;

		return 0;
	}
	else
	{
		if (errbuf)
			snprintf(errbuf, PCAP_ERRBUF_SIZE, "The interface name has not been specified.");

		return -1;
	}
};



/*!	\ingroup remote_func

	\brief It opens a generic source in order to capture / send (WinPcap only) traffic.
	
	The pcap_open() replaces all the pcap_open_xxx() functions with a single call.

	This function hides the differences between the different pcap_open_xxx() functions
	so that the programmer does not have to manage different opening function.
	In this way, the 'true' open function is decided according to the source type,
	which is included into the source string (in the form of source prefix).

	This function can rely on the pcap_createsrcstr() to create the string that keeps
	the capture device according to	the new syntax, and the pcap_parsesrcstr() for the
	other way round.

	\param source: zero-terminated string containing the source name to open.
	The source name has to include the format prefix according to the 
	syntax proposed by WinPcap. It cannot be NULL.
	On on Linux systems with 2.2 or later kernels, a device argument of "any"
	 (i.e. rpcap://any) can be used to capture packets from all interfaces.
	 <br>
	In case the pcap_createsrcstr() is not used, remember that the new source 
	syntax allows for these formats to be used in the pcap_open():
	- file://filename [we want to open a local file]
	- rpcap://host.foo.bar/adaptername [everything literal, no port number]
	- rpcap://host.foo.bar:1234/adaptername [everything literal, with port number]
	- rpcap://10.11.12.13/adaptername [IPv4 numeric, no port number]
	- rpcap://10.11.12.13:1234/adaptername [IPv4 numeric, with port number]
	- rpcap://[10.11.12.13]:1234/adaptername [IPv4 numeric with IPv6 format, with port number]
	- rpcap://[1:2:3::4]/adaptername [IPv6 numeric, no port number]
	- rpcap://[1:2:3::4]:1234/adaptername [IPv6 numeric, with port number]
	- rpcap://adaptername [local adapter, opened without using the RPCAP protocol]
	- adaptername [to open a local adapter; kept for compability, but it is strongly discouraged]
	- (NULL) [to open the first local adapter; kept for compability, but it is strongly discouraged]
	
	The following formats are not allowed:
	- rpcap:// [to open the first local adapter]
	- rpcap://hostname/ [to open the first remote adapter]

	\param snaplen: length of the packet that has to be retained.	
	For each packet received by the filter, only the first 'snaplen' bytes are stored 
	in the buffer and passed to the user application. For instance, snaplen equal to 
	100 means that only the first 100 bytes of each packet are stored.

  	\param flags: keeps several flags that can be needed for capturing packets.
	The allowed flags are the following:
	- PCAP_OPENFLAG_PROMISCUOUS: if the adapter has to go in promiscuous mode.		
	It is '1' if you have to open the adapter in promiscuous mode, '0' otherwise.
	Note that even if this parameter is false, the interface could well be in promiscuous
	mode for some other reason (for example because another capture process with 
	promiscuous mode enabled is currently using that interface).
	On on Linux systems with 2.2 or later kernels (that have the "any" device), this
	flag does not work on the "any" device; if an argument of "any" is supplied,
	the 'promisc' flag is ignored.
	- PCAP_OPENFLAG_SERVEROPEN_DP: it specifies who is responsible for opening the data
	connection in case of a remote capture (it means 'server open data path').
	If it is '1', it specifies if the data connection has to be intitiated 
	by the capturing device (which becomes like 'active'). If '0', the connection 
	will be initiated by the client workstation.
	This flag is used to overcome the problem of firewalls, which allow
	only outgoing connections. In that case, the capturing device can open
	a connection toward the client workstation in order to allow the
	data trasfer.
	In fact, the data connection is opened using a random port (while the
	control connection uses a standard port), so it is hard to configure
	a firewall to permit traffic on the data path.
	This flag is meaningless if the source is not a remote interface.
	Addictionally, it is meaningless if the data connection is done using
	the UDP protocol, since in this case the connection wil always be opened
	by the server.
	In these cases, it is simply ignored.
	- PCAP_OPENFLAG_UDP_DP: it specifies if the data trasfer (in case of a remote
	capture) has to be done with UDP protocol.
	If it is '1' if you want a UDP data connection, '0' if you want
	a TCP data connection; control connection is always TCP-based.
	A UDP connection is much lighter, but it does not guarantee that all
	the captured packets arrive to the client workstation. Moreover, 
	it could be harmful in case of network congestion.
	This flag is meaningless if the source is not a remote interface.
	In that case, it is simply ignored.

	\param read_timeout: read timeout in milliseconds.
	The read timeout is used to arrange that the read not necessarily return
	immediately when a packet is seen, but that it waits for some amount of 
	time to allow more packets to arrive and to read multiple packets from 
	the OS kernel in one operation. Not all platforms support a read timeout;
	on platforms that don't, the read timeout is ignored.

	\param auth: a pointer to a 'struct pcap_rmtauth' that keeps the information required to
	authenticate the user on a remote machine. In case this is not a remote capture, this
	pointer can be set to NULL.

	\param errbuf: a pointer to a user-allocated buffer which will contain the error
	in case this function fails. The pcap_open() and findalldevs() are the only two
	functions which have this parameter, since they do not have (yet) a pointer to a
	pcap_t structure, which reserves space for the error string. Since these functions
	do not have (yet) a pcap_t pointer (the pcap_t pointer is NULL in case of errors),
	they need an explicit 'errbuf' variable.
	'errbuf' may also be set to warning text when pcap_open_live() succeds; 
	to detect this case the caller should store a  zero-length string in  
	'errbuf' before calling pcap_open_live() and display the warning to the user 
	if 'errbuf' is no longer a zero-length string.

	\return A pointer to a 'pcap_t' which can be used as a parameter to the following
	calls (pcap_compile() and so on) and that specifies an opened WinPcap session. In case of 
	problems, it returns NULL and the 'errbuf' variable keeps the error message.

	\warning The source cannot be larger than PCAP_BUF_SIZE.
*/
pcap_t *pcap_open(const char *source, int snaplen, int flags, int read_timeout, struct pcap_rmtauth *auth, char *errbuf)
{
char host[PCAP_BUF_SIZE], port[PCAP_BUF_SIZE], name[PCAP_BUF_SIZE];
int type;
pcap_t *fp;

	if (strlen(source) > PCAP_BUF_SIZE)
	{
		snprintf(errbuf, PCAP_ERRBUF_SIZE, "The source string is too long. Cannot handle it correctly.");
		return NULL;
	}

	// determine the type of the source (NULL, file, local, remote)
	if (pcap_parsesrcstr(source, &type, host, port, name, errbuf) == -1)
		return NULL;


	switch (type) 
	{
		case PCAP_SRC_FILE:
			fp = pcap_open_offline(name, NULL);
			break;

		case PCAP_SRC_IFREMOTE:
			// Although we already have host, port and iface, we prefer TO PASS only 'pars' to the 
			// pcap_open_remote() so that it has to call the pcap_parsesrcstr() again.
			// This is less optimized, but much clearer.
			fp= pcap_opensource_remote(source, auth, errbuf);

			if (fp == NULL)
				return NULL;

			fp->snapshot= snaplen;
#ifdef WIN32
			fp->timeout= read_timeout;
#else
			fp->md.timeout= read_timeout;
#endif
			fp->rmt_flags= flags;
			break;

		case PCAP_SRC_IFLOCAL:
			fp= pcap_open_live(name, snaplen, (flags & PCAP_OPENFLAG_PROMISCUOUS), read_timeout, errbuf);
			break;

		default:
			strcpy(errbuf, "Source type not supported");
			return NULL;
	}
	return fp;
}



/*!	\ingroup remote_func

	\brief It blocks until a network connection is accepted (active mode only).

	This function has been defined to allow the client dealing with the 'active mode'.
	In other words, in the 'active mode' the server opens the connection toward the
	client, so that the client has to open a socket in order to wait for connections.
	When a new connection is accepted, the RPCAP protocol starts as usual; the only 
	difference is that the connection is initiated by the server.

	This function accepts only ONE connection, then it closes the waiting socket. This means
	that if some error occurs, the application has to call it again in order to accept another
	connection.

	This function returns when a new connection (coming from a valid host 'connectinghost')
	is accepted; it returns error otherwise.

	\param address: a string that keeps the network address we have to bind to; 
	usually it is NULL (it means 'bind on all local addresses').

	\param port: a string that keeps the network port on which we have to bind to; usually
	it is NULL (it means 'bind on the predefined port', i.e. RPCAP_DEFAULT_NETPORT_ACTIVE).

	\param hostlist: a string that keeps the host name of the host from whom we are
	expecting a connection; it can be NULL (it means 'accept connection from everyone').
	Host names are separated by a whatever character in the RPCAP_HOSTLIST_SEP list.

	\param connectinghost: a user-allocated buffer that will contain the name of the host
	is trying to connect to us.
	This variable must be at least RPCAP_HOSTLIST_SIZE bytes..

	\param auth: a pointer to a pcap_rmtauth structure. This pointer keeps the information
	required to authenticate the RPCAP connection to the remote host.

	\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 The SOCKET identifier of the new control connection if everything is fine,
	a negative number if some errors occurred. The error message is returned into the errbuf variable.
	In case it returns '-1', this means 'everything is fine', but the host cannot be admitted.
	In case it returns '-2', in means 'unrecoverable error' (for example it is not able to bind the 
	socket, or something like that).
	In case it returns '-3', it means 'authentication failed'. The authentication check is performed
	only if the connecting host is among the ones that are allowed to connect to this host.

	The host that is connecting to us is returned into the hostlist variable, which ust be allocated
	by the user. This variable contains the host name both in case the host is allowed, 
	and in case the connection is refused.

	\warning Although this function returns the socket established by the new control connection,
	this value should not be used. This value will be stored into some libpcap internal
	variables and it will be managed automatically by the library. In other words, all the
	following calls to findalldevs() and pcap_open() will check if the host is among one that
	already has a control connection in place; if so, that one will be used.

	\warning This function has several problems if used inside a thread, which is stopped
	when this call is blocked into the accept(). In this case, the socket on which we accept
	connections is not freed (thread termination is a very dirty job), so that we are no
	longer able to accept other connections until the program (i.e. the process) stops.
	In order to solve the problem, call the pcap_remoteact_cleanup().
*/
int pcap_remoteact_accept(const char *address, const char *port, const char *hostlist, char *connectinghost, struct pcap_rmtauth *auth, char *errbuf)

⌨️ 快捷键说明

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