Merge pull request #18394 from donaldsharp/fpm_listener_output

zebra: add ability to specify output file with fpm_listener
This commit is contained in:
Donatas Abraitis 2025-03-15 18:32:19 +01:00 committed by GitHub
commit 35cc716363
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -44,6 +44,7 @@ struct glob {
int sock;
bool reflect;
bool dump_hex;
FILE *output_file;
};
struct glob glob_space;
@ -123,13 +124,13 @@ static int accept_conn(int listen_sock)
while (1) {
char buf[120];
fprintf(stdout, "Waiting for client connection...\n");
fprintf(glob->output_file, "Waiting for client connection...\n");
client_len = sizeof(client_addr);
sock = accept(listen_sock, (struct sockaddr *)&client_addr,
&client_len);
if (sock >= 0) {
fprintf(stdout, "Accepted client %s\n",
fprintf(glob->output_file, "Accepted client %s\n",
inet_ntop(AF_INET, &client_addr.sin_addr, buf, sizeof(buf)));
return sock;
}
@ -172,8 +173,7 @@ read_fpm_msg(char *buf, size_t buf_len)
bytes_read = read(glob->sock, cur, need_len);
if (bytes_read == 0) {
fprintf(stdout,
"Socket closed as that read returned 0\n");
fprintf(glob->output_file, "Socket closed as that read returned 0\n");
return NULL;
}
@ -567,7 +567,7 @@ addr_to_s(unsigned char family, void *addr)
}
/*
* netlink_msg_ctx_print
* netlink_msg_ctx_snprint
*/
static int netlink_msg_ctx_snprint(struct netlink_msg_ctx *ctx, char *buf,
size_t buf_len)
@ -628,7 +628,7 @@ static void print_netlink_msg_ctx(struct netlink_msg_ctx *ctx)
char buf[1024];
netlink_msg_ctx_snprint(ctx, buf, sizeof(buf));
printf("%s\n", buf);
fprintf(glob->output_file, "%s\n", buf);
}
static void fpm_listener_hexdump(const void *mem, size_t len)
@ -641,7 +641,7 @@ static void fpm_listener_hexdump(const void *mem, size_t len)
return;
if (len == 0) {
printf("%016lx: (zero length / no data)\n", (long)src);
fprintf(glob->output_file, "%016lx: (zero length / no data)\n", (long)src);
return;
}
@ -654,14 +654,14 @@ static void fpm_listener_hexdump(const void *mem, size_t len)
const uint8_t *lineend = src + 8;
uint32_t line_bytes = 0;
printf("%016lx: ", (long)src);
fprintf(glob->output_file, "%016lx: ", (long)src);
while (src < lineend && src < end) {
printf("%02x ", *src++);
fprintf(glob->output_file, "%02x ", *src++);
line_bytes++;
}
if (line_bytes < 8)
printf("%*s", (8 - line_bytes) * 3, "");
fprintf(glob->output_file, "%*s", (8 - line_bytes) * 3, "");
src -= line_bytes;
while (src < lineend && src < end && fb.pos < fb.buf + fb.len) {
@ -672,7 +672,7 @@ static void fpm_listener_hexdump(const void *mem, size_t len)
else
*fb.pos++ = '.';
}
printf("\n");
fprintf(glob->output_file, "\n");
}
}
@ -711,20 +711,17 @@ static void parse_netlink_msg(char *buf, size_t buf_len, fpm_msg_hdr_t *fpm)
if (glob->reflect && hdr->nlmsg_type == RTM_NEWROUTE &&
ctx->rtmsg->rtm_protocol > RTPROT_STATIC) {
printf(" Route %s(%u) reflecting back\n",
netlink_prot_to_s(
ctx->rtmsg->rtm_protocol),
ctx->rtmsg->rtm_protocol);
fprintf(glob->output_file, " Route %s(%u) reflecting back\n",
netlink_prot_to_s(ctx->rtmsg->rtm_protocol),
ctx->rtmsg->rtm_protocol);
ctx->rtmsg->rtm_flags |= RTM_F_OFFLOAD;
write(glob->sock, fpm, fpm_msg_len(fpm));
}
break;
default:
fprintf(stdout,
"Ignoring netlink message - Type: %s(%d)\n",
netlink_msg_type_to_s(hdr->nlmsg_type),
hdr->nlmsg_type);
fprintf(glob->output_file, "Ignoring netlink message - Type: %s(%d)\n",
netlink_msg_type_to_s(hdr->nlmsg_type), hdr->nlmsg_type);
}
}
}
@ -734,8 +731,8 @@ static void parse_netlink_msg(char *buf, size_t buf_len, fpm_msg_hdr_t *fpm)
*/
static void process_fpm_msg(fpm_msg_hdr_t *hdr)
{
fprintf(stdout, "FPM message - Type: %d, Length %d\n", hdr->msg_type,
ntohs(hdr->msg_len));
fprintf(glob->output_file, "FPM message - Type: %d, Length %d\n", hdr->msg_type,
ntohs(hdr->msg_len));
if (hdr->msg_type != FPM_MSG_TYPE_NETLINK) {
fprintf(stderr, "Unknown fpm message type %u\n", hdr->msg_type);
@ -770,12 +767,12 @@ int main(int argc, char **argv)
pid_t daemon;
int r;
bool fork_daemon = false;
setbuf(stdout, NULL);
const char *output_file = NULL;
memset(glob, 0, sizeof(*glob));
glob->output_file = stdout;
while ((r = getopt(argc, argv, "rdv")) != -1) {
while ((r = getopt(argc, argv, "rdvo:")) != -1) {
switch (r) {
case 'r':
glob->reflect = true;
@ -786,9 +783,23 @@ int main(int argc, char **argv)
case 'v':
glob->dump_hex = true;
break;
case 'o':
output_file = optarg;
break;
}
}
if (output_file) {
glob->output_file = fopen(output_file, "w");
if (!glob->output_file) {
fprintf(stderr, "Failed to open output file %s: %s\n", output_file,
strerror(errno));
exit(1);
}
}
setbuf(glob->output_file, NULL);
if (fork_daemon) {
daemon = fork();
@ -805,7 +816,7 @@ int main(int argc, char **argv)
while (1) {
glob->sock = accept_conn(glob->server_sock);
fpm_serve();
fprintf(stdout, "Done serving client");
fprintf(glob->output_file, "Done serving client\n");
}
}
#else