144d362409d5469aed47d19e7908d19bd194493aThomas Graf/* 244d362409d5469aed47d19e7908d19bd194493aThomas Graf * src/nf-monitor.c Monitor netfilter events 344d362409d5469aed47d19e7908d19bd194493aThomas Graf * 444d362409d5469aed47d19e7908d19bd194493aThomas Graf * This library is free software; you can redistribute it and/or 544d362409d5469aed47d19e7908d19bd194493aThomas Graf * modify it under the terms of the GNU Lesser General Public 644d362409d5469aed47d19e7908d19bd194493aThomas Graf * License as published by the Free Software Foundation version 2.1 744d362409d5469aed47d19e7908d19bd194493aThomas Graf * of the License. 844d362409d5469aed47d19e7908d19bd194493aThomas Graf * 910cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch> 1044d362409d5469aed47d19e7908d19bd194493aThomas Graf * Copyright (c) 2007 Philip Craig <philipc@snapgear.com> 1144d362409d5469aed47d19e7908d19bd194493aThomas Graf * Copyright (c) 2007 Secure Computing Corporation 1244d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 1344d362409d5469aed47d19e7908d19bd194493aThomas Graf 148808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf#include <netlink/cli/utils.h> 1544d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netlink/netfilter/nfnl.h> 1644d362409d5469aed47d19e7908d19bd194493aThomas Graf 1744d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic void obj_input(struct nl_object *obj, void *arg) 1844d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 1944d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nl_dump_params dp = { 2044d362409d5469aed47d19e7908d19bd194493aThomas Graf .dp_type = NL_DUMP_STATS, 2144d362409d5469aed47d19e7908d19bd194493aThomas Graf .dp_fd = stdout, 2244d362409d5469aed47d19e7908d19bd194493aThomas Graf .dp_dump_msgtype = 1, 2344d362409d5469aed47d19e7908d19bd194493aThomas Graf }; 2444d362409d5469aed47d19e7908d19bd194493aThomas Graf 2544d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_object_dump(obj, &dp); 2644d362409d5469aed47d19e7908d19bd194493aThomas Graf} 2744d362409d5469aed47d19e7908d19bd194493aThomas Graf 2844d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic int event_input(struct nl_msg *msg, void *arg) 2944d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 3044d362409d5469aed47d19e7908d19bd194493aThomas Graf if (nl_msg_parse(msg, &obj_input, NULL) < 0) 3144d362409d5469aed47d19e7908d19bd194493aThomas Graf fprintf(stderr, "<<EVENT>> Unknown message type\n"); 3244d362409d5469aed47d19e7908d19bd194493aThomas Graf 3344d362409d5469aed47d19e7908d19bd194493aThomas Graf /* Exit nl_recvmsgs_def() and return to the main select() */ 3444d362409d5469aed47d19e7908d19bd194493aThomas Graf return NL_STOP; 3544d362409d5469aed47d19e7908d19bd194493aThomas Graf} 3644d362409d5469aed47d19e7908d19bd194493aThomas Graf 3744d362409d5469aed47d19e7908d19bd194493aThomas Grafint main(int argc, char *argv[]) 3844d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 3910cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf struct nl_sock *sock; 4010cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf int err; 4144d362409d5469aed47d19e7908d19bd194493aThomas Graf int i, idx; 4244d362409d5469aed47d19e7908d19bd194493aThomas Graf 4344d362409d5469aed47d19e7908d19bd194493aThomas Graf static const struct { 4444d362409d5469aed47d19e7908d19bd194493aThomas Graf enum nfnetlink_groups gr_id; 4544d362409d5469aed47d19e7908d19bd194493aThomas Graf const char* gr_name; 4610cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf } groups[] = { 4744d362409d5469aed47d19e7908d19bd194493aThomas Graf { NFNLGRP_CONNTRACK_NEW, "ct-new" }, 4844d362409d5469aed47d19e7908d19bd194493aThomas Graf { NFNLGRP_CONNTRACK_UPDATE, "ct-update" }, 4944d362409d5469aed47d19e7908d19bd194493aThomas Graf { NFNLGRP_CONNTRACK_DESTROY, "ct-destroy" }, 5044d362409d5469aed47d19e7908d19bd194493aThomas Graf { NFNLGRP_NONE, NULL } 5144d362409d5469aed47d19e7908d19bd194493aThomas Graf }; 5244d362409d5469aed47d19e7908d19bd194493aThomas Graf 538808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf sock = nl_cli_alloc_socket(); 54f9071054d0f2512dea9e95f99c308e931ed78dbaPatrick McHardy nl_socket_disable_seq_check(sock); 5510cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf nl_socket_modify_cb(sock, NL_CB_VALID, NL_CB_CUSTOM, event_input, NULL); 5644d362409d5469aed47d19e7908d19bd194493aThomas Graf 5744d362409d5469aed47d19e7908d19bd194493aThomas Graf if (argc > 1 && !strcasecmp(argv[1], "-h")) { 5844d362409d5469aed47d19e7908d19bd194493aThomas Graf printf("Usage: nf-monitor [<groups>]\n"); 5944d362409d5469aed47d19e7908d19bd194493aThomas Graf 6044d362409d5469aed47d19e7908d19bd194493aThomas Graf printf("Known groups:"); 6110cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf for (i = 0; groups[i].gr_id != NFNLGRP_NONE; i++) 6210cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf printf(" %s", groups[i].gr_name); 6344d362409d5469aed47d19e7908d19bd194493aThomas Graf printf("\n"); 6444d362409d5469aed47d19e7908d19bd194493aThomas Graf return 2; 6544d362409d5469aed47d19e7908d19bd194493aThomas Graf } 6644d362409d5469aed47d19e7908d19bd194493aThomas Graf 678808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf nl_cli_connect(sock, NETLINK_NETFILTER); 6844d362409d5469aed47d19e7908d19bd194493aThomas Graf 6944d362409d5469aed47d19e7908d19bd194493aThomas Graf for (idx = 1; argc > idx; idx++) { 7010cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf for (i = 0; groups[i].gr_id != NFNLGRP_NONE; i++) { 7110cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf if (strcmp(argv[idx], groups[i].gr_name)) 7210cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf continue; 7310cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf 7410cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf err = nl_socket_add_membership(sock, groups[i].gr_id); 7510cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf if (err < 0) 768808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf nl_cli_fatal(err, 778808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf "Unable to add membership: %s", 788808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf nl_geterror(err)); 7910cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf break; 8044d362409d5469aed47d19e7908d19bd194493aThomas Graf } 8110cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf 8210cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf if (groups[i].gr_id == NFNLGRP_NONE) 838808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf nl_cli_fatal(NLE_OBJ_NOTFOUND, "Unknown group: \"%s\"", 848808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf argv[idx]); 8544d362409d5469aed47d19e7908d19bd194493aThomas Graf } 8644d362409d5469aed47d19e7908d19bd194493aThomas Graf 8744d362409d5469aed47d19e7908d19bd194493aThomas Graf while (1) { 8844d362409d5469aed47d19e7908d19bd194493aThomas Graf fd_set rfds; 8944d362409d5469aed47d19e7908d19bd194493aThomas Graf int fd, retval; 9044d362409d5469aed47d19e7908d19bd194493aThomas Graf 9110cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf fd = nl_socket_get_fd(sock); 9244d362409d5469aed47d19e7908d19bd194493aThomas Graf 9344d362409d5469aed47d19e7908d19bd194493aThomas Graf FD_ZERO(&rfds); 9444d362409d5469aed47d19e7908d19bd194493aThomas Graf FD_SET(fd, &rfds); 9544d362409d5469aed47d19e7908d19bd194493aThomas Graf /* wait for an incoming message on the netlink socket */ 9644d362409d5469aed47d19e7908d19bd194493aThomas Graf retval = select(fd+1, &rfds, NULL, NULL, NULL); 9744d362409d5469aed47d19e7908d19bd194493aThomas Graf 9844d362409d5469aed47d19e7908d19bd194493aThomas Graf if (retval) { 9944d362409d5469aed47d19e7908d19bd194493aThomas Graf /* FD_ISSET(fd, &rfds) will be true */ 10010cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf nl_recvmsgs_default(sock); 10144d362409d5469aed47d19e7908d19bd194493aThomas Graf } 10244d362409d5469aed47d19e7908d19bd194493aThomas Graf } 10344d362409d5469aed47d19e7908d19bd194493aThomas Graf 10410cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf return 0; 10544d362409d5469aed47d19e7908d19bd194493aThomas Graf} 106