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