Archive

Archive for December, 2004

Netfilter hooks, and the skb structure (sk_buff.h)

December 24th, 2004 SuperHac No comments

How to use Netfilter hooks written by Owen Klan, presents a general overview of Netfilter and covers the basics of kernel module development.

I also found a resource on the sk_buff structure, which holds packets passing through the network stack. You can find it here: skb – Linux network buffers

Categories: Kernel, LIBIPQ, Linux, Netfiliter Tags:

LIBIPQ Packet Processing

December 16th, 2004 SuperHac No comments

For those that are not familiar with LIBIPQ, it’s a library for receving packets from the Netfilter framework in user space applications. You can use this library to grab packets before they leave the stack, and make decisions on what to do with them. For instance you can Accept, Reject, or even mangle packets. It uses the IP_QUEUE module which you may have seen used with IPTABLES.

For example: # iptables -A OUTPUT -j QUEUE

This tells netfilter to route all out going packets orginating from your machine to the QUEUE.

Developing with LIBIPQ requires the iptables-devel package to be installed. You can then compile your programs by linking them to the LIBIPQ library as shown below:

# gcc yourapp.c -lipq

You need to be root to run any program that uses LIBIPQ. Also if you recieve an error like, “passer: Failed to send netlink message: Connection refused” you need to load the ip_queue module. Just issue: # modprobe ip_queue.

I would like to thank Ulysses, Srinivas, Henrik, Maarteen for all their help. If I forgot anyone else thank you too!

Below is a code snippet for parsing out the raw packet found in the structure ipq_packet_msg_t(ipq_packet_msg_t->payload). This snippet fits into the example from Quick Intro to libipq. This is very useful for people just getting started with LIBIPQ since documentation on this is scarce.

case IPQM_PACKET:
{
ipq_packet_msg_t *m = ipq_get_packet(buf);

__u16 first_two_bytes = 0; /* hold the first two bytes from payload */

/* Cast the IP Header from the raw packet */
struct iphdr *iph = ((struct iphdr *)m->payload);

/* Cast the TCP Header from the raw packet */
struct tcphdr *tcp = (struct tcphdr *)(m->payload + (iph->ihl << 2));

/* get the payload offset from with the raw packet */
int unsigned payload_offset = ((iph->ihl << 2) + (tcp->doff << 2));

/* calculate the length of the payload */
int unsigned payload_length = (unsigned int) ntohs(iph->tot_len) – ((iph->ihl << 2) + (tcp->doff << 2));

/* Calculate the size of the IP Header. iph->ihl contains the number of 32 bit
words that represent the header size. Therfore to get the number of bytes
multiple this number by 4 */
int iphdr_size = (iph->ihl << 2);

/* Calculate the size of the TCP Header. tcp->doff contains the number of 32 bit
words that represent the header size. Therfore to get the number of bytes
multiple this number by 4 */
int tcphdr_size = (tcp->doff << 2);

/* get the destination port of the packet */
int port = ntohs(tcp->dest);

/* Get the first two bytes of the payload if a payload is present*/
if(payload_length)
first_two_bytes = *(__u16 *) (m->payload + payload_offset);

/* example code */
if (port == 9555) /* Check for a port match */
{
printf(“Matched a packet\n”);

if(payload_length)
printf(“First two bytes: 0x%x\n”, first_two_bytes); /* prints in HEX */

printf(“IP Header size: %d\n”, iphdr_size);
printf(“TCP Header size: %d\n”, tcphdr_size);
printf(“Payload Size : %d\n”, payload_length);
printf(“TOTAL IP Packet size: %d\n”, ntohs(iph->tot_len));
printf(“\n”);

status = ipq_set_verdict(h, m->packet_id, NF_ACCEPT, 0, NULL);

}
else
{
status = ipq_set_verdict(h, m->packet_id, NF_ACCEPT, 0, NULL);
if (status < 0)
die(h);
}
break;
}
}

Categories: Kernel, LIBIPQ, Linux, Netfiliter Tags: