📄 pcap-new.c
字号:
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;
}
}
}
/*! \ingroup wpcapfunc
\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_STRING 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. This source starts
with an identifier according to the new \link remote_source_string Source Specification Syntax
\endlink.
\param type: pointer to an integer, which is used to return the code corrisponding to the
selected source. The code will be one defined in the \link remote_source_ID Source identification
Codes \endlink.<br>
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.<br>
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_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;
}
}
return 0;
}
// Look for a 'file://' identifier
if ( (ptr= strstr(source, PCAP_SRC_FILE_STRING)) != NULL)
{
ptr+= strlen(PCAP_SRC_FILE_STRING);
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 in the source string.");
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 in the source string.");
return -1;
}
};
/*! \ingroup wpcapfunc
\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 new
\link remote_source_string Source Specification Syntax\endlink and it cannot be NULL.<br>
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 order to makes the source syntax easier, please remember that:
- the adapters returned by the pcap_findalldevs_ex() can be used immediately by the pcap_open()
- in case the user wants to pass its own source string to the pcap_open(), the
pcap_createsrcstr() helps in creating the correct source identifier.
\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 defined in the \link remote_open_flags pcap_open() flags \endlink.
\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.
\warning The following formats are not allowed as 'source' strings:
- rpcap:// [to open the first local adapter]
- rpcap://hostname/ [to open the first remote adapter]
*/
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 (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, errbuf);
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 linux
fp->md.timeout= read_timeout;
#else
fp->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 wpcapfunc
\brief It defines a sampling method for packet capture.
This function allows applying a sampling method to the packet capture process.
The currently sampling methods (and the way to set them) are described into the
struct pcap_samp. In other words, the user must set the appropriate parameters
into it; these will be applied as soon as the capture starts.
\warning Sampling parameters <strong>cannot</strong> be changed when a capture is
active. These parameters must be applied <strong>before</strong> starting the capture.
If they are applied when the capture is in progress, the new settings are ignored.
\warning Sampling works only when capturing data on Win32 or reading from a file.
It has not been implemented on other platforms. Sampling works on remote machines
provided that the probe (i.e. the capturing device) is a Win32 workstation.
*/
struct pcap_samp *pcap_setsampling(pcap_t *p)
{
return &(p->rmt_samp);
}
/*!
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -