|
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