mirror of https://gerrit.osmocom.org/osmo-pcap
osmo-pcap-server: Write the pcap files to disk, roll them over
This commit is contained in:
parent
88c07f2b7e
commit
7309a906d0
|
@ -171,7 +171,6 @@ int main(int argc, char **argv)
|
|||
/* seed the PRNG */
|
||||
srand(time(NULL));
|
||||
|
||||
|
||||
signal(SIGINT, &signal_handler);
|
||||
signal(SIGABRT, &signal_handler);
|
||||
signal(SIGUSR1, &signal_handler);
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
#include <osmo-pcap/osmo_pcap_server.h>
|
||||
#include <osmo-pcap/common.h>
|
||||
#include <osmo-pcap/wireformat.h>
|
||||
|
||||
#include <osmocom/core/socket.h>
|
||||
#include <osmocom/core/talloc.h>
|
||||
|
@ -30,6 +31,7 @@
|
|||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
@ -48,6 +50,96 @@ static void close_connection(struct osmo_pcap_conn *conn)
|
|||
}
|
||||
}
|
||||
|
||||
static void restart_pcap(struct osmo_pcap_conn *conn)
|
||||
{
|
||||
time_t now = time(NULL);
|
||||
struct tm *tm = localtime(&now);
|
||||
char *filename;
|
||||
int rc;
|
||||
|
||||
if (conn->local_fd >= 0) {
|
||||
close(conn->local_fd);
|
||||
conn->local_fd = -1;
|
||||
}
|
||||
|
||||
|
||||
filename = talloc_asprintf(conn, "%s/trace-%s-%d%.2d%.2d_%.2d%.2d%.2d.pcap",
|
||||
conn->server->base_path, conn->name,
|
||||
tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
|
||||
tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||
conn->local_fd = creat(filename, S_IRUSR);
|
||||
if (conn->local_fd < 0) {
|
||||
LOGP(DSERVER, LOGL_ERROR, "Failed to file: '%s'\n", filename);
|
||||
return;
|
||||
}
|
||||
|
||||
rc = write(conn->local_fd, &conn->file_hdr, sizeof(conn->file_hdr));
|
||||
if (rc != sizeof(conn->file_hdr)) {
|
||||
LOGP(DSERVER, LOGL_ERROR, "Failed to write the header: %d\n", errno);
|
||||
close(conn->local_fd);
|
||||
conn->local_fd = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
conn->last_write = *tm;
|
||||
talloc_free(filename);
|
||||
}
|
||||
|
||||
static void link_data(struct osmo_pcap_conn *conn, struct osmo_pcap_data *data)
|
||||
{
|
||||
struct pcap_file_header *hdr;
|
||||
|
||||
if (data->len != sizeof(*hdr)) {
|
||||
LOGP(DSERVER, LOGL_ERROR, "The pcap_file_header does not fit.\n");
|
||||
close_connection(conn);
|
||||
return;
|
||||
}
|
||||
|
||||
hdr = (struct pcap_file_header *) &data->data[0];
|
||||
if (conn->local_fd < 0) {
|
||||
conn->file_hdr = *hdr;
|
||||
restart_pcap(conn);
|
||||
} else if (memcmp(&conn->file_hdr, hdr, sizeof(*hdr)) != 0) {
|
||||
conn->file_hdr = *hdr;
|
||||
restart_pcap(conn);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if we are past the limit or on a day change
|
||||
*/
|
||||
static void write_data(struct osmo_pcap_conn *conn, struct osmo_pcap_data *data)
|
||||
{
|
||||
time_t now = time(NULL);
|
||||
struct tm *tm = localtime(&now);
|
||||
int rc;
|
||||
|
||||
if (conn->local_fd < -1) {
|
||||
LOGP(DSERVER, LOGL_ERROR, "No file is open. close connection.\n");
|
||||
close_connection(conn);
|
||||
return;
|
||||
}
|
||||
|
||||
off_t cur = lseek(conn->local_fd, 0, SEEK_CUR);
|
||||
if (cur > conn->server->max_size) {
|
||||
LOGP(DSERVER, LOGL_NOTICE, "Rolling over file for %s\n", conn->name);
|
||||
restart_pcap(conn);
|
||||
} else if (conn->last_write.tm_mday != tm->tm_mday ||
|
||||
conn->last_write.tm_mon != tm->tm_mon ||
|
||||
conn->last_write.tm_year != tm->tm_year) {
|
||||
LOGP(DSERVER, LOGL_NOTICE, "Rolling over file for %s\n", conn->name);
|
||||
restart_pcap(conn);
|
||||
}
|
||||
|
||||
conn->last_write = *tm;
|
||||
rc = write(conn->local_fd, &data->data[0], data->len);
|
||||
if (rc != data->len) {
|
||||
LOGP(DSERVER, LOGL_ERROR, "Failed to write for %s\n", conn->name);
|
||||
close_connection(conn);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void osmo_pcap_server_delete(struct osmo_pcap_conn *conn)
|
||||
{
|
||||
close_connection(conn);
|
||||
|
@ -55,7 +147,6 @@ void osmo_pcap_server_delete(struct osmo_pcap_conn *conn)
|
|||
talloc_free(conn);
|
||||
}
|
||||
|
||||
|
||||
struct osmo_pcap_conn *osmo_pcap_server_find(struct osmo_pcap_server *server,
|
||||
const char *name)
|
||||
{
|
||||
|
@ -81,18 +172,43 @@ struct osmo_pcap_conn *osmo_pcap_server_find(struct osmo_pcap_server *server,
|
|||
|
||||
static int read_cb(struct osmo_fd *fd, unsigned int what)
|
||||
{
|
||||
struct osmo_pcap_data *data;
|
||||
struct osmo_pcap_conn *conn;
|
||||
char buf[4096];
|
||||
int rc;
|
||||
|
||||
conn = fd->data;
|
||||
rc = read(fd->fd, buf, sizeof(buf));
|
||||
if (rc < 0) {
|
||||
data = (struct osmo_pcap_data *) &buf[0];
|
||||
|
||||
rc = read(fd->fd, buf, sizeof(*data));
|
||||
if (rc != sizeof(*data)) {
|
||||
LOGP(DSERVER, LOGL_ERROR, "Failed to read from %s\n", conn->name);
|
||||
close_connection(conn);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (data->len > 2000) {
|
||||
LOGP(DSERVER, LOGL_ERROR, "Unplausible result %u\n", data->len);
|
||||
close_connection(conn);
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = read(fd->fd, &data->data[0], data->len);
|
||||
if (rc != data->len) {
|
||||
LOGP(DSERVER, LOGL_ERROR, "Two short packet %d\n", rc);
|
||||
close_connection(conn);
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (data->type) {
|
||||
case PKT_LINK_HDR:
|
||||
link_data(conn, data);
|
||||
break;
|
||||
case PKT_LINK_DATA:
|
||||
write_data(conn, data);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue