Project

General

Profile

Feature #5499 ยป pcapoverip.diff

Hans Vermeer, 09/26/2024 07:42 PM

View differences:

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;
    (1-1/1)