Linux Netfilter discussions
 help / color / mirror / Atom feed
From: Iliya Peregoudov <iliyap@rambler.ru>
To: netfilter@lists.netfilter.org
Subject: Listening for queued packets over netlink
Date: Mon, 16 Aug 2004 21:43:23 +0400	[thread overview]
Message-ID: <web-74047681@mail1.rambler.ru> (raw)

I wrote a small dumb program that listens for packet messages from 
ip_queue module. But the program is not working as I expect it to 
work. It receives an infinite flow of trash packets from kernel. 
Please help! I need a clue. The program text is below.

#include <asm/types.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <linux/netlink.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4/ip_queue.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <signal.h>

static int done = 0;

void sigint(int signum)
{
    done = 1;
}

int main(int argc, char *argv[])
{
    int fd;
    struct sockaddr_nl a;
    size_t alen;
    struct sockaddr_nl ra;
    size_t ralen;
    struct nlmsghdr *h;
    struct ipq_mode_msg *m;
    struct ipq_packet_msg *p;
    struct ipq_verdict_msg *v;
    char dbuf[20];
    unsigned char obuf[128];
    unsigned char ibuf[128];
    size_t nsent, nrecv;
    int seq = 0;

    /* Create the socket */
    fd = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_FIREWALL);
    if (fd == -1) {
       perror("socket");
       return EXIT_FAILURE;
    }

    /* Bind local end of the socket to the pid of current process */
    memset(&a, 0, sizeof(struct sockaddr_nl));
    a.nl_family = AF_NETLINK;
    a.nl_pid = getpid();
    a.nl_groups = 0;
    if (bind(fd, (struct sockaddr *)&a, sizeof(struct sockaddr_nl)) == 
-1) {
       perror("bind");
       return EXIT_FAILURE;
    }

    /* Remote end of the socket is in kernel */
    memset(&a, 0, sizeof(struct sockaddr_nl));
    a.nl_family = AF_NETLINK;
    a.nl_pid = 0;
    a.nl_groups = 0;

    /* Send a mode message to register for packet messages */
    h = (struct nlmsghdr *)obuf;
    h->nlmsg_type = IPQM_MODE;
    h->nlmsg_len = NLMSG_LENGTH(sizeof(struct ipq_mode_msg));
    h->nlmsg_flags = 0; /* NLM_F_REQUEST; */
    h->nlmsg_pid = getpid();
    h->nlmsg_seq = seq++;

    m = NLMSG_DATA(h);
    m->value = IPQ_COPY_META;
    m->range = 0;

    nsent = sendto(fd, (void *)obuf, h->nlmsg_len, 0,
            (struct sockaddr *)&a, sizeof(struct sockaddr_nl));
    if (nsent == -1) {
       perror("sendto(IPQM_MODE)");
       return EXIT_FAILURE;
    }

    /* we're ready to filter packets */
    signal(SIGINT, sigint);
    while (!done) {
       alen = sizeof(struct sockaddr_nl);
       nrecv = recvfrom(fd, (void *)ibuf, 128, 0,
               (struct sockaddr *)&ra, &ralen);
       if (nrecv == -1) {
          perror("recvfrom(IPQM_PACKET)");
          done = 1;
          continue;
       }

       h = (struct nlmsghdr *)ibuf;
       p = NLMSG_DATA(h);

       strftime(dbuf, 20, "%Y-%m-%d %H:%M:%S", 
localtime(&p->timestamp_sec));
       printf(
       "-----\n"
       "remote_pid: %d\n"
       "packet_id: %lu\n"
       "mark: %lu\n"
       "timestamp: %s.%06ld\n"
       "hook: %u\n"
       "indev: %s\n"
       "outdev: %s\n"
       "hw_protocol: %u\n"
       "hw_type: %u\n"
       "hw_addrlen: %u\n"
       "hw_addr: %s\n"
       "data_len: %u\n",
       ra.nl_pid,
       p->packet_id, p->mark,
       dbuf, p->timestamp_usec,
       p->hook, p->indev_name, p->outdev_name,
       p->hw_protocol, p->hw_type, p->hw_addrlen, (char *)NULL,
       p->data_len);

       /* Sent ACCEPT verdict message */
       h = (struct nlmsghdr *)obuf;
       h->nlmsg_type = IPQM_VERDICT;
       h->nlmsg_len = NLMSG_LENGTH(sizeof(struct ipq_verdict_msg));
       h->nlmsg_flags = 0; /*NLM_F_REQUEST;*/
       h->nlmsg_pid = getpid();
       h->nlmsg_seq = seq++;

       v = (struct ipq_verdict_msg *)NLMSG_DATA(h);
       v->value = NF_ACCEPT;
       v->id = p->packet_id;

       nsent = sendto(fd, (void *)obuf, h->nlmsg_len, 0,
               (struct sockaddr *)&a, sizeof(struct sockaddr_nl));
       if (nsent == -1) {
          perror("sendto(IPQM_VERDICT)");
          done = 1;
          continue;
       }
    }

    /* Send a mode message to unregister from packet messages */
    h = (struct nlmsghdr *)obuf;
    h->nlmsg_type = IPQM_MODE;
    h->nlmsg_len = NLMSG_LENGTH(sizeof(struct ipq_mode_msg));
    h->nlmsg_flags = NLM_F_REQUEST;
    h->nlmsg_pid = getpid();
    h->nlmsg_seq = seq++;

    m = NLMSG_DATA(h);
    m->value = IPQ_COPY_NONE;
    m->range = 0;

    nsent = sendto(fd, (void *)obuf, h->nlmsg_len, 0,
            (struct sockaddr *)&a, sizeof(struct sockaddr_nl));
    if (nsent == -1) {
       perror("sendto(IPQM_MODE)");
       return EXIT_FAILURE;
    }

    close(fd);

    return 0;
}


                 reply	other threads:[~2004-08-16 17:43 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=web-74047681@mail1.rambler.ru \
    --to=iliyap@rambler.ru \
    --cc=netfilter@lists.netfilter.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox