diff -aur a/debian/include/linux/netfilter_ipv4/ipt_ULOG.h b/debian/include/linux/netfilter_ipv4/ipt_ULOG.h --- a/debian/include/linux/netfilter_ipv4/ipt_ULOG.h 2010-04-08 22:18:47.000000000 +0100 +++ b/debian/include/linux/netfilter_ipv4/ipt_ULOG.h 2010-04-08 22:25:50.000000000 +0100 @@ -31,15 +31,28 @@ char prefix[ULOG_PREFIX_LEN]; }; +/* This is needed to fix the mismatch between the field sizes in kernel + * and userspace. In particular, Debian sparc port features 32-bit + * userspace, but 64-bit kernel, leading to size mismatch. Structure + * above is not used anywhere in ulogd, otherwise it would need to be + * similarly mangled. */ +#ifdef __sparc__ +#define KERNEL_LONG long long +#define KERNEL_SIZE_T unsigned long long +#else +#define KERNEL_LONG long +#define KERNEL_SIZE_T size_t +#endif + /* Format of the ULOG packets passed through netlink */ typedef struct ulog_packet_msg { - unsigned long mark; - long timestamp_sec; - long timestamp_usec; + unsigned KERNEL_LONG mark; + KERNEL_LONG timestamp_sec; + KERNEL_LONG timestamp_usec; unsigned int hook; char indev_name[IFNAMSIZ]; char outdev_name[IFNAMSIZ]; - size_t data_len; + KERNEL_SIZE_T data_len; char prefix[ULOG_PREFIX_LEN]; unsigned char mac_len; unsigned char mac[ULOG_MAC_LEN]; diff -aur a/debian/patches/ipt_ULOG.patch b/debian/patches/ipt_ULOG.patch --- a/debian/patches/ipt_ULOG.patch 2010-04-08 22:18:47.000000000 +0100 +++ b/debian/patches/ipt_ULOG.patch 2010-04-08 22:19:26.000000000 +0100 @@ -5,7 +5,7 @@ # doesn't work for subdirs #CFLAGS+=$(INCIPULOG) $(INCCONFFILE) -CFLAGS+=-I/lib/modules/`uname -r`/build/include -+CFLAGS+=-I@srcdir@/debian/include ++CFLAGS+=-I$(PWD)/debian/include #CFLAGS+=@DEFS@ #CFLAGS+=-g -DDEBUG -DDEBUG_MYSQL -DDEBUG_PGSQL diff -aur a/extensions/ulogd_BASE.c b/extensions/ulogd_BASE.c --- a/extensions/ulogd_BASE.c 2005-11-25 19:58:26.000000000 +0000 +++ b/extensions/ulogd_BASE.c 2010-04-08 22:18:35.000000000 +0100 @@ -203,7 +203,13 @@ ulog_packet_msg_t *pkt) { ulog_iret_t *ret = ip->result; +#ifdef STRICT_ALIGNMENT + struct iphdr aligned_iph; + memcpy(&aligned_iph, pkt->payload, sizeof(struct iphdr)); + struct iphdr *iph = &aligned_iph; +#else struct iphdr *iph = (struct iphdr *) pkt->payload; +#endif ret[0].value.ui32 = ntohl(iph->saddr); ret[0].flags |= ULOGD_RETF_VALID; @@ -308,7 +314,13 @@ { struct iphdr *iph = (struct iphdr *) pkt->payload; void *protoh = (u_int32_t *)iph + iph->ihl; +#ifdef STRICT_ALIGNMENT + struct tcphdr aligned_tcph; + memcpy(&aligned_tcph, protoh, sizeof(struct tcphdr)); + struct tcphdr *tcph = &aligned_tcph; +#else struct tcphdr *tcph = (struct tcphdr *) protoh; +#endif ulog_iret_t *ret = ip->result; if (iph->protocol != IPPROTO_TCP) @@ -382,7 +394,13 @@ { struct iphdr *iph = (struct iphdr *) pkt->payload; void *protoh = (u_int32_t *)iph + iph->ihl; - struct udphdr *udph = protoh; +#ifdef STRICT_ALIGNMENT + struct udphdr aligned_udph; + memcpy(&aligned_udph, protoh, sizeof(struct udphdr)); + struct udphdr *udph = &aligned_udph; +#else + struct udphdr *udph = (struct udphdr *) protoh; +#endif ulog_iret_t *ret = ip->result; if (iph->protocol != IPPROTO_UDP) @@ -440,7 +458,13 @@ { struct iphdr *iph = (struct iphdr *) pkt->payload; void *protoh = (u_int32_t *)iph + iph->ihl; - struct icmphdr *icmph = protoh; +#ifdef STRICT_ALIGNMENT + struct icmphdr aligned_icmph; + memcpy(&aligned_icmph, protoh, sizeof(struct icmphdr)); + struct icmphdr *icmph = &aligned_icmph; +#else + struct icmphdr *icmph = (struct icmphdr *) protoh; +#endif ulog_iret_t *ret = ip->result; if (iph->protocol != IPPROTO_ICMP) diff -aur a/extensions/ulogd_PWSNIFF.c b/extensions/ulogd_PWSNIFF.c --- a/extensions/ulogd_PWSNIFF.c 2005-11-25 19:58:26.000000000 +0000 +++ b/extensions/ulogd_PWSNIFF.c 2010-04-08 22:16:43.000000000 +0100 @@ -64,7 +64,13 @@ static ulog_iret_t *_interp_pwsniff(ulog_interpreter_t *ip, ulog_packet_msg_t *pkt) { +#ifdef STRICT_ALIGNMENT + char aligned_payload[sizeof(struct iphdr) + sizeof(struct tcphdr)]; + memcpy(aligned_payload, pkt->payload, sizeof(struct iphdr) + sizeof(struct tcphdr)); + struct iphdr *iph = (struct iphdr *) aligned_payload; +#else struct iphdr *iph = (struct iphdr *) pkt->payload; +#endif void *protoh = (u_int32_t *)iph + iph->ihl; struct tcphdr *tcph = protoh; u_int32_t tcplen = ntohs(iph->tot_len) - iph->ihl * 4; diff -aur a/include/ulogd/ulogd.h b/include/ulogd/ulogd.h --- a/include/ulogd/ulogd.h 2005-11-25 19:58:25.000000000 +0000 +++ b/include/ulogd/ulogd.h 2010-04-08 21:49:22.000000000 +0100 @@ -56,6 +56,12 @@ #define ULOGD_ERROR 7 /* error condition, requires user action */ #define ULOGD_FATAL 8 /* fatal, program aborted */ + +/* whether the platform has strict alignment requirements */ +#ifdef __sparc__ +#define STRICT_ALIGNMENT +#endif + typedef struct ulog_iret { /* next interpreter return (key) in the global list */ struct ulog_iret *next;