All of lore.kernel.org
 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.