Feature #5499 ยป pcapoverip.diff
src/source-pcap-file-helper.c | ||
---|---|---|
return true;
|
||
}
|
||
TmEcode RunPcapOverIP(PcapFileFileVars *pfv)
|
||
{
|
||
char errbuf[PCAP_ERRBUF_SIZE] = "";
|
||
int sockfd;
|
||
struct sockaddr_in server_addr;
|
||
FILE *file;
|
||
char *ip = NULL;
|
||
int port = 0;
|
||
if(unlikely(pfv->filename == NULL)) {
|
||
SCLogError("Filename was null");
|
||
SCReturnInt(TM_ECODE_FAILED);
|
||
}
|
||
// Parse the filename to extract IP and port
|
||
if (strncmp(pfv->filename, "TCP@", 4) == 0) {
|
||
char *ip_port = pfv->filename + 4; // Skip "TCP@"
|
||
char *colon = strchr(ip_port, ':');
|
||
if (colon) {
|
||
*colon = '\0'; // Temporarily null-terminate the IP
|
||
ip = strdup(ip_port);
|
||
port = atoi(colon + 1);
|
||
*colon = ':'; // Restore the colon
|
||
}
|
||
}
|
||
if (!ip || port == 0) {
|
||
SCLogError("Invalid filename format. Expected TCP@ip:port");
|
||
free(ip);
|
||
SCReturnInt(TM_ECODE_FAILED);
|
||
}
|
||
SCLogInfo("Connecting to %s on port %d", ip, port);
|
||
while (1) { // Outer loop to keep reconnecting
|
||
sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
||
if (sockfd < 0) {
|
||
SCLogError("socket failed: %s", strerror(errno));
|
||
goto next;
|
||
}
|
||
// Initialize server address struct
|
||
memset(&server_addr, 0, sizeof(server_addr));
|
||
server_addr.sin_family = AF_INET;
|
||
server_addr.sin_port = htons(port);
|
||
if (inet_pton(AF_INET, ip, &server_addr.sin_addr) <= 0) {
|
||
SCLogError("inet_pton failed: %s", strerror(errno));
|
||
goto next_close_sock;
|
||
}
|
||
// Connect to the server
|
||
if (connect(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
|
||
SCLogError("connect failed: %s", strerror(errno));
|
||
goto next_close_sock;
|
||
}
|
||
SCLogInfo("Connected to server %s on port %d.", ip, port);
|
||
file = fdopen(sockfd, "r");
|
||
if (file == NULL) {
|
||
SCLogError("fdopen failed: %s", strerror(errno));
|
||
goto next_close_sock;
|
||
}
|
||
pfv->pcap_handle = pcap_fopen_offline(file, errbuf);
|
||
if (pfv->pcap_handle == NULL) {
|
||
SCLogError("%s", errbuf);
|
||
fclose(file);
|
||
goto next_close_sock;
|
||
}
|
||
if (pfv->shared != NULL && pfv->shared->bpf_string != NULL) {
|
||
SCLogInfo("using bpf-filter \"%s\"", pfv->shared->bpf_string);
|
||
if (pcap_compile(pfv->pcap_handle, &pfv->filter, pfv->shared->bpf_string, 1, 0) < 0) {
|
||
SCLogError("bpf compilation error %s for %s", pcap_geterr(pfv->pcap_handle),
|
||
pfv->filename);
|
||
pcap_close(pfv->pcap_handle);
|
||
close(sockfd);
|
||
SCReturnInt(TM_ECODE_FAILED);
|
||
}
|
||
if (pcap_setfilter(pfv->pcap_handle, &pfv->filter) < 0) {
|
||
SCLogError("could not set bpf filter %s for %s", pcap_geterr(pfv->pcap_handle),
|
||
pfv->filename);
|
||
pcap_freecode(&pfv->filter);
|
||
pcap_close(pfv->pcap_handle);
|
||
close(sockfd);
|
||
SCReturnInt(TM_ECODE_FAILED);
|
||
}
|
||
pcap_freecode(&pfv->filter);
|
||
}
|
||
pfv->datalink = pcap_datalink(pfv->pcap_handle);
|
||
SCLogDebug("datalink %" PRId32 "", pfv->datalink);
|
||
DatalinkSetGlobalType(pfv->datalink);
|
||
if (!PeekFirstPacketTimestamp(pfv))
|
||
SCReturnInt(TM_ECODE_FAILED);
|
||
DecoderFunc UnusedFnPtr;
|
||
TmEcode validated = ValidateLinkType(pfv->datalink, &UnusedFnPtr);
|
||
if (validated != TM_ECODE_OK)
|
||
SCReturnInt(validated);
|
||
TmEcode result = PcapFileDispatch(pfv);
|
||
pcap_close(pfv->pcap_handle);
|
||
if (result == TM_ECODE_FAILED) {
|
||
SCLogError("PcapFileDispatch failed");
|
||
SCReturnInt(TM_ECODE_FAILED);
|
||
}
|
||
SCLogInfo("Finished processing. Waiting 5 seconds before reconnecting...");
|
||
// file is already closed by closing the handle no need for fclose
|
||
next_close_sock:
|
||
close(sockfd);
|
||
next:
|
||
sleep(5);
|
||
}
|
||
// This point should never be reached due to the infinite loop
|
||
SCReturnInt(TM_ECODE_OK);
|
||
}
|
||
TmEcode InitPcapFile(PcapFileFileVars *pfv)
|
||
{
|
||
char errbuf[PCAP_ERRBUF_SIZE] = "";
|
src/source-pcap-file-helper.h | ||
---|---|---|
*/
|
||
TmEcode PcapFileDispatch(PcapFileFileVars *ptv);
|
||
TmEcode RunPcapOverIP(PcapFileFileVars *pfv);
|
||
/**
|
||
* From a PcapFileFileVars, prepare the filename for processing by setting
|
||
* pcap_handle, datalink, and filter
|
src/source-pcap-file.c | ||
---|---|---|
TmThreadsSetFlag(tv, THV_RUNNING);
|
||
if(ptv->is_directory == 0) {
|
||
SCLogInfo("Starting file run for %s", ptv->behavior.file->filename);
|
||
status = PcapFileDispatch(ptv->behavior.file);
|
||
char* pcap_overip_prefix = "TCP@";
|
||
if (!strncmp(ptv->behavior.file->filename, pcap_overip_prefix, 4)) {
|
||
RunPcapOverIP(ptv->behavior.file);
|
||
} else {
|
||
SCLogInfo("Starting file run for %s", ptv->behavior.file->filename);
|
||
status = PcapFileDispatch(ptv->behavior.file);
|
||
}
|
||
CleanupPcapFileFromThreadVars(ptv, ptv->behavior.file);
|
||
} else {
|
||
SCLogInfo("Starting directory run for %s", ptv->behavior.directory->filename);
|
||
... | ... | |
if (ConfGetBool("pcap-file.delete-when-done", &should_delete) == 1) {
|
||
ptv->shared.should_delete = should_delete == 1;
|
||
}
|
||
char* pcap_overip_prefix = "TCP@";
|
||
if (!strncmp(initdata, pcap_overip_prefix, 4)) {
|
||
SCLogDebug("argument %s was a file", (char *)initdata);
|
||
const size_t toalloc = sizeof(PcapFileFileVars) + pcap_g.read_buffer_size;
|
||
PcapFileFileVars *pv = SCCalloc(1, toalloc);
|
||
if (unlikely(pv == NULL)) {
|
||
SCLogError("Failed to allocate file vars");
|
||
CleanupPcapFileThreadVars(ptv);
|
||
SCReturnInt(TM_ECODE_OK);
|
||
}
|
||
pv->filename = SCStrdup((char *)initdata);
|
||
if (unlikely(pv->filename == NULL)) {
|
||
SCLogError("Failed to allocate filename");
|
||
CleanupPcapFileFileVars(pv);
|
||
CleanupPcapFileThreadVars(ptv);
|
||
SCReturnInt(TM_ECODE_OK);
|
||
}
|
||
pv->shared = &ptv->shared;
|
||
ptv->is_directory = 0;
|
||
ptv->behavior.file = pv;
|
||
goto NEXT_CHECK;
|
||
}
|
||
DIR *directory = NULL;
|
||
SCLogDebug("checking file or directory %s", (char*)initdata);
|
||
if(PcapDetermineDirectoryOrFile((char *)initdata, &directory) == TM_ECODE_FAILED) {
|
||
... | ... | |
ptv->is_directory = 1;
|
||
ptv->behavior.directory = pv;
|
||
}
|
||
NEXT_CHECK:
|
||
if (ConfGet("pcap-file.checksum-checks", &tmpstring) != 1) {
|
||
pcap_g.conf_checksum_mode = CHECKSUM_VALIDATION_AUTO;
|
||
} else {
|
src/suricata.c | ||
---|---|---|
PrintUsage(argv[0]);
|
||
return TM_ECODE_FAILED;
|
||
}
|
||
SCStat buf;
|
||
if (SCStatFn(optarg, &buf) != 0) {
|
||
SCLogError("pcap file '%s': %s", optarg, strerror(errno));
|
||
return TM_ECODE_FAILED;
|
||
}
|
||
// SCStat buf;
|
||
// if (SCStatFn(optarg, &buf) != 0) {
|
||
// SCLogError("pcap file '%s': %s", optarg, strerror(errno));
|
||
// return TM_ECODE_FAILED;
|
||
// }
|
||
if (ConfSetFinal("pcap-file.file", optarg) != 1) {
|
||
SCLogError("ERROR: Failed to set pcap-file.file\n");
|
||
return TM_ECODE_FAILED;
|