The contents of this page are licensed under the following license
libipq -- iptables userspace packet queuing library
libipq requires kernel ip_queue module: insmod ip_queue. Compilation: gcc ./ipq.c -o ./ipq -lipq . |
#include <linux/netfilter.h> #include <netinet/ip.h> #include <linux/tcp.h> #include <linux/udp.h> #include <libipq.h> #include <stdio.h> #define PACKET_LENGTH 2048 static char* __u32_to_str (__u32 ip) { unsigned int tmp = 0; int i; char *str_ip; str_ip = (char *)malloc (sizeof(char) * 16); str_ip[0] = '\0'; for (i=0; i<4; i++) { tmp = ip & 255; sprintf ((str_ip + strlen(str_ip)), "%d.", (unsigned int)tmp); ip >>= 8; } sprintf ((str_ip + (strlen(str_ip) - 1)), "%c", '\0'); str_ip[15] = '\0'; return ((char *)str_ip); } static void die(struct ipq_handle *h) { ipq_perror("Error"); ipq_destroy_handle(h); exit(1); } int main(int argc, char *argv[]) { int nStatus; unsigned char cbBuf[PACKET_LENGTH]; struct ipq_handle* lpstHandle; struct ipq_packet_msg* lpstPacketMsg; struct iphdr* lpstIPHeader; struct tcphdr* lpstTCP; struct udphdr* lpstUDP; /* init and create queue */ lpstHandle = ipq_create_handle(0, PF_INET); if (!lpstHandle) die(lpstHandle); /* mode: (here) copy entire packet to the user space and advise ip_queue */ nStatus = ipq_set_mode(lpstHandle, IPQ_COPY_PACKET, PACKET_LENGTH); if (nStatus < 0) die(lpstHandle); while(1) { /* block for packet */ nStatus = ipq_read(lpstHandle, cbBuf, PACKET_LENGTH, 0); if (nStatus < 0) die(lpstHandle); switch (ipq_message_type(cbBuf)) { case NLMSG_ERROR: { fprintf(stderr, "%s: Received error message %d.\n", argv[0], ipq_get_msgerr(cbBuf)); break; } case IPQM_PACKET: { /* get packet */ lpstPacketMsg = ipq_get_packet(cbBuf); lpstIPHeader = ((struct iphdr*)lpstPacketMsg->payload); /* show packet info */ if (lpstIPHeader && lpstIPHeader->protocol == IPPROTO_TCP) { lpstTCP = (struct tcphdr*)(lpstPacketMsg->payload + (lpstIPHeader->ihl << 2)); if (lpstTCP) { printf("[TCP] %s:%d -> %s:%d\n", __u32_to_str(lpstIPHeader->saddr), lpstTCP->source, __u32_to_str(lpstIPHeader->daddr), lpstTCP->dest); } } else if (lpstIPHeader && lpstIPHeader->protocol == IPPROTO_UDP) { lpstUDP = (struct udphdr*)(lpstPacketMsg->payload + (lpstIPHeader->ihl << 2)); if (lpstUDP) { printf("[UDP] %s:%d -> %s:%d\n", __u32_to_str(lpstIPHeader->saddr), lpstUDP->source, __u32_to_str(lpstIPHeader->daddr), lpstUDP->dest); } } /* verdict: (here) accept */ nStatus = ipq_set_verdict(lpstHandle, lpstPacketMsg->packet_id, NF_ACCEPT, 0, NULL); if (nStatus < 0) die(lpstHandle); break; } default: { fprintf(stderr, "%s: Unknown message type!\n", argv[0]); break; } } }; ipq_destroy_handle(lpstHandle); return 0; } |
August, 23rd 2006 © Michał Kalewski