|
Packit |
209cc3 |
/*
|
|
Packit |
209cc3 |
* Copyright (c) 2002 - 2005 NetGroup, Politecnico di Torino (Italy)
|
|
Packit |
209cc3 |
* Copyright (c) 2005 - 2008 CACE Technologies, Davis (California)
|
|
Packit |
209cc3 |
* All rights reserved.
|
|
Packit |
209cc3 |
*
|
|
Packit |
209cc3 |
* Redistribution and use in source and binary forms, with or without
|
|
Packit |
209cc3 |
* modification, are permitted provided that the following conditions
|
|
Packit |
209cc3 |
* are met:
|
|
Packit |
209cc3 |
*
|
|
Packit |
209cc3 |
* 1. Redistributions of source code must retain the above copyright
|
|
Packit |
209cc3 |
* notice, this list of conditions and the following disclaimer.
|
|
Packit |
209cc3 |
* 2. Redistributions in binary form must reproduce the above copyright
|
|
Packit |
209cc3 |
* notice, this list of conditions and the following disclaimer in the
|
|
Packit |
209cc3 |
* documentation and/or other materials provided with the distribution.
|
|
Packit |
209cc3 |
* 3. Neither the name of the Politecnico di Torino, CACE Technologies
|
|
Packit |
209cc3 |
* nor the names of its contributors may be used to endorse or promote
|
|
Packit |
209cc3 |
* products derived from this software without specific prior written
|
|
Packit |
209cc3 |
* permission.
|
|
Packit |
209cc3 |
*
|
|
Packit |
209cc3 |
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
Packit |
209cc3 |
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
Packit |
209cc3 |
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
Packit |
209cc3 |
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
Packit |
209cc3 |
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
Packit |
209cc3 |
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
Packit |
209cc3 |
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
Packit |
209cc3 |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
Packit |
209cc3 |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
Packit |
209cc3 |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
Packit |
209cc3 |
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
Packit |
209cc3 |
*
|
|
Packit |
209cc3 |
*/
|
|
Packit |
209cc3 |
|
|
Packit |
209cc3 |
#ifdef HAVE_CONFIG_H
|
|
Packit |
209cc3 |
#include <config.h>
|
|
Packit |
209cc3 |
#endif
|
|
Packit |
209cc3 |
|
|
Packit |
209cc3 |
#include "ftmacros.h"
|
|
Packit |
209cc3 |
|
|
Packit |
209cc3 |
/*
|
|
Packit |
209cc3 |
* sockutils.h may include <crtdbg.h> on Windows, and pcap-int.h will
|
|
Packit |
209cc3 |
* include portability.h, and portability.h, on Windows, expects that
|
|
Packit |
209cc3 |
* <crtdbg.h> has already been included, so include sockutils.h first.
|
|
Packit |
209cc3 |
*/
|
|
Packit |
209cc3 |
#include "sockutils.h"
|
|
Packit |
209cc3 |
#include "pcap-int.h" // for the details of the pcap_t structure
|
|
Packit |
209cc3 |
#include "pcap-rpcap.h"
|
|
Packit |
209cc3 |
#include "rpcap-protocol.h"
|
|
Packit |
209cc3 |
#include <errno.h> // for the errno variable
|
|
Packit |
209cc3 |
#include <stdlib.h> // for malloc(), free(), ...
|
|
Packit |
209cc3 |
#include <string.h> // for strstr, etc
|
|
Packit |
209cc3 |
|
|
Packit |
209cc3 |
#ifndef _WIN32
|
|
Packit |
209cc3 |
#include <dirent.h> // for readdir
|
|
Packit |
209cc3 |
#endif
|
|
Packit |
209cc3 |
|
|
Packit |
209cc3 |
/* String identifier to be used in the pcap_findalldevs_ex() */
|
|
Packit |
209cc3 |
#define PCAP_TEXT_SOURCE_FILE "File"
|
|
Packit |
209cc3 |
#define PCAP_TEXT_SOURCE_FILE_LEN (sizeof PCAP_TEXT_SOURCE_FILE - 1)
|
|
Packit |
209cc3 |
/* String identifier to be used in the pcap_findalldevs_ex() */
|
|
Packit |
209cc3 |
#define PCAP_TEXT_SOURCE_ADAPTER "Network adapter"
|
|
Packit |
209cc3 |
#define PCAP_TEXT_SOURCE_ADAPTER_LEN (sizeof "Network adapter" - 1)
|
|
Packit |
209cc3 |
|
|
Packit |
209cc3 |
/* String identifier to be used in the pcap_findalldevs_ex() */
|
|
Packit |
209cc3 |
#define PCAP_TEXT_SOURCE_ON_LOCAL_HOST "on local host"
|
|
Packit |
209cc3 |
#define PCAP_TEXT_SOURCE_ON_LOCAL_HOST_LEN (sizeof PCAP_TEXT_SOURCE_ON_LOCAL_HOST + 1)
|
|
Packit |
209cc3 |
|
|
Packit |
209cc3 |
/****************************************************
|
|
Packit |
209cc3 |
* *
|
|
Packit |
209cc3 |
* Function bodies *
|
|
Packit |
209cc3 |
* *
|
|
Packit |
209cc3 |
****************************************************/
|
|
Packit |
209cc3 |
|
|
Packit |
209cc3 |
int pcap_findalldevs_ex(const char *source, struct pcap_rmtauth *auth, pcap_if_t **alldevs, char *errbuf)
|
|
Packit |
209cc3 |
{
|
|
Packit |
209cc3 |
int type;
|
|
Packit |
209cc3 |
char name[PCAP_BUF_SIZE], path[PCAP_BUF_SIZE], filename[PCAP_BUF_SIZE];
|
|
Packit |
209cc3 |
size_t pathlen;
|
|
Packit |
209cc3 |
size_t stringlen;
|
|
Packit |
209cc3 |
pcap_t *fp;
|
|
Packit |
209cc3 |
char tmpstring[PCAP_BUF_SIZE + 1]; /* Needed to convert names and descriptions from 'old' syntax to the 'new' one */
|
|
Packit |
209cc3 |
pcap_if_t *lastdev; /* Last device in the pcap_if_t list */
|
|
Packit |
209cc3 |
pcap_if_t *dev; /* Device we're adding to the pcap_if_t list */
|
|
Packit |
209cc3 |
|
|
Packit |
209cc3 |
/* List starts out empty. */
|
|
Packit |
209cc3 |
(*alldevs) = NULL;
|
|
Packit |
209cc3 |
lastdev = NULL;
|
|
Packit |
209cc3 |
|
|
Packit |
209cc3 |
if (strlen(source) > PCAP_BUF_SIZE)
|
|
Packit |
209cc3 |
{
|
|
Packit |
209cc3 |
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "The source string is too long. Cannot handle it correctly.");
|
|
Packit |
209cc3 |
return -1;
|
|
Packit |
209cc3 |
}
|
|
Packit |
209cc3 |
|
|
Packit |
209cc3 |
/*
|
|
Packit |
209cc3 |
* Determine the type of the source (file, local, remote)
|
|
Packit |
209cc3 |
* There are some differences if pcap_findalldevs_ex() is called to list files and remote adapters.
|
|
Packit |
209cc3 |
* In the first case, the name of the directory we have to look into must be present (therefore
|
|
Packit |
209cc3 |
* the 'name' parameter of the pcap_parsesrcstr() is present).
|
|
Packit |
209cc3 |
* In the second case, the name of the adapter is not required (we need just the host). So, we have
|
|
Packit |
209cc3 |
* to use a first time this function to get the source type, and a second time to get the appropriate
|
|
Packit |
209cc3 |
* info, which depends on the source type.
|
|
Packit |
209cc3 |
*/
|
|
Packit |
209cc3 |
if (pcap_parsesrcstr(source, &type, NULL, NULL, NULL, errbuf) == -1)
|
|
Packit |
209cc3 |
return -1;
|
|
Packit |
209cc3 |
|
|
Packit |
209cc3 |
switch (type)
|
|
Packit |
209cc3 |
{
|
|
Packit |
209cc3 |
case PCAP_SRC_IFLOCAL:
|
|
Packit |
209cc3 |
if (pcap_parsesrcstr(source, &type, NULL, NULL, NULL, errbuf) == -1)
|
|
Packit |
209cc3 |
return -1;
|
|
Packit |
209cc3 |
|
|
Packit |
209cc3 |
/* Initialize temporary string */
|
|
Packit |
209cc3 |
tmpstring[PCAP_BUF_SIZE] = 0;
|
|
Packit |
209cc3 |
|
|
Packit |
209cc3 |
/* The user wants to retrieve adapters from a local host */
|
|
Packit |
209cc3 |
if (pcap_findalldevs(alldevs, errbuf) == -1)
|
|
Packit |
209cc3 |
return -1;
|
|
Packit |
209cc3 |
|
|
Packit |
209cc3 |
if (*alldevs == NULL)
|
|
Packit |
209cc3 |
{
|
|
Packit |
209cc3 |
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
|
Packit |
209cc3 |
"No interfaces found! Make sure libpcap/Npcap is properly installed"
|
|
Packit |
209cc3 |
" on the local machine.");
|
|
Packit |
209cc3 |
return -1;
|
|
Packit |
209cc3 |
}
|
|
Packit |
209cc3 |
|
|
Packit |
209cc3 |
/* Scan all the interfaces and modify name and description */
|
|
Packit |
209cc3 |
/* This is a trick in order to avoid the re-implementation of the pcap_findalldevs here */
|
|
Packit |
209cc3 |
dev = *alldevs;
|
|
Packit |
209cc3 |
while (dev)
|
|
Packit |
209cc3 |
{
|
|
Packit |
209cc3 |
char *localdesc, *desc;
|
|
Packit |
209cc3 |
|
|
Packit |
209cc3 |
/* Create the new device identifier */
|
|
Packit |
209cc3 |
if (pcap_createsrcstr(tmpstring, PCAP_SRC_IFLOCAL, NULL, NULL, dev->name, errbuf) == -1)
|
|
Packit |
209cc3 |
return -1;
|
|
Packit |
209cc3 |
|
|
Packit |
209cc3 |
/* Delete the old pointer */
|
|
Packit |
209cc3 |
free(dev->name);
|
|
Packit |
209cc3 |
|
|
Packit |
209cc3 |
/* Make a copy of the new device identifier */
|
|
Packit |
209cc3 |
dev->name = strdup(tmpstring);
|
|
Packit |
209cc3 |
if (dev->name == NULL)
|
|
Packit |
209cc3 |
{
|
|
Packit |
209cc3 |
pcap_fmt_errmsg_for_errno(errbuf,
|
|
Packit |
209cc3 |
PCAP_ERRBUF_SIZE, errno,
|
|
Packit |
209cc3 |
"malloc() failed");
|
|
Packit |
209cc3 |
pcap_freealldevs(*alldevs);
|
|
Packit |
209cc3 |
return -1;
|
|
Packit |
209cc3 |
}
|
|
Packit |
209cc3 |
|
|
Packit |
209cc3 |
/*
|
|
Packit |
209cc3 |
* Create the description.
|
|
Packit |
209cc3 |
*/
|
|
Packit |
209cc3 |
if ((dev->description == NULL) || (dev->description[0] == 0))
|
|
Packit |
209cc3 |
localdesc = dev->name;
|
|
Packit |
209cc3 |
else
|
|
Packit |
209cc3 |
localdesc = dev->description;
|
|
Packit |
209cc3 |
if (pcap_asprintf(&desc, "%s '%s' %s",
|
|
Packit |
209cc3 |
PCAP_TEXT_SOURCE_ADAPTER, localdesc,
|
|
Packit |
209cc3 |
PCAP_TEXT_SOURCE_ON_LOCAL_HOST) == -1)
|
|
Packit |
209cc3 |
{
|
|
Packit |
209cc3 |
pcap_fmt_errmsg_for_errno(errbuf,
|
|
Packit |
209cc3 |
PCAP_ERRBUF_SIZE, errno,
|
|
Packit |
209cc3 |
"malloc() failed");
|
|
Packit |
209cc3 |
pcap_freealldevs(*alldevs);
|
|
Packit |
209cc3 |
return -1;
|
|
Packit |
209cc3 |
}
|
|
Packit |
209cc3 |
|
|
Packit |
209cc3 |
/* Now overwrite the description */
|
|
Packit |
209cc3 |
free(dev->description);
|
|
Packit |
209cc3 |
dev->description = desc;
|
|
Packit |
209cc3 |
|
|
Packit |
209cc3 |
dev = dev->next;
|
|
Packit |
209cc3 |
}
|
|
Packit |
209cc3 |
|
|
Packit |
209cc3 |
return 0;
|
|
Packit |
209cc3 |
|
|
Packit |
209cc3 |
case PCAP_SRC_FILE:
|
|
Packit |
209cc3 |
{
|
|
Packit |
209cc3 |
#ifdef _WIN32
|
|
Packit |
209cc3 |
WIN32_FIND_DATA filedata;
|
|
Packit |
209cc3 |
HANDLE filehandle;
|
|
Packit |
209cc3 |
#else
|
|
Packit |
209cc3 |
struct dirent *filedata;
|
|
Packit |
209cc3 |
DIR *unixdir;
|
|
Packit |
209cc3 |
#endif
|
|
Packit |
209cc3 |
|
|
Packit |
209cc3 |
if (pcap_parsesrcstr(source, &type, NULL, NULL, name, errbuf) == -1)
|
|
Packit |
209cc3 |
return -1;
|
|
Packit |
209cc3 |
|
|
Packit |
209cc3 |
/* Check that the filename is correct */
|
|
Packit |
209cc3 |
stringlen = strlen(name);
|
|
Packit |
209cc3 |
|
|
Packit |
209cc3 |
/* The directory must end with '\' in Win32 and '/' in UNIX */
|
|
Packit |
209cc3 |
#ifdef _WIN32
|
|
Packit |
209cc3 |
#define ENDING_CHAR '\\'
|
|
Packit |
209cc3 |
#else
|
|
Packit |
209cc3 |
#define ENDING_CHAR '/'
|
|
Packit |
209cc3 |
#endif
|
|
Packit |
209cc3 |
|
|
Packit |
209cc3 |
if (name[stringlen - 1] != ENDING_CHAR)
|
|
Packit |
209cc3 |
{
|
|
Packit |
209cc3 |
name[stringlen] = ENDING_CHAR;
|
|
Packit |
209cc3 |
name[stringlen + 1] = 0;
|
|
Packit |
209cc3 |
|
|
Packit |
209cc3 |
stringlen++;
|
|
Packit |
209cc3 |
}
|
|
Packit |
209cc3 |
|
|
Packit |
209cc3 |
/* Save the path for future reference */
|
|
Packit |
209cc3 |
pcap_snprintf(path, sizeof(path), "%s", name);
|
|
Packit |
209cc3 |
pathlen = strlen(path);
|
|
Packit |
209cc3 |
|
|
Packit |
209cc3 |
#ifdef _WIN32
|
|
Packit |
209cc3 |
/* To perform directory listing, Win32 must have an 'asterisk' as ending char */
|
|
Packit |
209cc3 |
if (name[stringlen - 1] != '*')
|
|
Packit |
209cc3 |
{
|
|
Packit |
209cc3 |
name[stringlen] = '*';
|
|
Packit |
209cc3 |
name[stringlen + 1] = 0;
|
|
Packit |
209cc3 |
}
|
|
Packit |
209cc3 |
|
|
Packit |
209cc3 |
filehandle = FindFirstFile(name, &filedata);
|
|
Packit |
209cc3 |
|
|
Packit |
209cc3 |
if (filehandle == INVALID_HANDLE_VALUE)
|
|
Packit |
209cc3 |
{
|
|
Packit |
209cc3 |
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Error when listing files: does folder '%s' exist?", path);
|
|
Packit |
209cc3 |
return -1;
|
|
Packit |
209cc3 |
}
|
|
Packit |
209cc3 |
|
|
Packit |
209cc3 |
#else
|
|
Packit |
209cc3 |
/* opening the folder */
|
|
Packit |
209cc3 |
unixdir= opendir(path);
|
|
Packit |
209cc3 |
|
|
Packit |
209cc3 |
/* get the first file into it */
|
|
Packit |
209cc3 |
filedata= readdir(unixdir);
|
|
Packit |
209cc3 |
|
|
Packit |
209cc3 |
if (filedata == NULL)
|
|
Packit |
209cc3 |
{
|
|
Packit |
209cc3 |
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Error when listing files: does folder '%s' exist?", path);
|
|
Packit |
209cc3 |
return -1;
|
|
Packit |
209cc3 |
}
|
|
Packit |
209cc3 |
#endif
|
|
Packit |
209cc3 |
|
|
Packit |
209cc3 |
/* Add all files we find to the list. */
|
|
Packit |
209cc3 |
do
|
|
Packit |
209cc3 |
{
|
|
Packit |
209cc3 |
#ifdef _WIN32
|
|
Packit |
209cc3 |
/* Skip the file if the pathname won't fit in the buffer */
|
|
Packit |
209cc3 |
if (pathlen + strlen(filedata.cFileName) >= sizeof(filename))
|
|
Packit |
209cc3 |
continue;
|
|
Packit |
209cc3 |
pcap_snprintf(filename, sizeof(filename), "%s%s", path, filedata.cFileName);
|
|
Packit |
209cc3 |
#else
|
|
Packit |
209cc3 |
if (pathlen + strlen(filedata->d_name) >= sizeof(filename))
|
|
Packit |
209cc3 |
continue;
|
|
Packit |
209cc3 |
pcap_snprintf(filename, sizeof(filename), "%s%s", path, filedata->d_name);
|
|
Packit |
209cc3 |
#endif
|
|
Packit |
209cc3 |
|
|
Packit |
209cc3 |
fp = pcap_open_offline(filename, errbuf);
|
|
Packit |
209cc3 |
|
|
Packit |
209cc3 |
if (fp)
|
|
Packit |
209cc3 |
{
|
|
Packit |
209cc3 |
/* allocate the main structure */
|
|
Packit |
209cc3 |
dev = (pcap_if_t *)malloc(sizeof(pcap_if_t));
|
|
Packit |
209cc3 |
if (dev == NULL)
|
|
Packit |
209cc3 |
{
|
|
Packit |
209cc3 |
pcap_fmt_errmsg_for_errno(errbuf,
|
|
Packit |
209cc3 |
PCAP_ERRBUF_SIZE, errno,
|
|
Packit |
209cc3 |
"malloc() failed");
|
|
Packit |
209cc3 |
pcap_freealldevs(*alldevs);
|
|
Packit |
209cc3 |
return -1;
|
|
Packit |
209cc3 |
}
|
|
Packit |
209cc3 |
|
|
Packit |
209cc3 |
/* Initialize the structure to 'zero' */
|
|
Packit |
209cc3 |
memset(dev, 0, sizeof(pcap_if_t));
|
|
Packit |
209cc3 |
|
|
Packit |
209cc3 |
/* Append it to the list. */
|
|
Packit |
209cc3 |
if (lastdev == NULL)
|
|
Packit |
209cc3 |
{
|
|
Packit |
209cc3 |
/*
|
|
Packit |
209cc3 |
* List is empty, so it's also
|
|
Packit |
209cc3 |
* the first device.
|
|
Packit |
209cc3 |
*/
|
|
Packit |
209cc3 |
*alldevs = dev;
|
|
Packit |
209cc3 |
}
|
|
Packit |
209cc3 |
else
|
|
Packit |
209cc3 |
{
|
|
Packit |
209cc3 |
/*
|
|
Packit |
209cc3 |
* Append after the last device.
|
|
Packit |
209cc3 |
*/
|
|
Packit |
209cc3 |
lastdev->next = dev;
|
|
Packit |
209cc3 |
}
|
|
Packit |
209cc3 |
/* It's now the last device. */
|
|
Packit |
209cc3 |
lastdev = dev;
|
|
Packit |
209cc3 |
|
|
Packit |
209cc3 |
/* Create the new source identifier */
|
|
Packit |
209cc3 |
if (pcap_createsrcstr(tmpstring, PCAP_SRC_FILE, NULL, NULL, filename, errbuf) == -1)
|
|
Packit |
209cc3 |
{
|
|
Packit |
209cc3 |
pcap_freealldevs(*alldevs);
|
|
Packit |
209cc3 |
return -1;
|
|
Packit |
209cc3 |
}
|
|
Packit |
209cc3 |
|
|
Packit |
209cc3 |
dev->name = strdup(tmpstring);
|
|
Packit |
209cc3 |
if (dev->name == NULL)
|
|
Packit |
209cc3 |
{
|
|
Packit |
209cc3 |
pcap_fmt_errmsg_for_errno(errbuf,
|
|
Packit |
209cc3 |
PCAP_ERRBUF_SIZE, errno,
|
|
Packit |
209cc3 |
"malloc() failed");
|
|
Packit |
209cc3 |
pcap_freealldevs(*alldevs);
|
|
Packit |
209cc3 |
return -1;
|
|
Packit |
209cc3 |
}
|
|
Packit |
209cc3 |
|
|
Packit |
209cc3 |
/*
|
|
Packit |
209cc3 |
* Create the description.
|
|
Packit |
209cc3 |
*/
|
|
Packit |
209cc3 |
if (pcap_asprintf(&dev->description,
|
|
Packit |
209cc3 |
"%s '%s' %s", PCAP_TEXT_SOURCE_FILE,
|
|
Packit |
209cc3 |
filename, PCAP_TEXT_SOURCE_ON_LOCAL_HOST) == -1)
|
|
Packit |
209cc3 |
{
|
|
Packit |
209cc3 |
pcap_fmt_errmsg_for_errno(errbuf,
|
|
Packit |
209cc3 |
PCAP_ERRBUF_SIZE, errno,
|
|
Packit |
209cc3 |
"malloc() failed");
|
|
Packit |
209cc3 |
pcap_freealldevs(*alldevs);
|
|
Packit |
209cc3 |
return -1;
|
|
Packit |
209cc3 |
}
|
|
Packit |
209cc3 |
|
|
Packit |
209cc3 |
pcap_close(fp);
|
|
Packit |
209cc3 |
}
|
|
Packit |
209cc3 |
}
|
|
Packit |
209cc3 |
#ifdef _WIN32
|
|
Packit |
209cc3 |
while (FindNextFile(filehandle, &filedata) != 0);
|
|
Packit |
209cc3 |
#else
|
|
Packit |
209cc3 |
while ( (filedata= readdir(unixdir)) != NULL);
|
|
Packit |
209cc3 |
#endif
|
|
Packit |
209cc3 |
|
|
Packit |
209cc3 |
|
|
Packit |
209cc3 |
#ifdef _WIN32
|
|
Packit |
209cc3 |
/* Close the search handle. */
|
|
Packit |
209cc3 |
FindClose(filehandle);
|
|
Packit |
209cc3 |
#endif
|
|
Packit |
209cc3 |
|
|
Packit |
209cc3 |
return 0;
|
|
Packit |
209cc3 |
}
|
|
Packit |
209cc3 |
|
|
Packit |
209cc3 |
case PCAP_SRC_IFREMOTE:
|
|
Packit |
209cc3 |
return pcap_findalldevs_ex_remote(source, auth, alldevs, errbuf);
|
|
Packit |
209cc3 |
|
|
Packit |
209cc3 |
default:
|
|
Packit |
209cc3 |
pcap_strlcpy(errbuf, "Source type not supported", PCAP_ERRBUF_SIZE);
|
|
Packit |
209cc3 |
return -1;
|
|
Packit |
209cc3 |
}
|
|
Packit |
209cc3 |
}
|
|
Packit |
209cc3 |
|
|
Packit |
209cc3 |
pcap_t *pcap_open(const char *source, int snaplen, int flags, int read_timeout, struct pcap_rmtauth *auth, char *errbuf)
|
|
Packit |
209cc3 |
{
|
|
Packit |
209cc3 |
char name[PCAP_BUF_SIZE];
|
|
Packit |
209cc3 |
int type;
|
|
Packit |
209cc3 |
pcap_t *fp;
|
|
Packit |
209cc3 |
int status;
|
|
Packit |
209cc3 |
|
|
Packit |
209cc3 |
/*
|
|
Packit |
209cc3 |
* A null device name is equivalent to the "any" device -
|
|
Packit |
209cc3 |
* which might not be supported on this platform, but
|
|
Packit |
209cc3 |
* this means that you'll get a "not supported" error
|
|
Packit |
209cc3 |
* rather than, say, a crash when we try to dereference
|
|
Packit |
209cc3 |
* the null pointer.
|
|
Packit |
209cc3 |
*/
|
|
Packit |
209cc3 |
if (source == NULL)
|
|
Packit |
209cc3 |
source = "any";
|
|
Packit |
209cc3 |
|
|
Packit |
209cc3 |
if (strlen(source) > PCAP_BUF_SIZE)
|
|
Packit |
209cc3 |
{
|
|
Packit |
209cc3 |
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "The source string is too long. Cannot handle it correctly.");
|
|
Packit |
209cc3 |
return NULL;
|
|
Packit |
209cc3 |
}
|
|
Packit |
209cc3 |
|
|
Packit |
209cc3 |
/*
|
|
Packit |
209cc3 |
* Determine the type of the source (file, local, remote) and,
|
|
Packit |
209cc3 |
* if it's file or local, the name of the file or capture device.
|
|
Packit |
209cc3 |
*/
|
|
Packit |
209cc3 |
if (pcap_parsesrcstr(source, &type, NULL, NULL, name, errbuf) == -1)
|
|
Packit |
209cc3 |
return NULL;
|
|
Packit |
209cc3 |
|
|
Packit |
209cc3 |
switch (type)
|
|
Packit |
209cc3 |
{
|
|
Packit |
209cc3 |
case PCAP_SRC_FILE:
|
|
Packit |
209cc3 |
return pcap_open_offline(name, errbuf);
|
|
Packit |
209cc3 |
|
|
Packit |
209cc3 |
case PCAP_SRC_IFLOCAL:
|
|
Packit |
209cc3 |
fp = pcap_create(name, errbuf);
|
|
Packit |
209cc3 |
break;
|
|
Packit |
209cc3 |
|
|
Packit |
209cc3 |
case PCAP_SRC_IFREMOTE:
|
|
Packit |
209cc3 |
/*
|
|
Packit |
209cc3 |
* Although we already have host, port and iface, we prefer
|
|
Packit |
209cc3 |
* to pass only 'source' to pcap_open_rpcap(), so that it
|
|
Packit |
209cc3 |
* has to call pcap_parsesrcstr() again.
|
|
Packit |
209cc3 |
* This is less optimized, but much clearer.
|
|
Packit |
209cc3 |
*/
|
|
Packit |
209cc3 |
return pcap_open_rpcap(source, snaplen, flags, read_timeout, auth, errbuf);
|
|
Packit |
209cc3 |
|
|
Packit |
209cc3 |
default:
|
|
Packit |
209cc3 |
pcap_strlcpy(errbuf, "Source type not supported", PCAP_ERRBUF_SIZE);
|
|
Packit |
209cc3 |
return NULL;
|
|
Packit |
209cc3 |
}
|
|
Packit |
209cc3 |
|
|
Packit |
209cc3 |
if (fp == NULL)
|
|
Packit |
209cc3 |
return (NULL);
|
|
Packit |
209cc3 |
status = pcap_set_snaplen(fp, snaplen);
|
|
Packit |
209cc3 |
if (status < 0)
|
|
Packit |
209cc3 |
goto fail;
|
|
Packit |
209cc3 |
if (flags & PCAP_OPENFLAG_PROMISCUOUS)
|
|
Packit |
209cc3 |
{
|
|
Packit |
209cc3 |
status = pcap_set_promisc(fp, 1);
|
|
Packit |
209cc3 |
if (status < 0)
|
|
Packit |
209cc3 |
goto fail;
|
|
Packit |
209cc3 |
}
|
|
Packit |
209cc3 |
if (flags & PCAP_OPENFLAG_MAX_RESPONSIVENESS)
|
|
Packit |
209cc3 |
{
|
|
Packit |
209cc3 |
status = pcap_set_immediate_mode(fp, 1);
|
|
Packit |
209cc3 |
if (status < 0)
|
|
Packit |
209cc3 |
goto fail;
|
|
Packit |
209cc3 |
}
|
|
Packit |
209cc3 |
#ifdef _WIN32
|
|
Packit |
209cc3 |
/*
|
|
Packit |
209cc3 |
* This flag is supported on Windows only.
|
|
Packit |
209cc3 |
* XXX - is there a way to support it with
|
|
Packit |
209cc3 |
* the capture mechanisms on UN*X? It's not
|
|
Packit |
209cc3 |
* exactly a "set direction" operation; I
|
|
Packit |
209cc3 |
* think it means "do not capture packets
|
|
Packit |
209cc3 |
* injected with pcap_sendpacket() or
|
|
Packit |
209cc3 |
* pcap_inject()".
|
|
Packit |
209cc3 |
*/
|
|
Packit |
209cc3 |
/* disable loopback capture if requested */
|
|
Packit |
209cc3 |
if (flags & PCAP_OPENFLAG_NOCAPTURE_LOCAL)
|
|
Packit |
209cc3 |
fp->opt.nocapture_local = 1;
|
|
Packit |
209cc3 |
#endif /* _WIN32 */
|
|
Packit |
209cc3 |
status = pcap_set_timeout(fp, read_timeout);
|
|
Packit |
209cc3 |
if (status < 0)
|
|
Packit |
209cc3 |
goto fail;
|
|
Packit |
209cc3 |
status = pcap_activate(fp);
|
|
Packit |
209cc3 |
if (status < 0)
|
|
Packit |
209cc3 |
goto fail;
|
|
Packit |
209cc3 |
return fp;
|
|
Packit |
209cc3 |
|
|
Packit |
209cc3 |
fail:
|
|
Packit |
209cc3 |
if (status == PCAP_ERROR)
|
|
Packit |
209cc3 |
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s",
|
|
Packit |
209cc3 |
name, fp->errbuf);
|
|
Packit |
209cc3 |
else if (status == PCAP_ERROR_NO_SUCH_DEVICE ||
|
|
Packit |
209cc3 |
status == PCAP_ERROR_PERM_DENIED ||
|
|
Packit |
209cc3 |
status == PCAP_ERROR_PROMISC_PERM_DENIED)
|
|
Packit |
209cc3 |
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s (%s)",
|
|
Packit |
209cc3 |
name, pcap_statustostr(status), fp->errbuf);
|
|
Packit |
209cc3 |
else
|
|
Packit |
209cc3 |
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s",
|
|
Packit |
209cc3 |
name, pcap_statustostr(status));
|
|
Packit |
209cc3 |
pcap_close(fp);
|
|
Packit |
209cc3 |
return NULL;
|
|
Packit |
209cc3 |
}
|
|
Packit |
209cc3 |
|
|
Packit |
209cc3 |
struct pcap_samp *pcap_setsampling(pcap_t *p)
|
|
Packit |
209cc3 |
{
|
|
Packit |
209cc3 |
return &p->rmt_samp;
|
|
Packit |
209cc3 |
}
|