]> git.puffer.fish Git - mirror/frr.git/commitdiff
zebra: add ability to specify output file with fpm_listener 18394/head
authorDonald Sharp <sharpd@nvidia.com>
Fri, 14 Mar 2025 17:22:16 +0000 (13:22 -0400)
committerDonald Sharp <sharpd@nvidia.com>
Fri, 14 Mar 2025 17:24:19 +0000 (13:24 -0400)
The fpm_listener didn't have the ability to specify the output
file location at all.  Modify the code to accept this.

Signed-off-by: Donald Sharp <sharpd@nvidia.com>
zebra/fpm_listener.c

index 140cfa77cf4dc68ffffd458eba88c4c41231e37f..43ca6e47b887750f1400f5c67bb39b44fa3f060d 100644 (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