#include <linux/types.h>
#include <netinet/in.h>
#include <netinet/ip.h>
+#include <netinet/ip6.h>
#include <netinet/tcp.h>
+#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
return ( ph )? ntohl( ph->packet_id ) : 0;
}
-// Payload headers
-struct headers {
- struct ip first;
+struct ipv4_pkt {
+ struct ip first; // .ip_dst[4 bytes]
struct tcphdr second;
- //unsigned char pad[12]; // ??
};
-///////// Debugging
+struct ipv6_pkt {
+ struct ip6_hdr first; // .ip6_dst[16 bytes]
+ struct tcphdr second;
+};
-static unsigned char *tell_ip(u_int32_t ip) {
- static unsigned char THEIP[20];
- unsigned char *b = (unsigned char *)&ip;
- sprintf( (char*) THEIP, "%d.%d.%d.%d%c", b[0], b[1], b[2], b[3], 0 );
- return THEIP;
+// Payload packet
+struct packet {
+ union {
+ unsigned int packet_type:4; // 4 or 6
+ struct ipv4_pkt packet4;
+ struct ipv6_pkt packet6;
+ } p;
+ //unsigned char pad[12]; // ??
+};
+
+static struct packet *get_headerP(unsigned char *data) {
+ return (struct packet *) data;
}
-static u_int32_t get_dest_ip4(unsigned char *data) {
- struct headers *p = (struct headers *) data;
- return p->first.ip_dst.s_addr;
+///////// Debugging
+//const char *inet_ntop(int af, const void *restrict src,
+// char dst[restrict .size], socklen_t size);
+
+static const char *tell_ip(struct packet *ip) {
+ static char THEIP[200];
+ switch ( ip->p.packet_type ) {
+ case 4:
+ return inet_ntop( AF_INET, &ip->p.packet4.first.ip_dst, THEIP, 200 );
+ case 6:
+ return inet_ntop( AF_INET6, &ip->p.packet6.first.ip6_dst, THEIP, 200 );
+ }
+ return strcpy( THEIP, "???" );
}
/**
* Review payload packet payload
*/
static void view_payload(unsigned char *data,int length) {
- u_int32_t ip4 = get_dest_ip4( data );
- u_int16_t port = ntohs( ((struct headers *) data )->second.th_dport );
- u_int8_t syn = sizeof( struct headers );
- unsigned char *body = data ;//+ sizeof( struct headers );
+ struct packet *header = get_headerP( data );
+ u_int16_t port = 0;
+ u_int8_t syn = 0;
+ unsigned char *body = data ;//+ sizeof( struct packet );
+ switch ( header->p.packet_type ) {
+ case 4:
+ port = ntohs( ((struct ipv4_pkt *) data )->second.th_dport );
+ syn = sizeof( struct ipv4_pkt );
+ break;
+ case 6:
+ port = ntohs( ((struct ipv6_pkt *) data )->second.th_dport );
+ syn = sizeof( struct ipv6_pkt );
+ break;
+ }
#define END 400
unsigned char * end = body + ( ( length > END )? END : length );
- fprintf( stderr, "%s %d %d %d ", tell_ip( ip4 ), syn, port, length );
+ fprintf( stderr, "%s %d %d %d ", tell_ip( header ), syn, port, length );
while ( body < end ) {
unsigned char c = *body++;
if ( c < ' ' || c >= 127 || 1 ) {
*/
static unsigned char *ssl_host(unsigned char *data,int length) {
// Check that it's a "Client Hello" message
- unsigned char *p = data + sizeof( struct headers ) + 12;
+ unsigned char *p;
+ switch ( ((struct packet *) data)->p.packet_type ) {
+ case 4:
+ p = data + sizeof( struct ipv4_pkt ) + 12; //??
+ break;
+ case 6:
+ p = data + sizeof( struct ipv6_pkt ) + 0; //??
+ break;
+ default:
+ return 0;
+ }
if ( p[0] != 0x16 || p[1] != 0x03 || p[5] != 0x01 || p[6] != 0x00 ) {
return 0;
}
* "Host:" attribute.
*/
static unsigned char *http_host(unsigned char *data,int length) {
- unsigned char *body = data + sizeof( struct headers );
+ unsigned char *body = data + sizeof( struct packet );
+ switch ( ((struct packet *) data)->p.packet_type ) {
+ case 4:
+ body = data + sizeof( struct ipv4_pkt );
+ break;
+ case 6:
+ body = data + sizeof( struct ipv6_pkt );
+ break;
+ default:
+ return 0;
+ }
if ( ( strncmp( (char*) body, "GET ", 4 ) != 0 ) &&
( strncmp( (char*) body, "POST ", 5 ) != 0 ) ) {
return 0;
unsigned char *data;
int length = nfq_get_payload( nfa, &data);
int verdict = NF_ACCEPT;
- u_int32_t ip4 = get_dest_ip4( data );
+ struct packet *header = get_headerP( data );
#if 0
- fprintf( stderr, "PKT %s %d\n", tell_ip( ip4 ), length );
+ fprintf( stderr, "PKT %s %d\n", tell_ip( header ), length );
#endif
if ( length >= 100 ) {
unsigned char *host = http_host( data, length );
#if 1
- fprintf( stderr, "HTTP HOST %s %s\n", tell_ip( ip4 ), host );
+ fprintf( stderr, "HTTP HOST %s %s\n", tell_ip( header ), host );
#endif
if ( host == 0 ) {
host = ssl_host( data, length );
#if 1
- fprintf( stderr, "SSL HOST %s %s\n", tell_ip( ip4 ), host );
+ fprintf( stderr, "SSL HOST %s %s\n", tell_ip( header ), host );
#endif
}
if ( host ) {
add_cache( host, ix );
#if 1
fprintf( stderr, "%s %d %s ** %d\n",
- tell_ip( ip4 ), hash_code( host ), host, ix );
+ tell_ip( header ), hash_code( host ), host, ix );
#endif
if ( ix > 0 ) {
verdict = NF_DROP;