<?xml version="1.0" encoding="UTF-8"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://purl.org/rss/1.0/" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:syn="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/">
  <channel about="http://blog.gmane.org/gmane.comp.security.firewalls.netfilter.devel">
    <title>gmane.comp.security.firewalls.netfilter.devel</title>
    <link>http://blog.gmane.org/gmane.comp.security.firewalls.netfilter.devel</link>
    <description/>
    <syn:updatePeriod>hourly</syn:updatePeriod>
    <syn:updateFrequency>1</syn:updateFrequency>
    <syn:updateBase>1901-01-01T00:00+00:00</syn:updateBase>
    <items>
      <rdf:Seq>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/27412"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/27411"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/27410"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/27409"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/27408"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/27407"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/27406"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/27405"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/27404"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/27403"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/27402"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/27401"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/27400"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/27399"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/27398"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/27397"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/27396"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/27395"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/27394"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/27393"/>
      </rdf:Seq>
    </items>
    <image rdf:resource="http://gmane.org/img/gmane-25t.png"/>
    <textinput rdf:resource=""/>
  </channel>
  <image rdf:about="http://gmane.org/img/gmane-25t.png">
    <title>Gmane</title>
    <url>http://gmane.org/img/gmane-25t.png</url>
    <link>http://gmane.org</link>
  </image>
  <item rdf:about="http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/27412">
    <title>Re: [PATCH] More secure SYSRQ for xtables-addons</title>
    <link>http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/27412</link>
    <description>
On Tuesday 2008-12-02 02:39, Patrick McHardy wrote:
It looks similar to RFC 2617 HA1 generation. Should be ok.
In paranoia mode, the administrator can always change the
password after using it (effectively making it some sort of OTP).

On the other hand, xt_SYSRQ could, theoretically, also do a full
three-way authentication instead of the SPA it currently does. But I
think that is a bit of overkill.
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo&lt; at &gt;vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

</description>
    <dc:creator>Jan Engelhardt</dc:creator>
    <dc:date>2008-12-02T01:53:37</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/27411">
    <title>Re: sg_set_page not usable for .bss?</title>
    <link>http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/27411</link>
    <description>
On Tuesday 2008-12-02 01:14, David Miller wrote:
Yes, kmalloc is already used. But then, what sort of address
does kmalloc return, if not an address within kernelspace?
(usually &gt;=0xc0000000 on standard i386)
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo&lt; at &gt;vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

</description>
    <dc:creator>Jan Engelhardt</dc:creator>
    <dc:date>2008-12-02T01:41:02</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/27410">
    <title>Re: [PATCH] More secure SYSRQ for xtables-addons</title>
    <link>http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/27410</link>
    <description>
This module is starting to look kind of useful. Maybe its time for
a resubmission for review and possibly merging once these patches
are included.

If we were to merge it, it would also be good to get some feedback
from the crypto guys about whether the chosen authentication scheme
meets its claims.
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo&lt; at &gt;vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

</description>
    <dc:creator>Patrick McHardy</dc:creator>
    <dc:date>2008-12-02T01:39:31</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/27409">
    <title>Re: sg_set_page not usable for .bss?</title>
    <link>http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/27409</link>
    <description>From: Jan Engelhardt &lt;jengelh&lt; at &gt;medozas.de&gt;
Date: Tue, 2 Dec 2008 01:13:34 +0100 (CET)


kmalloc and copy it there, or something like that, you just
can't use in-kernel addresses, ever.

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo&lt; at &gt;vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

</description>
    <dc:creator>David Miller</dc:creator>
    <dc:date>2008-12-02T00:14:18</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/27408">
    <title>Re: sg_set_page not usable for .bss?</title>
    <link>http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/27408</link>
    <description>
On Tuesday 2008-12-02 01:10, David Miller wrote:
Great :-)  So what is the best way to use the SHA1 crypto algo
with in-kernel addresses?


Jan
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo&lt; at &gt;vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

</description>
    <dc:creator>Jan Engelhardt</dc:creator>
    <dc:date>2008-12-02T00:13:34</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/27407">
    <title>Re: sg_set_page not usable for .bss?</title>
    <link>http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/27407</link>
    <description>From: Jan Engelhardt &lt;jengelh&lt; at &gt;medozas.de&gt;
Date: Mon, 1 Dec 2008 23:40:18 +0100 (CET)


You can't use these interfaces on kernel image addresses.
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo&lt; at &gt;vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

</description>
    <dc:creator>David Miller</dc:creator>
    <dc:date>2008-12-02T00:10:26</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/27406">
    <title>sg_set_page not usable for .bss?</title>
    <link>http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/27406</link>
    <description>
On Monday 2008-12-01 23:02, John Haxby wrote:

Well, sysrq_password is in the .bss section, where as digest_password
is on the heap due to being kmalloc'ed. Maybe that makes a difference?
Someone more versed with the virtual memory layer might know.

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo&lt; at &gt;vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

</description>
    <dc:creator>Jan Engelhardt</dc:creator>
    <dc:date>2008-12-01T22:40:18</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/27405">
    <title>Re: [PATCH] More secure SYSRQ for xtables-addons</title>
    <link>http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/27405</link>
    <description>
On Monday 2008-12-01 23:02, John Haxby wrote:

Oh drats, I did not see that. That's why I prefer explicit zero tests
everywhere (except bools, because they are bools, and not
integers/pointers), e.g.

for (i = 0; sysrq_password[i] != '\0'; ++i)

Also, \n could be simply tested for by adding it to the for condition:

for (i = 0; sysrq_password[i] != '\0' &amp;&amp;
     sysrq_password[i] != '\n'; ++i)
/* loop */;

Turns out doing so saves 7 bytes on i586 ;-)
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo&lt; at &gt;vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

</description>
    <dc:creator>Jan Engelhardt</dc:creator>
    <dc:date>2008-12-01T22:37:58</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/27404">
    <title>Re: [PATCH] More secure SYSRQ for xtables-addons</title>
    <link>http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/27404</link>
    <description>I didn't like that much either: the reason given was that it didn't want 
to rely on kernel resources but that's quite a weak reason for including 
its own sha-1.  On the other hand, for kernels where there isn't an 
sha-1 available that does make sense.
Thanks, I'll work that into the man page.
I think it does this anyway doesn't it?   The "sysrq_password[i]" loop 
test stops at the '\0' and the "if (sysrq_password[i] == '\n') break" 
breaks out early if there's a '\n' in the string.  The next assignment 
either overwrites the trailing '\0' with another one or null-terminates 
the string at the first LF.
No :-)   Eventually I discovered the reason my code wasn't working boils 
down to the definition of sg_set_buf:

    sg_set_page(sg, virt_to_page(buf), buflen, offset_in_page(buf))

which doesn't work for sysrq_password.   I don't know why I'll double check.
Yes.


Yes.

Thanks again.

jch
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo&lt; at &gt;vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

</description>
    <dc:creator>John Haxby</dc:creator>
    <dc:date>2008-12-01T22:02:12</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/27403">
    <title>[ULOGD2 PATCH 08/18] Treat nice function return.</title>
    <link>http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/27403</link>
    <description>gcc was warning that the return of the nice function should
be treated. This patch adds an error message in case of failure.

Signed-off-by: Eric Leblond &lt;eric&lt; at &gt;inl.fr&gt;
---
 src/ulogd.c |    8 +++++++-
 1 files changed, 7 insertions(+), 1 deletions(-)

diff --git a/src/ulogd.c b/src/ulogd.c
index e69079d..ead35b5 100644
--- a/src/ulogd.c
+++ b/src/ulogd.c
&lt; at &gt;&lt; at &gt; -1129,7 +1129,13 &lt; at &gt;&lt; at &gt; int main(int argc, char* argv[])
 }
 }
 
-nice(-1);
+errno = 0;
+if (nice(-1) == -1) {
+if (errno != 0)
+ulogd_log(ULOGD_ERROR, "Could not nice process: %s\n",
+  strerror(errno));
+}
+
 
 if (daemonize){
 if (fork()) {
</description>
    <dc:creator>Eric Leblond</dc:creator>
    <dc:date>2008-12-01T21:36:06</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/27402">
    <title>[ULOGD2 PATCH 10/18] Don't free pluginstance when leaving</title>
    <link>http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/27402</link>
    <description>If we free pluginstance in the stop function we won't
be able to iter anymore on the stack linked list.

Signed-off-by: Eric Leblond &lt;eric&lt; at &gt;inl.fr&gt;
---
 input/packet/ulogd_inppkt_NFLOG.c |    2 --
 input/packet/ulogd_inppkt_ULOG.c  |    1 -
 2 files changed, 0 insertions(+), 3 deletions(-)

diff --git a/input/packet/ulogd_inppkt_NFLOG.c b/input/packet/ulogd_inppkt_NFLOG.c
index e27355d..9a39234 100644
--- a/input/packet/ulogd_inppkt_NFLOG.c
+++ b/input/packet/ulogd_inppkt_NFLOG.c
&lt; at &gt;&lt; at &gt; -569,8 +569,6 &lt; at &gt;&lt; at &gt; static int stop(struct ulogd_pluginstance *pi)
 nflog_unbind_group(ui-&gt;nful_gh);
 nflog_close(ui-&gt;nful_h);
 
-free(pi);
-
 return 0;
 }
 
diff --git a/input/packet/ulogd_inppkt_ULOG.c b/input/packet/ulogd_inppkt_ULOG.c
index 00975de..719898d 100644
--- a/input/packet/ulogd_inppkt_ULOG.c
+++ b/input/packet/ulogd_inppkt_ULOG.c
&lt; at &gt;&lt; at &gt; -309,7 +309,6 &lt; at &gt;&lt; at &gt; static int fini(struct ulogd_pluginstance *pi)
 struct ulog_input *ui = (struct ulog_input *)pi-&gt;private;
 
 ulogd_unregister_fd(&amp;ui-&gt;ulog_fd);
-free(pi);
 
 return 0;
 }
</description>
    <dc:creator>Eric Leblond</dc:creator>
    <dc:date>2008-12-01T21:36:08</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/27401">
    <title>[ULOGD2 PATCH 17/18] Fix memory leak in destructor_nfct().</title>
    <link>http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/27401</link>
    <description>This patch fixes a memroy leak in the destructor function which was not
releasing the memory allocated for each connection tracking entry.

Signed-off-by: Eric Leblond &lt;eric&lt; at &gt;inl.fr&gt;
---
 input/flow/ulogd_inpflow_NFCT.c |   10 ++++++++++
 1 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/input/flow/ulogd_inpflow_NFCT.c b/input/flow/ulogd_inpflow_NFCT.c
index a39bf08..1730ec9 100644
--- a/input/flow/ulogd_inpflow_NFCT.c
+++ b/input/flow/ulogd_inpflow_NFCT.c
&lt; at &gt;&lt; at &gt; -692,6 +692,13 &lt; at &gt;&lt; at &gt; static int read_cb_nfct(int fd, unsigned int what, void *param)
 return 0;
 }
 
+static int do_free(void *data1, void *data2)
+{
+struct ct_timestamp *ts = data2;
+free(ts-&gt;ct);
+}
+
+
 static int do_purge(void *data1, void *data2)
 {
 int ret;
&lt; at &gt;&lt; at &gt; -887,6 +894,9 &lt; at &gt;&lt; at &gt; static int destructor_nfct(struct ulogd_pluginstance *pi)
 struct nfct_pluginstance *cpi = (void *) pi-&gt;private;
 int rc;
 
+/* free existent entries */
+hashtable_iterate(cpi-&gt;ct_active, NULL, do_free);
+
 hashtable_destroy(cpi-&gt;ct_active);
 
 rc = nfct_close(cpi-&gt;cth);
</description>
    <dc:creator>Eric Leblond</dc:creator>
    <dc:date>2008-12-01T21:36:15</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/27400">
    <title>[ULOGD2 PATCH 01/18] add ukey_* function for key assignation</title>
    <link>http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/27400</link>
    <description>From: Pablo Neira Ayuso &lt;pablo&lt; at &gt;netfilter.org&gt;

This patch cleans up the current key assignation by introducing a
set of functions ukey_* to set the key value as Eric Leblond and
we discussed during the latest Netfilter Workshop. This patch is
based on an idea from Holger Eitzenberger.

Signed-off-by: Eric Leblond &lt;eric&lt; at &gt;inl.fr&gt;
---
 filter/raw2packet/ulogd_raw2packet_BASE.c  |  217 ++++++++++------------------
 filter/raw2packet/ulogd_raw2packet_LOCAL.c |    7 +-
 filter/ulogd_filter_HWHDR.c                |   76 +++++-----
 filter/ulogd_filter_IFINDEX.c              |   30 +++--
 filter/ulogd_filter_IP2BIN.c               |    9 +-
 filter/ulogd_filter_IP2STR.c               |   15 +-
 filter/ulogd_filter_MARK.c                 |    4 +-
 filter/ulogd_filter_PRINTFLOW.c            |    3 +-
 filter/ulogd_filter_PRINTPKT.c             |    3 +-
 filter/ulogd_filter_PWSNIFF.c              |   27 ++--
 include/ulogd/ulogd.h                      |   60 ++++++++-
 input/flow/ulogd_inpflow_NFCT.c            |  159 +++++++--------------
 input/packet/ulogd_inppkt_NFLOG.c          |  101 +++++---------
 input/packet/ulogd_inppkt_ULOG.c           |   45 ++----
 output/pcap/ulogd_output_PCAP.c            |   11 +-
 output/ulogd_output_NACCT.c                |   34 +++---
 util/printflow.c                           |   52 ++++----
 util/printpkt.c                            |  146 ++++++++++---------
 18 files changed, 448 insertions(+), 551 deletions(-)

diff --git a/filter/raw2packet/ulogd_raw2packet_BASE.c b/filter/raw2packet/ulogd_raw2packet_BASE.c
index e61d904..c38c696 100644
--- a/filter/raw2packet/ulogd_raw2packet_BASE.c
+++ b/filter/raw2packet/ulogd_raw2packet_BASE.c
&lt; at &gt;&lt; at &gt; -521,43 +521,25 &lt; at &gt;&lt; at &gt; static int _interp_tcp(struct ulogd_pluginstance *pi, struct tcphdr *tcph,
 if (len &lt; sizeof(struct tcphdr))
 return ULOGD_IRET_OK;
 
-ret[KEY_TCP_SPORT].u.value.ui16 = ntohs(tcph-&gt;source);
-ret[KEY_TCP_SPORT].flags |= ULOGD_RETF_VALID;
-ret[KEY_TCP_DPORT].u.value.ui16 = ntohs(tcph-&gt;dest);
-ret[KEY_TCP_DPORT].flags |= ULOGD_RETF_VALID;
-ret[KEY_TCP_SEQ].u.value.ui32 = ntohl(tcph-&gt;seq);
-ret[KEY_TCP_SEQ].flags |= ULOGD_RETF_VALID;
-ret[KEY_TCP_ACKSEQ].u.value.ui32 = ntohl(tcph-&gt;ack_seq);
-ret[KEY_TCP_ACKSEQ].flags |= ULOGD_RETF_VALID;
-ret[KEY_TCP_OFFSET].u.value.ui8 = ntohs(tcph-&gt;doff);
-ret[KEY_TCP_OFFSET].flags |= ULOGD_RETF_VALID;
-ret[KEY_TCP_RESERVED].u.value.ui8 = ntohs(tcph-&gt;res1);
-ret[KEY_TCP_RESERVED].flags |= ULOGD_RETF_VALID;
-ret[KEY_TCP_WINDOW].u.value.ui16 = ntohs(tcph-&gt;window);
-ret[KEY_TCP_WINDOW].flags |= ULOGD_RETF_VALID;
-
-ret[KEY_TCP_URG].u.value.b = tcph-&gt;urg;
-ret[KEY_TCP_URG].flags |= ULOGD_RETF_VALID;
-if (tcph-&gt;urg) {
-ret[KEY_TCP_URGP].u.value.ui16 = ntohs(tcph-&gt;urg_ptr);
-ret[KEY_TCP_URGP].flags |= ULOGD_RETF_VALID;
-}
-ret[KEY_TCP_ACK].u.value.b = tcph-&gt;ack;
-ret[KEY_TCP_ACK].flags |= ULOGD_RETF_VALID;
-ret[KEY_TCP_PSH].u.value.b = tcph-&gt;psh;
-ret[KEY_TCP_PSH].flags |= ULOGD_RETF_VALID;
-ret[KEY_TCP_RST].u.value.b = tcph-&gt;rst;
-ret[KEY_TCP_RST].flags |= ULOGD_RETF_VALID;
-ret[KEY_TCP_SYN].u.value.b = tcph-&gt;syn;
-ret[KEY_TCP_SYN].flags |= ULOGD_RETF_VALID;
-ret[KEY_TCP_FIN].u.value.b = tcph-&gt;fin;
-ret[KEY_TCP_FIN].flags |= ULOGD_RETF_VALID;
-ret[KEY_TCP_RES1].u.value.b = tcph-&gt;res1;
-ret[KEY_TCP_RES1].flags |= ULOGD_RETF_VALID;
-ret[KEY_TCP_RES2].u.value.b = tcph-&gt;res2;
-ret[KEY_TCP_RES2].flags |= ULOGD_RETF_VALID;
-ret[KEY_TCP_CSUM].u.value.ui16 = ntohs(tcph-&gt;check);
-ret[KEY_TCP_CSUM].u.value.ui16 = ULOGD_RETF_VALID;
+okey_set_u16(&amp;ret[KEY_TCP_SPORT], ntohs(tcph-&gt;source));
+okey_set_u16(&amp;ret[KEY_TCP_DPORT], ntohs(tcph-&gt;dest));
+okey_set_u32(&amp;ret[KEY_TCP_SEQ], ntohl(tcph-&gt;seq));
+okey_set_u32(&amp;ret[KEY_TCP_ACKSEQ], ntohl(tcph-&gt;ack_seq));
+okey_set_u8(&amp;ret[KEY_TCP_OFFSET], ntohs(tcph-&gt;doff));
+okey_set_u8(&amp;ret[KEY_TCP_RESERVED], ntohs(tcph-&gt;res1));
+okey_set_u16(&amp;ret[KEY_TCP_WINDOW], ntohs(tcph-&gt;window));
+
+okey_set_b(&amp;ret[KEY_TCP_URG], tcph-&gt;urg);
+if (tcph-&gt;urg)
+okey_set_u16(&amp;ret[KEY_TCP_URGP], ntohs(tcph-&gt;urg_ptr));
+okey_set_b(&amp;ret[KEY_TCP_ACK], tcph-&gt;ack);
+okey_set_b(&amp;ret[KEY_TCP_PSH], tcph-&gt;psh);
+okey_set_b(&amp;ret[KEY_TCP_RST], tcph-&gt;rst);
+okey_set_b(&amp;ret[KEY_TCP_SYN], tcph-&gt;syn);
+okey_set_b(&amp;ret[KEY_TCP_FIN], tcph-&gt;fin);
+okey_set_b(&amp;ret[KEY_TCP_RES1], tcph-&gt;res1);
+okey_set_b(&amp;ret[KEY_TCP_RES2], tcph-&gt;res2);
+okey_set_u16(&amp;ret[KEY_TCP_CSUM], ntohs(tcph-&gt;check));
 
 return ULOGD_IRET_OK;
 }
&lt; at &gt;&lt; at &gt; -575,14 +557,10 &lt; at &gt;&lt; at &gt; static int _interp_udp(struct ulogd_pluginstance *pi, struct udphdr *udph,
 if (len &lt; sizeof(struct udphdr))
 return ULOGD_IRET_OK;
 
-ret[KEY_UDP_SPORT].u.value.ui16 = ntohs(udph-&gt;source);
-ret[KEY_UDP_SPORT].flags |= ULOGD_RETF_VALID;
-ret[KEY_UDP_DPORT].u.value.ui16 = ntohs(udph-&gt;dest);
-ret[KEY_UDP_DPORT].flags |= ULOGD_RETF_VALID;
-ret[KEY_UDP_LEN].u.value.ui16 = ntohs(udph-&gt;len);
-ret[KEY_UDP_LEN].flags |= ULOGD_RETF_VALID;
-ret[KEY_UDP_CSUM].u.value.ui16 = ntohs(udph-&gt;check);
-ret[KEY_UDP_CSUM].flags |= ULOGD_RETF_VALID;
+okey_set_u16(&amp;ret[KEY_UDP_SPORT], ntohs(udph-&gt;source));
+okey_set_u16(&amp;ret[KEY_UDP_DPORT], ntohs(udph-&gt;dest));
+okey_set_u16(&amp;ret[KEY_UDP_LEN], ntohs(udph-&gt;len));
+okey_set_u16(&amp;ret[KEY_UDP_CSUM], ntohs(udph-&gt;check));
 
 return ULOGD_IRET_OK;
 }
&lt; at &gt;&lt; at &gt; -599,33 +577,28 &lt; at &gt;&lt; at &gt; static int _interp_icmp(struct ulogd_pluginstance *pi, struct icmphdr *icmph,
 if (len &lt; sizeof(struct icmphdr))
 return ULOGD_IRET_OK;
 
-ret[KEY_ICMP_TYPE].u.value.ui8 = icmph-&gt;type;
-ret[KEY_ICMP_TYPE].flags |= ULOGD_RETF_VALID;
-ret[KEY_ICMP_CODE].u.value.ui8 = icmph-&gt;code;
-ret[KEY_ICMP_CODE].flags |= ULOGD_RETF_VALID;
+okey_set_u8(&amp;ret[KEY_ICMP_TYPE], icmph-&gt;type);
+okey_set_u8(&amp;ret[KEY_ICMP_CODE], icmph-&gt;code);
 
 switch (icmph-&gt;type) {
 case ICMP_ECHO:
 case ICMP_ECHOREPLY:
-ret[KEY_ICMP_ECHOID].u.value.ui16 = ntohs(icmph-&gt;un.echo.id);
-ret[KEY_ICMP_ECHOID].flags |= ULOGD_RETF_VALID;
-ret[KEY_ICMP_ECHOSEQ].u.value.ui16 = ntohs(icmph-&gt;un.echo.sequence);
-ret[KEY_ICMP_ECHOSEQ].flags |= ULOGD_RETF_VALID;
+okey_set_u16(&amp;ret[KEY_ICMP_ECHOID], ntohs(icmph-&gt;un.echo.id));
+okey_set_u16(&amp;ret[KEY_ICMP_ECHOSEQ],
+     ntohs(icmph-&gt;un.echo.sequence));
 break;
 case ICMP_REDIRECT:
 case ICMP_PARAMETERPROB:
-ret[KEY_ICMP_GATEWAY].u.value.ui32 = ntohl(icmph-&gt;un.gateway);
-ret[KEY_ICMP_GATEWAY].flags |= ULOGD_RETF_VALID;
+okey_set_u32(&amp;ret[KEY_ICMP_GATEWAY], ntohl(icmph-&gt;un.gateway));
 break;
 case ICMP_DEST_UNREACH:
 if (icmph-&gt;code == ICMP_FRAG_NEEDED) {
-ret[KEY_ICMP_FRAGMTU].u.value.ui16 = ntohs(icmph-&gt;un.frag.mtu);
-ret[KEY_ICMP_FRAGMTU].flags |= ULOGD_RETF_VALID;
+okey_set_u16(&amp;ret[KEY_ICMP_FRAGMTU],
+     ntohs(icmph-&gt;un.frag.mtu));
 }
 break;
 }
-ret[KEY_ICMP_CSUM].u.value.ui16 = icmph-&gt;checksum;
-ret[KEY_ICMP_CSUM].flags |= ULOGD_RETF_VALID;
+okey_set_u16(&amp;ret[KEY_ICMP_CSUM], icmph-&gt;checksum);
 
 return ULOGD_IRET_OK;
 }
&lt; at &gt;&lt; at &gt; -642,22 +615,18 &lt; at &gt;&lt; at &gt; static int _interp_icmpv6(struct ulogd_pluginstance *pi, struct icmp6_hdr *icmph
 if (len &lt; sizeof(struct icmp6_hdr))
 return ULOGD_IRET_OK;
 
-ret[KEY_ICMPV6_TYPE].u.value.ui8 = icmph-&gt;icmp6_type;
-ret[KEY_ICMPV6_TYPE].flags |= ULOGD_RETF_VALID;
-ret[KEY_ICMPV6_CODE].u.value.ui8 = icmph-&gt;icmp6_code;
-ret[KEY_ICMPV6_CODE].flags |= ULOGD_RETF_VALID;
+okey_set_u8(&amp;ret[KEY_ICMPV6_TYPE], icmph-&gt;icmp6_type);
+okey_set_u8(&amp;ret[KEY_ICMPV6_CODE], icmph-&gt;icmp6_code);
 
 switch (icmph-&gt;icmp6_type) {
 case ICMP6_ECHO_REQUEST:
 case ICMP6_ECHO_REPLY:
-ret[KEY_ICMPV6_ECHOID].u.value.ui16 = ntohs(icmph-&gt;icmp6_id);
-ret[KEY_ICMPV6_ECHOID].flags |= ULOGD_RETF_VALID;
-ret[KEY_ICMPV6_ECHOSEQ].u.value.ui16 = ntohs(icmph-&gt;icmp6_seq);
-ret[KEY_ICMPV6_ECHOSEQ].flags |= ULOGD_RETF_VALID;
+okey_set_u16(&amp;ret[KEY_ICMPV6_ECHOID], ntohs(icmph-&gt;icmp6_id));
+okey_set_u16(&amp;ret[KEY_ICMPV6_ECHOSEQ],
+      ntohs(icmph-&gt;icmp6_seq));
 break;
 }
-ret[KEY_ICMPV6_CSUM].u.value.ui16 = icmph-&gt;icmp6_cksum;
-ret[KEY_ICMPV6_CSUM].flags |= ULOGD_RETF_VALID;
+okey_set_u16(&amp;ret[KEY_ICMPV6_CSUM], icmph-&gt;icmp6_cksum);
 
 return ULOGD_IRET_OK;
 }
&lt; at &gt;&lt; at &gt; -691,33 +660,23 &lt; at &gt;&lt; at &gt; static int _interp_iphdr(struct ulogd_pluginstance *pi, u_int32_t len)
 {
 struct ulogd_key *ret = pi-&gt;output.keys;
 struct iphdr *iph =
-GET_VALUE(pi-&gt;input.keys, INKEY_RAW_PCKT).ptr;
+ikey_get_ptr(&amp;pi-&gt;input.keys[INKEY_RAW_PCKT]);
 void *nexthdr = (u_int32_t *)iph + iph-&gt;ihl;
 
 if (len &lt; sizeof(struct iphdr) || len &lt;= (u_int32_t)(iph-&gt;ihl * 4))
 return ULOGD_IRET_OK;
 len -= iph-&gt;ihl * 4;
 
-ret[KEY_IP_SADDR].u.value.ui32 = iph-&gt;saddr;
-ret[KEY_IP_SADDR].flags |= ULOGD_RETF_VALID;
-ret[KEY_IP_DADDR].u.value.ui32 = iph-&gt;daddr;
-ret[KEY_IP_DADDR].flags |= ULOGD_RETF_VALID;
-ret[KEY_IP_PROTOCOL].u.value.ui8 = iph-&gt;protocol;
-ret[KEY_IP_PROTOCOL].flags |= ULOGD_RETF_VALID;
-ret[KEY_IP_TOS].u.value.ui8 = iph-&gt;tos;
-ret[KEY_IP_TOS].flags |= ULOGD_RETF_VALID;
-ret[KEY_IP_TTL].u.value.ui8 = iph-&gt;ttl;
-ret[KEY_IP_TTL].flags |= ULOGD_RETF_VALID;
-ret[KEY_IP_TOTLEN].u.value.ui16 = ntohs(iph-&gt;tot_len);
-ret[KEY_IP_TOTLEN].flags |= ULOGD_RETF_VALID;
-ret[KEY_IP_IHL].u.value.ui8 = iph-&gt;ihl;
-ret[KEY_IP_IHL].flags |= ULOGD_RETF_VALID;
-ret[KEY_IP_CSUM].u.value.ui16 = ntohs(iph-&gt;check);
-ret[KEY_IP_CSUM].flags |= ULOGD_RETF_VALID;
-ret[KEY_IP_ID].u.value.ui16 = ntohs(iph-&gt;id);
-ret[KEY_IP_ID].flags |= ULOGD_RETF_VALID;
-ret[KEY_IP_FRAGOFF].u.value.ui16 = ntohs(iph-&gt;frag_off);
-ret[KEY_IP_FRAGOFF].flags |= ULOGD_RETF_VALID;
+okey_set_u32(&amp;ret[KEY_IP_SADDR], iph-&gt;saddr);
+okey_set_u32(&amp;ret[KEY_IP_DADDR], iph-&gt;daddr);
+okey_set_u8(&amp;ret[KEY_IP_PROTOCOL], iph-&gt;protocol);
+okey_set_u8(&amp;ret[KEY_IP_TOS], iph-&gt;tos);
+okey_set_u8(&amp;ret[KEY_IP_TTL], iph-&gt;ttl);
+okey_set_u16(&amp;ret[KEY_IP_TOTLEN], ntohs(iph-&gt;tot_len));
+okey_set_u8(&amp;ret[KEY_IP_IHL], iph-&gt;ihl);
+okey_set_u16(&amp;ret[KEY_IP_CSUM], ntohs(iph-&gt;check));
+okey_set_u16(&amp;ret[KEY_IP_ID], ntohs(iph-&gt;id));
+okey_set_u16(&amp;ret[KEY_IP_FRAGOFF], ntohs(iph-&gt;frag_off));
 
 switch (iph-&gt;protocol) {
 case IPPROTO_TCP:
&lt; at &gt;&lt; at &gt; -760,8 +719,7 &lt; at &gt;&lt; at &gt; static int ip6_ext_hdr(u_int8_t nexthdr)
 static int _interp_ipv6hdr(struct ulogd_pluginstance *pi, u_int32_t len)
 {
 struct ulogd_key *ret = pi-&gt;output.keys;
-struct ip6_hdr *ipv6h =
-GET_VALUE(pi-&gt;input.keys, INKEY_RAW_PCKT).ptr;
+struct ip6_hdr *ipv6h = ikey_get_ptr(&amp;pi-&gt;input.keys[INKEY_RAW_PCKT]);
 unsigned int ptr, hdrlen = 0;
 u_int8_t curhdr;
 int fragment = 0;
&lt; at &gt;&lt; at &gt; -769,20 +727,14 &lt; at &gt;&lt; at &gt; static int _interp_ipv6hdr(struct ulogd_pluginstance *pi, u_int32_t len)
 if (len &lt; sizeof(struct ip6_hdr))
 return ULOGD_IRET_OK;
 
-memcpy(ret[KEY_IP_SADDR].u.value.ui128, &amp;ipv6h-&gt;ip6_src,
-       sizeof(ipv6h-&gt;ip6_src));
-ret[KEY_IP_SADDR].flags |= ULOGD_RETF_VALID;
-memcpy(ret[KEY_IP_DADDR].u.value.ui128, &amp;ipv6h-&gt;ip6_dst,
-       sizeof(ipv6h-&gt;ip6_dst));
-ret[KEY_IP_DADDR].flags |= ULOGD_RETF_VALID;
-ret[KEY_IP6_PAYLOAD_LEN].u.value.ui16 = ntohs(ipv6h-&gt;ip6_plen);
-ret[KEY_IP6_PAYLOAD_LEN].flags |= ULOGD_RETF_VALID;
-ret[KEY_IP6_PRIORITY].u.value.ui8 = ntohl(ipv6h-&gt;ip6_flow &amp; 0x0ff00000) &gt;&gt; 20;
-ret[KEY_IP6_PRIORITY].flags |= ULOGD_RETF_VALID;
-ret[KEY_IP6_FLOWLABEL].u.value.ui32 = ntohl(ipv6h-&gt;ip6_flow &amp; 0x000fffff);
-ret[KEY_IP6_FLOWLABEL].flags |= ULOGD_RETF_VALID;
-ret[KEY_IP6_HOPLIMIT].u.value.ui8 = ipv6h-&gt;ip6_hlim;
-ret[KEY_IP6_HOPLIMIT].flags |= ULOGD_RETF_VALID;
+okey_set_u128(&amp;ret[KEY_IP_SADDR], &amp;ipv6h-&gt;ip6_src);
+okey_set_u128(&amp;ret[KEY_IP_DADDR], &amp;ipv6h-&gt;ip6_dst);
+okey_set_u16(&amp;ret[KEY_IP6_PAYLOAD_LEN], ntohs(ipv6h-&gt;ip6_plen));
+okey_set_u8(&amp;ret[KEY_IP6_PRIORITY],
+    ntohl(ipv6h-&gt;ip6_flow &amp; 0x0ff00000) &gt;&gt; 20);
+okey_set_u32(&amp;ret[KEY_IP6_FLOWLABEL],
+     ntohl(ipv6h-&gt;ip6_flow &amp; 0x000fffff));
+okey_set_u8(&amp;ret[KEY_IP6_HOPLIMIT], ipv6h-&gt;ip6_hlim);
 
 curhdr = ipv6h-&gt;ip6_nxt;
 ptr = sizeof(struct ip6_hdr);
&lt; at &gt;&lt; at &gt; -803,10 +755,10 &lt; at &gt;&lt; at &gt; static int _interp_ipv6hdr(struct ulogd_pluginstance *pi, u_int32_t len)
 return ULOGD_IRET_OK;
 len -= hdrlen;
 
-ret[KEY_IP6_FRAG_OFF].u.value.ui16 = ntohs(fh-&gt;ip6f_offlg &amp; IP6F_OFF_MASK);
-ret[KEY_IP6_FRAG_OFF].flags |= ULOGD_RETF_VALID;
-ret[KEY_IP6_FRAG_ID].u.value.ui32 = ntohl(fh-&gt;ip6f_ident);
-ret[KEY_IP6_FRAG_ID].flags |= ULOGD_RETF_VALID;
+okey_set_u16(&amp;ret[KEY_IP6_FRAG_OFF],
+     ntohs(fh-&gt;ip6f_offlg &amp; IP6F_OFF_MASK));
+okey_set_u32(&amp;ret[KEY_IP6_FRAG_ID],
+     ntohl(fh-&gt;ip6f_ident));
 
 if (ntohs(fh-&gt;ip6f_offlg &amp; IP6F_OFF_MASK))
 fragment = 1;
&lt; at &gt;&lt; at &gt; -857,8 +809,7 &lt; at &gt;&lt; at &gt; static int _interp_ipv6hdr(struct ulogd_pluginstance *pi, u_int32_t len)
 goto out;
 
 
-ret[KEY_IP_PROTOCOL].u.value.ui8 = curhdr;
-ret[KEY_IP_PROTOCOL].flags |= ULOGD_RETF_VALID;
+okey_set_u8(&amp;ret[KEY_IP_PROTOCOL], curhdr);
 
 switch (curhdr) {
 case IPPROTO_TCP:
&lt; at &gt;&lt; at &gt; -873,8 +824,7 &lt; at &gt;&lt; at &gt; static int _interp_ipv6hdr(struct ulogd_pluginstance *pi, u_int32_t len)
 }
 
 out:
-ret[KEY_IP6_NEXTHDR].u.value.ui8 = curhdr;
-ret[KEY_IP6_NEXTHDR].flags |= ULOGD_RETF_VALID;
+okey_set_u8(&amp;ret[KEY_IP6_NEXTHDR], curhdr);
 return ULOGD_IRET_OK;
 }
 
&lt; at &gt;&lt; at &gt; -885,31 +835,19 &lt; at &gt;&lt; at &gt; static int _interp_arp(struct ulogd_pluginstance *pi, u_int32_t len)
 {
 struct ulogd_key *ret = pi-&gt;output.keys;
 const struct ether_arp *arph =
-GET_VALUE(pi-&gt;input.keys, INKEY_RAW_PCKT).ptr;
+ikey_get_ptr(&amp;pi-&gt;input.keys[INKEY_RAW_PCKT]);
 
 if (len &lt; sizeof(struct ether_arp))
 return ULOGD_IRET_OK;
 
-ret[KEY_ARP_HTYPE].u.value.ui16 = ntohs(arph-&gt;arp_hrd);
-SET_VALID(ret[KEY_ARP_HTYPE]);
-ret[KEY_ARP_PTYPE].u.value.ui16 = ntohs(arph-&gt;arp_pro);
-SET_VALID(ret[KEY_ARP_PTYPE]);
-ret[KEY_ARP_OPCODE].u.value.ui16 = ntohs(arph-&gt;arp_op);
-SET_VALID(ret[KEY_ARP_OPCODE]);
-
-ret[KEY_ARP_SHA].u.value.ptr = &amp;arph-&gt;arp_sha;
-SET_VALID(ret[KEY_ARP_SHA]);
-
-memcpy(&amp;ret[KEY_ARP_SPA].u.value.ui32, &amp;arph-&gt;arp_spa,
-       sizeof(u_int32_t));
-SET_VALID(ret[KEY_ARP_SPA]);
-
-ret[KEY_ARP_THA].u.value.ptr = &amp;arph-&gt;arp_tha;
-SET_VALID(ret[KEY_ARP_THA]);
+okey_set_u16(&amp;ret[KEY_ARP_HTYPE], ntohs(arph-&gt;arp_hrd));
+okey_set_u16(&amp;ret[KEY_ARP_PTYPE], ntohs(arph-&gt;arp_pro));
+okey_set_u16(&amp;ret[KEY_ARP_OPCODE], ntohs(arph-&gt;arp_op));
 
-memcpy(&amp;ret[KEY_ARP_TPA].u.value.ui32, &amp;arph-&gt;arp_tpa,
-       sizeof(u_int32_t));
-SET_VALID(ret[KEY_ARP_TPA]);
+okey_set_ptr(&amp;ret[KEY_ARP_SHA], &amp;arph-&gt;arp_sha);
+okey_set_ptr(&amp;ret[KEY_ARP_SPA], &amp;arph-&gt;arp_spa),
+okey_set_ptr(&amp;ret[KEY_ARP_THA], &amp;arph-&gt;arp_tha);
+okey_set_ptr(&amp;ret[KEY_ARP_TPA], &amp;arph-&gt;arp_tpa);
 
 return ULOGD_IRET_OK;
 }
&lt; at &gt;&lt; at &gt; -921,7 +859,7 &lt; at &gt;&lt; at &gt; static int _interp_arp(struct ulogd_pluginstance *pi, u_int32_t len)
 static int _interp_bridge(struct ulogd_pluginstance *pi, u_int32_t len)
 {
 const u_int16_t proto =
-GET_VALUE(pi-&gt;input.keys, INKEY_OOB_PROTOCOL).ui16;
+ikey_get_u16(&amp;pi-&gt;input.keys[INKEY_OOB_PROTOCOL]);
 
 switch (proto) {
 case ETH_P_IP:
&lt; at &gt;&lt; at &gt; -942,13 +880,12 &lt; at &gt;&lt; at &gt; static int _interp_bridge(struct ulogd_pluginstance *pi, u_int32_t len)
 
 static int _interp_pkt(struct ulogd_pluginstance *pi)
 {
-u_int32_t len = GET_VALUE(pi-&gt;input.keys, INKEY_RAW_PCKTLEN).ui32;
-u_int8_t family = GET_VALUE(pi-&gt;input.keys, INKEY_OOB_FAMILY).ui8;
+u_int32_t len = ikey_get_u32(&amp;pi-&gt;input.keys[INKEY_RAW_PCKTLEN]);
+u_int8_t family = ikey_get_u8(&amp;pi-&gt;input.keys[INKEY_OOB_FAMILY]);
 struct ulogd_key *ret = pi-&gt;output.keys;
 
-ret[KEY_OOB_PROTOCOL].u.value.ui16 =
-GET_VALUE(pi-&gt;input.keys, INKEY_OOB_PROTOCOL).ui16;
-SET_VALID(ret[KEY_OOB_PROTOCOL]);
+okey_set_u16(&amp;ret[KEY_OOB_PROTOCOL],
+     ikey_get_u16(&amp;pi-&gt;input.keys[INKEY_OOB_PROTOCOL]));
 
 switch (family) {
 case AF_INET:
diff --git a/filter/raw2packet/ulogd_raw2packet_LOCAL.c b/filter/raw2packet/ulogd_raw2packet_LOCAL.c
index bf400d7..fdfc7c8 100644
--- a/filter/raw2packet/ulogd_raw2packet_LOCAL.c
+++ b/filter/raw2packet/ulogd_raw2packet_LOCAL.c
&lt; at &gt;&lt; at &gt; -51,11 +51,8 &lt; at &gt;&lt; at &gt; static ulog_iret_t *_interp_local(ulog_interpreter_t *ip,
     gettimeofday(&amp;tv, NULL);
 
     /* put date */
-    ret[0].value.ui32 = (unsigned long) tv.tv_sec;
-    ret[0].flags |= ULOGD_RETF_VALID;
-
-    ret[1].value.ptr = hostname;
-    ret[1].flags |= ULOGD_RETF_VALID;
+    okey_set_ui32(&amp;ret[0], (unsigned long) tv.tv_sec);
+    okey_set_ptr(&amp;ret[1], hostname);
 
     return ret;
 }
diff --git a/filter/ulogd_filter_HWHDR.c b/filter/ulogd_filter_HWHDR.c
index 8df4f00..33e8316 100644
--- a/filter/ulogd_filter_HWHDR.c
+++ b/filter/ulogd_filter_HWHDR.c
&lt; at &gt;&lt; at &gt; -3,6 +3,7 &lt; at &gt;&lt; at &gt;
  * ulogd interpreter plugin for HWMAC
  *
  * (C) 2008 by Eric Leblond &lt;eric&lt; at &gt;inl.fr&gt;
+ * (C) 2008 by Pablo Neira Ayuso &lt;pablo&lt; at &gt;netfilter.org&gt;
  *
  * Based on ulogd_filter_IFINDEX.c Harald Welte &lt;laforge&lt; at &gt;gnumonks.org&gt;
  *
&lt; at &gt;&lt; at &gt; -128,32 +129,41 &lt; at &gt;&lt; at &gt; static int parse_mac2str(struct ulogd_key *ret, unsigned char *mac,
 buf_cur += sprintf(buf_cur, "%02x%c", mac[i],
 i == len - 1 ? 0 : ':');
 
-ret[okey].u.value.ptr = mac_str;
-ret[okey].flags |= ULOGD_RETF_VALID;
+okey_set_ptr(&amp;ret[okey], mac_str);
 
 return ULOGD_IRET_OK;
 }
 
+static void *hwhdr_get_saddr(struct ulogd_key *inp)
+{
+return ikey_get_ptr(&amp;inp[KEY_RAW_MAC]) + ETH_ALEN;
+}
+
+static void *hwhdr_get_daddr(struct ulogd_key *inp)
+{
+return ikey_get_ptr(&amp;inp[KEY_RAW_MAC]);
+}
+
+static u_int16_t hwhdr_get_len(struct ulogd_key *inp)
+{
+void *len = ikey_get_ptr(&amp;inp[KEY_RAW_MAC]) + 2 * ETH_ALEN;
+return ntohs(*(u_int16_t *) len);
+}
 static int parse_ethernet(struct ulogd_key *ret, struct ulogd_key *inp)
 {
 int fret;
 if (!pp_is_valid(inp, KEY_RAW_MAC_SADDR)) {
-fret = parse_mac2str(ret, 
-     GET_VALUE(inp, KEY_RAW_MAC).ptr
-+ ETH_ALEN,
+fret = parse_mac2str(ret, hwhdr_get_saddr(inp),
      KEY_MAC_SADDR, ETH_ALEN);
 if (fret != ULOGD_IRET_OK)
 return fret;
 }
-fret = parse_mac2str(ret, GET_VALUE(inp, KEY_RAW_MAC).ptr,
+fret = parse_mac2str(ret, hwhdr_get_daddr(inp),
      KEY_MAC_DADDR, ETH_ALEN);
 if (fret != ULOGD_IRET_OK)
 return fret;
 
-ret[KEY_MAC_PROTOCOL].u.value.ui16 =
-ntohs(*(u_int16_t *) (GET_VALUE(inp, KEY_RAW_MAC).ptr
-+ 2 * ETH_ALEN));
-ret[KEY_MAC_PROTOCOL].flags |= ULOGD_RETF_VALID;
+okey_set_u16(&amp;ret[KEY_MAC_PROTOCOL], hwhdr_get_len(inp));
 
 return ULOGD_IRET_OK;
 }
&lt; at &gt;&lt; at &gt; -164,46 +174,41 &lt; at &gt;&lt; at &gt; static int interp_mac2str(struct ulogd_pluginstance *pi)
 struct ulogd_key *inp = pi-&gt;input.keys;
 u_int16_t type = 0;
 
-if (pp_is_valid(inp, KEY_OOB_PROTOCOL)) {
-ret[KEY_MAC_PROTOCOL].u.value.ui16 =
-GET_VALUE(inp, KEY_OOB_PROTOCOL).ui16;
-ret[KEY_MAC_PROTOCOL].flags |= ULOGD_RETF_VALID;
-}
+if (pp_is_valid(inp, KEY_OOB_PROTOCOL))
+okey_set_u16(&amp;ret[KEY_MAC_PROTOCOL],
+     ikey_get_u16(&amp;inp[KEY_OOB_PROTOCOL]));
 
 if (pp_is_valid(inp, KEY_RAW_MAC_SADDR)) {
 int fret;
 fret = parse_mac2str(ret,
-     GET_VALUE(inp, KEY_RAW_MAC_SADDR).ptr,
+     ikey_get_ptr(&amp;inp[KEY_RAW_MAC_SADDR]),
      KEY_MAC_SADDR,
-     GET_VALUE(inp, KEY_RAW_MAC_ADDRLEN).ui16);
+     ikey_get_u16(&amp;inp[KEY_RAW_MAC_ADDRLEN]));
 if (fret != ULOGD_IRET_OK)
 return fret;
 }
 
 if (pp_is_valid(inp, KEY_RAW_MAC)) {
-if (GET_VALUE(inp, KEY_RAW_MAC_ADDRLEN).ui16 == ETH_ALEN) {
-ret[KEY_MAC_TYPE].u.value.ui16 = ARPHRD_ETHER;
-ret[KEY_MAC_TYPE].flags |= ULOGD_RETF_VALID;
-} else {
-ret[KEY_MAC_TYPE].u.value.ui16 = ARPHRD_VOID;
-ret[KEY_MAC_TYPE].flags |= ULOGD_RETF_VALID;
-}
+if (ikey_get_u16(&amp;inp[KEY_RAW_MAC_ADDRLEN]) == ETH_ALEN)
+okey_set_u16(&amp;ret[KEY_MAC_TYPE], ARPHRD_ETHER);
+else
+okey_set_u16(&amp;ret[KEY_MAC_TYPE], ARPHRD_VOID);
+
 return ULOGD_IRET_OK;
 }
 
 if (pp_is_valid(inp, KEY_RAW_TYPE)) {
 /* NFLOG with Linux &gt;= 2.6.27 case */
-ret[KEY_MAC_TYPE].u.value.ui16 = type =
-GET_VALUE(inp, KEY_RAW_TYPE).ui16;
-ret[KEY_MAC_TYPE].flags |= ULOGD_RETF_VALID;
+type = ikey_get_u16(&amp;inp[KEY_RAW_TYPE]);
+okey_set_u16(&amp;ret[KEY_MAC_TYPE], type);
 } else {
 /* ULOG case, treat ethernet encapsulation */
-if (GET_VALUE(inp, KEY_RAW_MACLEN).ui16 == ETH_HLEN) {
-ret[KEY_MAC_TYPE].u.value.ui16 = type = ARPHRD_ETHER;
-ret[KEY_MAC_TYPE].flags |= ULOGD_RETF_VALID;
+if (ikey_get_u16(&amp;inp[KEY_RAW_MACLEN]) == ETH_HLEN) {
+type = ARPHRD_ETHER;
+okey_set_u16(&amp;ret[KEY_MAC_TYPE], type);
 } else {
-ret[KEY_MAC_TYPE].u.value.ui16 = type = ARPHRD_VOID;
-ret[KEY_MAC_TYPE].flags |= ULOGD_RETF_VALID;
+type = ARPHRD_VOID;
+okey_set_u16(&amp;ret[KEY_MAC_TYPE], type);
 }
 }
 
&lt; at &gt;&lt; at &gt; -213,10 +218,9 &lt; at &gt;&lt; at &gt; static int interp_mac2str(struct ulogd_pluginstance *pi)
 default:
 /* convert raw header to string */
 return parse_mac2str(ret,
-     GET_VALUE(inp, KEY_RAW_MAC).ptr,
-     KEY_MAC_ADDR,
-     GET_VALUE(inp,
-     KEY_RAW_MACLEN).ui16);
+    ikey_get_ptr(&amp;inp[KEY_RAW_MAC]),
+    KEY_MAC_ADDR,
+    ikey_get_u16(&amp;inp[KEY_RAW_MACLEN]));
 }
 return ULOGD_IRET_OK;
 }
diff --git a/filter/ulogd_filter_IFINDEX.c b/filter/ulogd_filter_IFINDEX.c
index f7571bd..f56ee0b 100644
--- a/filter/ulogd_filter_IFINDEX.c
+++ b/filter/ulogd_filter_IFINDEX.c
&lt; at &gt;&lt; at &gt; -3,6 +3,7 &lt; at &gt;&lt; at &gt;
  * ulogd interpreter plugin for ifindex to ifname conversion
  *
  * (C) 2005 by Harald Welte &lt;laforge&lt; at &gt;gnumonks.org&gt;
+ * (C) 2008 by Pablo Neira Ayuso &lt;pablo&lt; at &gt;netfilter.org&gt;
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License version 2 
&lt; at &gt;&lt; at &gt; -61,20 +62,25 &lt; at &gt;&lt; at &gt; static int interp_ifindex(struct ulogd_pluginstance *pi)
 {
 struct ulogd_key *ret = pi-&gt;output.keys;
 struct ulogd_key *inp = pi-&gt;input.keys;
+void *ptr;
 
-ret[0].u.value.ptr = calloc(IFNAMSIZ, sizeof(char)); 
-nlif_index2name(nlif_inst, inp[0].u.source-&gt;u.value.ui32,
-ret[0].u.value.ptr);
-if (((char *)ret[0].u.value.ptr)[0] == '*')
-((char *)(ret[0].u.value.ptr))[0] = 0; 
-ret[0].flags |= ULOGD_RETF_VALID;
-
-ret[1].u.value.ptr = calloc(IFNAMSIZ, sizeof(char)); 
-nlif_index2name(nlif_inst, inp[1].u.source-&gt;u.value.ui32,
-ret[1].u.value.ptr);
-if (((char *)ret[1].u.value.ptr)[0] == '*')
-((char *)(ret[1].u.value.ptr))[0] = 0; 
-ret[1].flags |= ULOGD_RETF_VALID;
+ptr = calloc(IFNAMSIZ, sizeof(char));
+if (!ptr)
+return ULOGD_IRET_ERR;
+
+nlif_index2name(nlif_inst, ikey_get_u32(&amp;inp[0]), ptr);
+if (((char *)ptr)[0] == '*')
+((char *)(ptr))[0] = 0;
+okey_set_ptr(&amp;ret[0], ptr);
+
+ptr = calloc(IFNAMSIZ, sizeof(char));
+if (!ptr)
+return ULOGD_IRET_ERR;
+
+nlif_index2name(nlif_inst, ikey_get_u32(&amp;inp[1]), ptr);
+if (((char *)ptr)[0] == '*')
+((char *)(ptr))[0] = 0; 
+okey_set_ptr(&amp;ret[1], ptr);
 
 return ULOGD_IRET_OK;
 }
diff --git a/filter/ulogd_filter_IP2BIN.c b/filter/ulogd_filter_IP2BIN.c
index 2d9fc16..1d2865e 100644
--- a/filter/ulogd_filter_IP2BIN.c
+++ b/filter/ulogd_filter_IP2BIN.c
&lt; at &gt;&lt; at &gt; -137,12 +137,12 &lt; at &gt;&lt; at &gt; static char *ip2bin(struct ulogd_key* inp, int index, char family)
 
 switch (family) {
 case AF_INET6:
-addr = (struct in6_addr *) GET_VALUE(inp, index).ui128;
+addr = (struct in6_addr *)ikey_get_u128(&amp;inp[index]);
 break;
 case AF_INET:
 /* Convert IPv4 to IPv4 in IPv6 */
 addr = &amp;ip4_addr;
-uint32_to_ipv6(GET_VALUE(inp, index).ui32, addr);
+uint32_to_ipv6(ikey_get_u32(&amp;inp[index]), addr);
 break;
 default:
 /* TODO handle error */
&lt; at &gt;&lt; at &gt; -176,13 +176,12 &lt; at &gt;&lt; at &gt; static int interp_ip2bin(struct ulogd_pluginstance *pi)
 struct ulogd_key *ret = pi-&gt;output.keys;
 struct ulogd_key *inp = pi-&gt;input.keys;
 int i;
-int oob_family = GET_VALUE(inp, KEY_OOB_FAMILY).ui8;
+int oob_family = ikey_get_u8(&amp;inp[KEY_OOB_FAMILY]);
 
 /* Iter on all addr fields */
 for(i = START_KEY; i &lt; MAX_KEY; i++) {
 if (pp_is_valid(inp, i)) {
-ret[i-1].u.value.ptr = ip2bin(inp, i, oob_family);
-ret[i-1].flags |= ULOGD_RETF_VALID;
+okey_set_ptr(&amp;ret[i-1], ip2bin(inp, i, oob_family));
 }
 }
 
diff --git a/filter/ulogd_filter_IP2STR.c b/filter/ulogd_filter_IP2STR.c
index a1c1e87..df94c72 100644
--- a/filter/ulogd_filter_IP2STR.c
+++ b/filter/ulogd_filter_IP2STR.c
&lt; at &gt;&lt; at &gt; -145,7 +145,7 &lt; at &gt;&lt; at &gt; static struct ulogd_key ip2str_keys[] = {
 static char *ip2str(struct ulogd_key *inp, int index)
 {
 char tmp[IPADDR_LENGTH];
-char family = GET_VALUE(inp, KEY_OOB_FAMILY).ui8;
+char family = ikey_get_u8(&amp;inp[KEY_OOB_FAMILY]);
 char convfamily = family;
 
 if (family == AF_BRIDGE) {
&lt; at &gt;&lt; at &gt; -154,7 +154,7 &lt; at &gt;&lt; at &gt; static char *ip2str(struct ulogd_key *inp, int index)
   "No protocol inside AF_BRIDGE packet\n");
 return NULL;
 }
-switch (GET_VALUE(inp, KEY_OOB_PROTOCOL).ui16) {
+switch (ikey_get_u16(&amp;inp[KEY_OOB_PROTOCOL])) {
 case ETH_P_IPV6:
 convfamily = AF_INET6;
 break;
&lt; at &gt;&lt; at &gt; -172,15 +172,15 &lt; at &gt;&lt; at &gt; static char *ip2str(struct ulogd_key *inp, int index)
 }
 
 switch (convfamily) {
+u_int32_t ip;
 case AF_INET6:
 inet_ntop(AF_INET6,
-  GET_VALUE(inp, index).ui128,
+  ikey_get_u128(&amp;inp[index]),
   tmp, sizeof(tmp));
 break;
 case AF_INET:
-inet_ntop(AF_INET,
-  &amp;GET_VALUE(inp, index).ui32,
-  tmp, sizeof(tmp));
+ip = ikey_get_u32(&amp;inp[index]);
+inet_ntop(AF_INET, &amp;ip, tmp, sizeof(tmp));
 break;
 default:
 /* TODO error handling */
&lt; at &gt;&lt; at &gt; -199,8 +199,7 &lt; at &gt;&lt; at &gt; static int interp_ip2str(struct ulogd_pluginstance *pi)
 /* Iter on all addr fields */
 for (i = START_KEY; i &lt;= MAX_KEY; i++) {
 if (pp_is_valid(inp, i)) {
-ret[i-START_KEY].u.value.ptr = ip2str(inp, i);
-ret[i-START_KEY].flags |= ULOGD_RETF_VALID;
+okey_set_ptr(&amp;ret[i-START_KEY], ip2str(inp, i));
 }
 }
 
diff --git a/filter/ulogd_filter_MARK.c b/filter/ulogd_filter_MARK.c
index 98f5dae..1a7c2fd 100644
--- a/filter/ulogd_filter_MARK.c
+++ b/filter/ulogd_filter_MARK.c
&lt; at &gt;&lt; at &gt; -72,14 +72,14 &lt; at &gt;&lt; at &gt; static int interp_mark(struct ulogd_pluginstance *pi)
 {
 struct ulogd_key *inp = pi-&gt;input.keys;
 if (pp_is_valid(inp, KEY_CT_MARK)) {
-if ((GET_VALUE(inp, KEY_CT_MARK).ui32 &amp;
+if ((ikey_get_u32(&amp;inp[KEY_CT_MARK]) &amp;
 pi-&gt;config_kset-&gt;ces[MARK_MASK].u.value) !=
 (u_int32_t) pi-&gt;config_kset-&gt;ces[MARK_MARK].u.value
    ) {
 return ULOGD_IRET_STOP;
 }
 } else if (pp_is_valid(inp, KEY_OOB_MARK)) {
-if ((GET_VALUE(inp, KEY_OOB_MARK).ui32 &amp;
+if ((ikey_get_u32(&amp;inp[KEY_OOB_MARK]) &amp;
 pi-&gt;config_kset-&gt;ces[MARK_MASK].u.value) !=
 (u_int32_t) pi-&gt;config_kset-&gt;ces[MARK_MARK].u.value
    ) {
diff --git a/filter/ulogd_filter_PRINTFLOW.c b/filter/ulogd_filter_PRINTFLOW.c
index b78c37b..1de1ba6 100644
--- a/filter/ulogd_filter_PRINTFLOW.c
+++ b/filter/ulogd_filter_PRINTFLOW.c
&lt; at &gt;&lt; at &gt; -37,8 +37,7 &lt; at &gt;&lt; at &gt; static int printflow_interp(struct ulogd_pluginstance *upi)
 static char buf[4096];
 
 printflow_print(inp, buf);
-ret[0].u.value.ptr = buf;
-ret[0].flags |= ULOGD_RETF_VALID;
+okey_set_ptr(&amp;ret[0], buf);
 return ULOGD_IRET_OK;
 }
 
diff --git a/filter/ulogd_filter_PRINTPKT.c b/filter/ulogd_filter_PRINTPKT.c
index 62a3cf7..3313194 100644
--- a/filter/ulogd_filter_PRINTPKT.c
+++ b/filter/ulogd_filter_PRINTPKT.c
&lt; at &gt;&lt; at &gt; -37,8 +37,7 &lt; at &gt;&lt; at &gt; static int printpkt_interp(struct ulogd_pluginstance *upi)
 static char buf[4096];
 
 printpkt_print(inp, buf);
-ret[0].u.value.ptr = buf;
-ret[0].flags |= ULOGD_RETF_VALID;
+okey_set_ptr(&amp;ret[0], buf);
 return ULOGD_IRET_OK;
 }
 
diff --git a/filter/ulogd_filter_PWSNIFF.c b/filter/ulogd_filter_PWSNIFF.c
index 3cbafb6..a6cbf94 100644
--- a/filter/ulogd_filter_PWSNIFF.c
+++ b/filter/ulogd_filter_PWSNIFF.c
&lt; at &gt;&lt; at &gt; -116,25 +116,22 &lt; at &gt;&lt; at &gt; static int interp_pwsniff(struct ulogd_pluginstance *pi)
 }
 
 if (len) {
-ret[0].u.value.ptr = (char *) malloc(len+1);
-ret[0].flags |= ULOGD_RETF_VALID;
-if (!ret[0].u.value.ptr) {
-ulogd_log(ULOGD_ERROR, "OOM (size=%u)\n", len);
+char *ptr;
+ptr = (char *) malloc(len+1);
+if (!ptr)
 return ULOGD_IRET_ERR;
-}
-strncpy((char *) ret[0].u.value.ptr, (char *)begp, len);
-*((char *)ret[0].u.value.ptr + len) = '\0';
+strncpy(ptr, (char *)begp, len);
+ptr[len] = '\0';
+okey_set_ptr(&amp;ret[0], ptr);
 }
 if (pw_len) {
-ret[1].u.value.ptr = (char *) malloc(pw_len+1);
-ret[1].flags |= ULOGD_RETF_VALID;
-if (!ret[1].u.value.ptr){
-ulogd_log(ULOGD_ERROR, "OOM (size=%u)\n", pw_len);
+char *ptr;
+ptr = (char *) malloc(pw_len+1);
+if (!ptr)
 return ULOGD_IRET_ERR;
-}
-strncpy((char *)ret[1].u.value.ptr, (char *)pw_begp, pw_len);
-*((char *)ret[1].u.value.ptr + pw_len) = '\0';
-
+strncpy(ptr, (char *)pw_begp, pw_len);
+ptr[pw_len] = '\0';
+okey_set_ptr(&amp;ret[1], ptr);
 }
 return ULOGD_IRET_OK;
 }
diff --git a/include/ulogd/ulogd.h b/include/ulogd/ulogd.h
index 776111a..3f6d784 100644
--- a/include/ulogd/ulogd.h
+++ b/include/ulogd/ulogd.h
&lt; at &gt;&lt; at &gt; -18,6 +18,7 &lt; at &gt;&lt; at &gt;
 #include &lt;stdio.h&gt;
 #include &lt;signal.h&gt;/* need this because of extension-sighandler */
 #include &lt;sys/types.h&gt;
+#include &lt;string.h&gt;
 
 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
 
&lt; at &gt;&lt; at &gt; -126,6 +127,64 &lt; at &gt;&lt; at &gt; struct ulogd_keyset {
 unsigned int type;
 };
 
+static inline void okey_set_b(struct ulogd_key *key, u_int8_t value)
+{
+key-&gt;u.value.b = value;
+key-&gt;flags |= ULOGD_RETF_VALID;
+}
+
+static inline void okey_set_u8(struct ulogd_key *key, u_int8_t value)
+{
+key-&gt;u.value.ui8 = value;
+key-&gt;flags |= ULOGD_RETF_VALID;
+}
+
+static inline void okey_set_u16(struct ulogd_key *key, u_int16_t value)
+{
+key-&gt;u.value.ui16 = value;
+key-&gt;flags |= ULOGD_RETF_VALID;
+}
+
+static inline void okey_set_u32(struct ulogd_key *key, u_int32_t value)
+{
+key-&gt;u.value.ui32 = value;
+key-&gt;flags |= ULOGD_RETF_VALID;
+}
+
+static inline void okey_set_u128(struct ulogd_key *key, const void *value)
+{
+memcpy(key-&gt;u.value.ui128, value, 16);
+key-&gt;flags |= ULOGD_RETF_VALID;
+}
+
+static inline void okey_set_ptr(struct ulogd_key *key, void *value)
+{
+key-&gt;u.value.ptr = value;
+key-&gt;flags |= ULOGD_RETF_VALID;
+}
+
+static inline u_int8_t ikey_get_u8(struct ulogd_key *key)
+{
+return key-&gt;u.source-&gt;u.value.ui8;
+}
+
+static inline u_int16_t ikey_get_u16(struct ulogd_key *key)
+{
+return key-&gt;u.source-&gt;u.value.ui16;
+}
+
+static inline u_int32_t ikey_get_u32(struct ulogd_key *key)
+{
+return key-&gt;u.source-&gt;u.value.ui32;
+}
+
+#define ikey_get_u128 ikey_get_ptr
+
+static inline void *ikey_get_ptr(struct ulogd_key *key)
+{
+return key-&gt;u.source-&gt;u.value.ptr;
+}
+
 struct ulogd_pluginstance_stack;
 struct ulogd_pluginstance;
 struct ulogd_plugin {
&lt; at &gt;&lt; at &gt; -221,7 +280,6 &lt; at &gt;&lt; at &gt; void __ulogd_log(int level, char *file, int line, const char *message, ...);
 #define IS_NEEDED(x)(x.flags &amp; ULOGD_RETF_NEEDED)
 #define SET_NEEDED(x)(x.flags |= ULOGD_RETF_NEEDED)
 
-#define GET_VALUE(res, x)(res[x].u.source-&gt;u.value)
 #define GET_FLAGS(res, x)(res[x].u.source-&gt;flags)
 #define pp_is_valid(res, x)\
 (res[x].u.source &amp;&amp; (GET_FLAGS(res, x) &amp; ULOGD_RETF_VALID))
diff --git a/input/flow/ulogd_inpflow_NFCT.c b/input/flow/ulogd_inpflow_NFCT.c
index 58bb0e2..a33ec35 100644
--- a/input/flow/ulogd_inpflow_NFCT.c
+++ b/input/flow/ulogd_inpflow_NFCT.c
&lt; at &gt;&lt; at &gt; -443,67 +443,39 &lt; at &gt;&lt; at &gt; static int propagate_ct(struct ulogd_pluginstance *upi,
 {
 struct ulogd_key *ret = upi-&gt;output.keys;
 
-ret[NFCT_CT_EVENT].u.value.ui32 = type;
-ret[NFCT_CT_EVENT].flags |= ULOGD_RETF_VALID;
-
-ret[NFCT_OOB_FAMILY].u.value.ui8 = nfct_get_attr_u8(ct, ATTR_L3PROTO);
-ret[NFCT_OOB_FAMILY].flags |= ULOGD_RETF_VALID;
-/* FIXME */
-ret[NFCT_OOB_PROTOCOL].u.value.ui8 = 0;
-ret[NFCT_OOB_PROTOCOL].flags |= ULOGD_RETF_VALID;
+okey_set_u32(&amp;ret[NFCT_CT_EVENT], type);
+okey_set_u8(&amp;ret[NFCT_OOB_FAMILY], nfct_get_attr_u8(ct, ATTR_L3PROTO));
+okey_set_u8(&amp;ret[NFCT_OOB_PROTOCOL], 0); /* FIXME */
 
 switch (nfct_get_attr_u8(ct, ATTR_L3PROTO)) {
 case AF_INET:
-ret[NFCT_ORIG_IP_SADDR].u.value.ui32 =
-nfct_get_attr_u32(ct, ATTR_ORIG_IPV4_SRC);
-ret[NFCT_ORIG_IP_SADDR].flags |= ULOGD_RETF_VALID;
-
-ret[NFCT_ORIG_IP_DADDR].u.value.ui32 =
-nfct_get_attr_u32(ct, ATTR_ORIG_IPV4_DST);
-ret[NFCT_ORIG_IP_DADDR].flags |= ULOGD_RETF_VALID;
-
-ret[NFCT_REPLY_IP_SADDR].u.value.ui32 =
-nfct_get_attr_u32(ct, ATTR_REPL_IPV4_SRC);
-ret[NFCT_REPLY_IP_SADDR].flags |= ULOGD_RETF_VALID;
-
-ret[NFCT_REPLY_IP_DADDR].u.value.ui32 =
-nfct_get_attr_u32(ct, ATTR_REPL_IPV4_DST);
-ret[NFCT_REPLY_IP_DADDR].flags |= ULOGD_RETF_VALID;
-
+okey_set_u32(&amp;ret[NFCT_ORIG_IP_SADDR],
+     nfct_get_attr_u32(ct, ATTR_ORIG_IPV4_SRC));
+okey_set_u32(&amp;ret[NFCT_ORIG_IP_DADDR],
+     nfct_get_attr_u32(ct, ATTR_ORIG_IPV4_DST));
+okey_set_u32(&amp;ret[NFCT_REPLY_IP_SADDR],
+     nfct_get_attr_u32(ct, ATTR_REPL_IPV4_SRC));
+okey_set_u32(&amp;ret[NFCT_REPLY_IP_DADDR],
+     nfct_get_attr_u32(ct, ATTR_REPL_IPV4_DST));
 break;
 case AF_INET6:
-memcpy(ret[NFCT_ORIG_IP_SADDR].u.value.ui128,
-       nfct_get_attr(ct, ATTR_ORIG_IPV6_SRC),
-       sizeof(int32_t) * 4);
-ret[NFCT_ORIG_IP_SADDR].flags |= ULOGD_RETF_VALID;
-
-memcpy(ret[NFCT_ORIG_IP_DADDR].u.value.ui128,
-       nfct_get_attr(ct, ATTR_ORIG_IPV6_DST),
-       sizeof(int32_t) * 4);
-ret[NFCT_ORIG_IP_DADDR].flags |= ULOGD_RETF_VALID;
-
-memcpy(ret[NFCT_REPLY_IP_SADDR].u.value.ui128,
-       nfct_get_attr(ct, ATTR_REPL_IPV6_SRC),
-       sizeof(int32_t) * 4);
-ret[NFCT_REPLY_IP_SADDR].flags |= ULOGD_RETF_VALID;
-
-memcpy(ret[NFCT_REPLY_IP_DADDR].u.value.ui128,
-       nfct_get_attr(ct, ATTR_REPL_IPV6_DST),
-       sizeof(int32_t) * 4);
-ret[NFCT_REPLY_IP_DADDR].flags |= ULOGD_RETF_VALID;
-
+okey_set_u128(&amp;ret[NFCT_ORIG_IP_SADDR],
+      nfct_get_attr(ct, ATTR_ORIG_IPV6_SRC));
+okey_set_u128(&amp;ret[NFCT_ORIG_IP_DADDR],
+      nfct_get_attr(ct, ATTR_ORIG_IPV6_DST));
+okey_set_u128(&amp;ret[NFCT_REPLY_IP_SADDR],
+      nfct_get_attr(ct, ATTR_REPL_IPV6_SRC));
+okey_set_u128(&amp;ret[NFCT_REPLY_IP_DADDR],
+      nfct_get_attr(ct, ATTR_REPL_IPV6_DST));
 break;
 default:
 ulogd_log(ULOGD_NOTICE, "Unknown protocol family (%d)\n",
   nfct_get_attr_u8(ct, ATTR_L3PROTO));
 }
-ret[NFCT_ORIG_IP_PROTOCOL].u.value.ui8 =
-nfct_get_attr_u8(ct, ATTR_ORIG_L4PROTO);
-ret[NFCT_ORIG_IP_PROTOCOL].flags |= ULOGD_RETF_VALID;
-
-ret[NFCT_REPLY_IP_PROTOCOL].u.value.ui8 =
-nfct_get_attr_u8(ct, ATTR_REPL_L4PROTO);
-ret[NFCT_REPLY_IP_PROTOCOL].flags |= ULOGD_RETF_VALID;
+okey_set_u8(&amp;ret[NFCT_ORIG_IP_PROTOCOL],
+    nfct_get_attr_u8(ct, ATTR_ORIG_L4PROTO));
+okey_set_u8(&amp;ret[NFCT_REPLY_IP_PROTOCOL],
+    nfct_get_attr_u8(ct, ATTR_REPL_L4PROTO));
 
 switch (nfct_get_attr_u8(ct, ATTR_ORIG_L4PROTO)) {
 case IPPROTO_TCP:
&lt; at &gt;&lt; at &gt; -511,22 +483,16 &lt; at &gt;&lt; at &gt; static int propagate_ct(struct ulogd_pluginstance *upi,
 case IPPROTO_UDPLITE:
 case IPPROTO_SCTP:
 case IPPROTO_DCCP:
-ret[NFCT_ORIG_L4_SPORT].u.value.ui16 =
-htons(nfct_get_attr_u16(ct, ATTR_ORIG_PORT_SRC));
-ret[NFCT_ORIG_L4_SPORT].flags |= ULOGD_RETF_VALID;
-
-ret[NFCT_ORIG_L4_DPORT].u.value.ui16 =
-htons(nfct_get_attr_u16(ct, ATTR_ORIG_PORT_DST));
-ret[NFCT_ORIG_L4_DPORT].flags |= ULOGD_RETF_VALID;
+okey_set_u16(&amp;ret[NFCT_ORIG_L4_SPORT],
+     htons(nfct_get_attr_u16(ct, ATTR_ORIG_PORT_SRC)));
+okey_set_u16(&amp;ret[NFCT_ORIG_L4_DPORT],
+     htons(nfct_get_attr_u16(ct, ATTR_ORIG_PORT_DST)));
 break;
 case IPPROTO_ICMP:
-ret[NFCT_ICMP_CODE].u.value.ui8 =
-nfct_get_attr_u8(ct, ATTR_ICMP_CODE);
-ret[NFCT_ICMP_CODE].flags |= ULOGD_RETF_VALID;
-
-ret[NFCT_ICMP_TYPE].u.value.ui8 =
-nfct_get_attr_u8(ct, ATTR_ICMP_TYPE);
-ret[NFCT_ICMP_TYPE].flags |= ULOGD_RETF_VALID;
+okey_set_u16(&amp;ret[NFCT_ICMP_CODE],
+     nfct_get_attr_u8(ct, ATTR_ICMP_CODE));
+okey_set_u16(&amp;ret[NFCT_ICMP_TYPE],
+     nfct_get_attr_u8(ct, ATTR_ICMP_TYPE));
 break;
 }
 
&lt; at &gt;&lt; at &gt; -536,55 +502,36 &lt; at &gt;&lt; at &gt; static int propagate_ct(struct ulogd_pluginstance *upi,
 case IPPROTO_UDPLITE:
 case IPPROTO_SCTP:
 case IPPROTO_DCCP:
-ret[NFCT_REPLY_L4_SPORT].u.value.ui16 =
-htons(nfct_get_attr_u16(ct, ATTR_REPL_PORT_SRC));
-ret[NFCT_REPLY_L4_SPORT].flags |= ULOGD_RETF_VALID;
-
-ret[NFCT_REPLY_L4_DPORT].u.value.ui16 =
-htons(nfct_get_attr_u16(ct, ATTR_REPL_PORT_DST));
-ret[NFCT_REPLY_L4_DPORT].flags |= ULOGD_RETF_VALID;
+okey_set_u16(&amp;ret[NFCT_REPLY_L4_SPORT],
+     htons(nfct_get_attr_u16(ct, ATTR_REPL_PORT_SRC)));
+okey_set_u16(&amp;ret[NFCT_REPLY_L4_DPORT],
+     htons(nfct_get_attr_u16(ct, ATTR_REPL_PORT_DST)));
 }
 
-ret[NFCT_ORIG_RAW_PKTLEN].u.value.ui32 =
-nfct_get_attr_u32(ct, ATTR_ORIG_COUNTER_BYTES);
-ret[NFCT_ORIG_RAW_PKTLEN].flags |= ULOGD_RETF_VALID;
-
-ret[NFCT_ORIG_RAW_PKTCOUNT].u.value.ui32 =
-nfct_get_attr_u32(ct, ATTR_ORIG_COUNTER_PACKETS);
-ret[NFCT_ORIG_RAW_PKTCOUNT].flags |= ULOGD_RETF_VALID;
-
-ret[NFCT_REPLY_RAW_PKTLEN].u.value.ui32 =
-nfct_get_attr_u32(ct, ATTR_REPL_COUNTER_BYTES);;
-ret[NFCT_REPLY_RAW_PKTLEN].flags |= ULOGD_RETF_VALID;
+okey_set_u32(&amp;ret[NFCT_ORIG_RAW_PKTLEN],
+     nfct_get_attr_u32(ct, ATTR_ORIG_COUNTER_BYTES));
+okey_set_u32(&amp;ret[NFCT_ORIG_RAW_PKTCOUNT],
+     nfct_get_attr_u32(ct, ATTR_ORIG_COUNTER_PACKETS));
+okey_set_u32(&amp;ret[NFCT_REPLY_RAW_PKTLEN],
+     nfct_get_attr_u32(ct, ATTR_REPL_COUNTER_BYTES));
+okey_set_u32(&amp;ret[NFCT_REPLY_RAW_PKTCOUNT],
+     nfct_get_attr_u32(ct, ATTR_REPL_COUNTER_PACKETS));
 
-ret[NFCT_REPLY_RAW_PKTCOUNT].u.value.ui32 =
-nfct_get_attr_u32(ct, ATTR_REPL_COUNTER_PACKETS);
-ret[NFCT_REPLY_RAW_PKTCOUNT].flags |= ULOGD_RETF_VALID;
-
-ret[NFCT_CT_MARK].u.value.ui32 = nfct_get_attr_u32(ct, ATTR_MARK);
-ret[NFCT_CT_MARK].flags |= ULOGD_RETF_VALID;
-
-ret[NFCT_CT_ID].u.value.ui32 = nfct_get_attr_u32(ct, ATTR_ID);
-ret[NFCT_CT_ID].flags |= ULOGD_RETF_VALID;
+okey_set_u32(&amp;ret[NFCT_CT_MARK], nfct_get_attr_u32(ct, ATTR_MARK));
+okey_set_u32(&amp;ret[NFCT_CT_ID], nfct_get_attr_u32(ct, ATTR_ID));
 
 if (ts) {
 if (ts-&gt;time[START].tv_sec) {
-ret[NFCT_FLOW_START_SEC].u.value.ui32 =
-ts-&gt;time[START].tv_sec;
-ret[NFCT_FLOW_START_SEC].flags |= ULOGD_RETF_VALID;
-
-ret[NFCT_FLOW_START_USEC].u.value.ui32 =
-ts-&gt;time[START].tv_usec;
-ret[NFCT_FLOW_START_USEC].flags |= ULOGD_RETF_VALID;
+okey_set_u32(&amp;ret[NFCT_FLOW_START_SEC],
+     ts-&gt;time[START].tv_sec);
+okey_set_u32(&amp;ret[NFCT_FLOW_START_USEC],
+     ts-&gt;time[START].tv_usec);
 }
 if (ts-&gt;time[STOP].tv_sec) {
-ret[NFCT_FLOW_END_SEC].u.value.ui32 =
-ts-&gt;time[STOP].tv_sec;
-ret[NFCT_FLOW_END_SEC].flags |= ULOGD_RETF_VALID;
-
-ret[NFCT_FLOW_END_USEC].u.value.ui32 =
-ts-&gt;time[STOP].tv_usec;
-ret[NFCT_FLOW_END_USEC].flags |= ULOGD_RETF_VALID;
+okey_set_u32(&amp;ret[NFCT_FLOW_END_SEC],
+     ts-&gt;time[STOP].tv_sec);
+okey_set_u32(&amp;ret[NFCT_FLOW_END_USEC],
+     ts-&gt;time[STOP].tv_usec);
 }
 }
 
diff --git a/input/packet/ulogd_inppkt_NFLOG.c b/input/packet/ulogd_inppkt_NFLOG.c
index 39f915a..5d25eec 100644
--- a/input/packet/ulogd_inppkt_NFLOG.c
+++ b/input/packet/ulogd_inppkt_NFLOG.c
&lt; at &gt;&lt; at &gt; -310,59 +310,43 &lt; at &gt;&lt; at &gt; interp_packet(struct ulogd_pluginstance *upi, struct nflog_data *ldata)
 u_int32_t uid;
 u_int32_t gid;
 
-ret[NFLOG_KEY_OOB_FAMILY].u.value.ui8 = af_ce(upi-&gt;config_kset).u.value;
-ret[NFLOG_KEY_OOB_FAMILY].flags |= ULOGD_RETF_VALID;
-
-ret[NFLOG_KEY_RAW_LABEL].u.value.ui8 =
-label_ce(upi-&gt;config_kset).u.value;
-ret[NFLOG_KEY_RAW_LABEL].flags |= ULOGD_RETF_VALID;
+okey_set_u8(&amp;ret[NFLOG_KEY_OOB_FAMILY], 
+    af_ce(upi-&gt;config_kset).u.value);
+okey_set_u8(&amp;ret[NFLOG_KEY_RAW_LABEL],
+    label_ce(upi-&gt;config_kset).u.value);
 
 if (ph) {
 /* FIXME */
-ret[NFLOG_KEY_OOB_HOOK].u.value.ui8 = ph-&gt;hook;
-ret[NFLOG_KEY_OOB_HOOK].flags |= ULOGD_RETF_VALID;
-ret[NFLOG_KEY_OOB_PROTOCOL].u.value.ui16 =
-ntohs(ph-&gt;hw_protocol);
-ret[NFLOG_KEY_OOB_PROTOCOL].flags |= ULOGD_RETF_VALID;
+okey_set_u8(&amp;ret[NFLOG_KEY_OOB_HOOK], ph-&gt;hook);
+okey_set_u16(&amp;ret[NFLOG_KEY_OOB_PROTOCOL],
+     ntohs(ph-&gt;hw_protocol));
 }
 
 if (nflog_get_msg_packet_hwhdrlen(ldata)) {
-ret[NFLOG_KEY_RAW_MAC].u.value.ptr =
-nflog_get_msg_packet_hwhdr(ldata);
-ret[NFLOG_KEY_RAW_MAC].flags |= ULOGD_RETF_VALID;
-ret[NFLOG_KEY_RAW_MAC_LEN].u.value.ui16 =
-nflog_get_msg_packet_hwhdrlen(ldata);
-ret[NFLOG_KEY_RAW_MAC_LEN].flags |= ULOGD_RETF_VALID;
-ret[NFLOG_KEY_RAW_TYPE].u.value.ui16 =
-nflog_get_hwtype(ldata);
-ret[NFLOG_KEY_RAW_TYPE].flags |= ULOGD_RETF_VALID;
+okey_set_ptr(&amp;ret[NFLOG_KEY_RAW_MAC], 
+     nflog_get_msg_packet_hwhdr(ldata));
+okey_set_u16(&amp;ret[NFLOG_KEY_RAW_MAC_LEN],
+     nflog_get_msg_packet_hwhdrlen(ldata));
+okey_set_u16(&amp;ret[NFLOG_KEY_RAW_TYPE], nflog_get_hwtype(ldata));
 }
 
 if (hw) {
-ret[NFLOG_KEY_RAW_MAC_SADDR].u.value.ptr = hw-&gt;hw_addr;
-ret[NFLOG_KEY_RAW_MAC_SADDR].flags |= ULOGD_RETF_VALID;
-ret[NFLOG_KEY_RAW_MAC_ADDRLEN].u.value.ui16 =
-ntohs(hw-&gt;hw_addrlen);
-ret[NFLOG_KEY_RAW_MAC_ADDRLEN].flags |= ULOGD_RETF_VALID;
+okey_set_ptr(&amp;ret[NFLOG_KEY_RAW_MAC_SADDR], hw-&gt;hw_addr);
+okey_set_u16(&amp;ret[NFLOG_KEY_RAW_MAC_ADDRLEN], 
+     ntohs(hw-&gt;hw_addrlen));
 }
 
 if (payload_len &gt;= 0) {
 /* include pointer to raw packet */
-ret[NFLOG_KEY_RAW_PCKT].u.value.ptr = payload;
-ret[NFLOG_KEY_RAW_PCKT].flags |= ULOGD_RETF_VALID;
-
-ret[NFLOG_KEY_RAW_PCKTLEN].u.value.ui32 = payload_len;
-ret[NFLOG_KEY_RAW_PCKTLEN].flags |= ULOGD_RETF_VALID;
+okey_set_ptr(&amp;ret[NFLOG_KEY_RAW_PCKT], payload);
+okey_set_u32(&amp;ret[NFLOG_KEY_RAW_PCKTLEN], payload_len);
 }
 
 /* number of packets */
-ret[NFLOG_KEY_RAW_PCKTCOUNT].u.value.ui32 = 1;
-ret[NFLOG_KEY_RAW_PCKTCOUNT].flags |= ULOGD_RETF_VALID;
+okey_set_u32(&amp;ret[NFLOG_KEY_RAW_PCKTCOUNT], 1);
 
-if (prefix) {
-ret[NFLOG_KEY_OOB_PREFIX].u.value.ptr = prefix;
-ret[NFLOG_KEY_OOB_PREFIX].flags |= ULOGD_RETF_VALID;
-}
+if (prefix)
+okey_set_ptr(&amp;ret[NFLOG_KEY_OOB_PREFIX], prefix);
 
 /* god knows why timestamp_usec contains crap if timestamp_sec
  * == 0 if (pkt-&gt;timestamp_sec || pkt-&gt;timestamp_usec) { */
&lt; at &gt;&lt; at &gt; -370,41 +354,26 &lt; at &gt;&lt; at &gt; interp_packet(struct ulogd_pluginstance *upi, struct nflog_data *ldata)
 gettimeofday(&amp;ts, NULL);
 
 /* FIXME: convert endianness */
-ret[NFLOG_KEY_OOB_TIME_SEC].u.value.ui32 = ts.tv_sec &amp; 0xffffffff;
-ret[NFLOG_KEY_OOB_TIME_SEC].flags |= ULOGD_RETF_VALID;
-ret[NFLOG_KEY_OOB_TIME_USEC].u.value.ui32 = ts.tv_usec &amp; 0xffffffff;
-ret[NFLOG_KEY_OOB_TIME_USEC].flags |= ULOGD_RETF_VALID;
+okey_set_u32(&amp;ret[NFLOG_KEY_OOB_TIME_SEC], ts.tv_sec &amp; 0xffffffff);
+okey_set_u32(&amp;ret[NFLOG_KEY_OOB_TIME_USEC], ts.tv_usec &amp; 0xffffffff);
 
-ret[NFLOG_KEY_OOB_MARK].u.value.ui32 = mark;
-ret[NFLOG_KEY_OOB_MARK].flags |= ULOGD_RETF_VALID;
+okey_set_u32(&amp;ret[NFLOG_KEY_OOB_MARK], mark);
 
-if (indev &gt; 0) {
-ret[NFLOG_KEY_OOB_IFINDEX_IN].u.value.ui32 = indev;
-ret[NFLOG_KEY_OOB_IFINDEX_IN].flags |= ULOGD_RETF_VALID;
-}
+if (indev &gt; 0)
+okey_set_u32(&amp;ret[NFLOG_KEY_OOB_IFINDEX_IN], indev);
 
-if (outdev &gt; 0) {
-ret[NFLOG_KEY_OOB_IFINDEX_OUT].u.value.ui32 = outdev;
-ret[NFLOG_KEY_OOB_IFINDEX_OUT].flags |= ULOGD_RETF_VALID;
-}
+if (outdev &gt; 0)
+okey_set_u32(&amp;ret[NFLOG_KEY_OOB_IFINDEX_OUT], outdev);
 
-if (nflog_get_uid(ldata, &amp;uid) == 0) {
-ret[NFLOG_KEY_OOB_UID].u.value.ui32 = uid;
-ret[NFLOG_KEY_OOB_UID].flags |= ULOGD_RETF_VALID;
-}
-if (nflog_get_gid(ldata, &amp;gid) == 0) {
-ret[NFLOG_KEY_OOB_GID].u.value.ui32 = gid;
-ret[NFLOG_KEY_OOB_GID].flags |= ULOGD_RETF_VALID;
-}
+if (nflog_get_uid(ldata, &amp;uid) == 0)
+okey_set_u32(&amp;ret[NFLOG_KEY_OOB_UID], uid);
+if (nflog_get_gid(ldata, &amp;gid) == 0)
+okey_set_u32(&amp;ret[NFLOG_KEY_OOB_GID], gid);
+if (nflog_get_seq(ldata, &amp;seq) == 0)
+okey_set_u32(&amp;ret[NFLOG_KEY_OOB_SEQ_LOCAL], seq);
+if (nflog_get_seq_global(ldata, &amp;seq) == 0)
+okey_set_u32(&amp;ret[NFLOG_KEY_OOB_SEQ_GLOBAL], seq);
 
-if (nflog_get_seq(ldata, &amp;seq) == 0) {
-ret[NFLOG_KEY_OOB_SEQ_LOCAL].u.value.ui32 = seq;
-ret[NFLOG_KEY_OOB_SEQ_LOCAL].flags |= ULOGD_RETF_VALID;
-}
-if (nflog_get_seq_global(ldata, &amp;seq) == 0) {
-ret[NFLOG_KEY_OOB_SEQ_GLOBAL].u.value.ui32 = seq;
-ret[NFLOG_KEY_OOB_SEQ_GLOBAL].flags |= ULOGD_RETF_VALID;
-}
 ulogd_propagate_results(upi);
 return 0;
 }
diff --git a/input/packet/ulogd_inppkt_ULOG.c b/input/packet/ulogd_inppkt_ULOG.c
index 3fdb42e..00975de 100644
--- a/input/packet/ulogd_inppkt_ULOG.c
+++ b/input/packet/ulogd_inppkt_ULOG.c
&lt; at &gt;&lt; at &gt; -190,54 +190,39 &lt; at &gt;&lt; at &gt; static int interp_packet(struct ulogd_pluginstance *ip, ulog_packet_msg_t *pkt)
 struct ulogd_key *ret = ip-&gt;output.keys;
 
 if (pkt-&gt;mac_len) {
-ret[ULOG_KEY_RAW_MAC].u.value.ptr = pkt-&gt;mac;
-ret[ULOG_KEY_RAW_MAC].flags |= ULOGD_RETF_VALID;
-ret[ULOG_KEY_RAW_MAC_LEN].u.value.ui16 = pkt-&gt;mac_len;
-ret[ULOG_KEY_RAW_MAC_LEN].flags |= ULOGD_RETF_VALID;
+okey_set_ptr(&amp;ret[ULOG_KEY_RAW_MAC], pkt-&gt;mac);
+okey_set_u16(&amp;ret[ULOG_KEY_RAW_MAC_LEN], pkt-&gt;mac_len);
 }
 
-ret[ULOG_KEY_RAW_LABEL].u.value.ui8 = ip-&gt;config_kset-&gt;ces[3].u.value;
-ret[ULOG_KEY_RAW_LABEL].flags |= ULOGD_RETF_VALID;
+okey_set_u8(&amp;ret[ULOG_KEY_RAW_LABEL], ip-&gt;config_kset-&gt;ces[3].u.value);
 
 /* include pointer to raw ipv4 packet */
-ret[ULOG_KEY_RAW_PCKT].u.value.ptr = pkt-&gt;payload;
-ret[ULOG_KEY_RAW_PCKT].flags |= ULOGD_RETF_VALID;
-ret[ULOG_KEY_RAW_PCKTLEN].u.value.ui32 = pkt-&gt;data_len;
-ret[ULOG_KEY_RAW_PCKTLEN].flags |= ULOGD_RETF_VALID;
-ret[ULOG_KEY_RAW_PCKTCOUNT].u.value.ui32 = 1;
-ret[ULOG_KEY_RAW_PCKTCOUNT].flags |= ULOGD_RETF_VALID;
+okey_set_ptr(&amp;ret[ULOG_KEY_RAW_PCKT], pkt-&gt;payload);
+okey_set_u32(&amp;ret[ULOG_KEY_RAW_PCKTLEN], pkt-&gt;data_len);
+okey_set_u32(&amp;ret[ULOG_KEY_RAW_PCKTCOUNT], 1);
 
-ret[ULOG_KEY_OOB_PREFIX].u.value.ptr = pkt-&gt;prefix;
-ret[ULOG_KEY_OOB_PREFIX].flags |= ULOGD_RETF_VALID;
+okey_set_ptr(&amp;ret[ULOG_KEY_OOB_PREFIX], pkt-&gt;prefix);
 
 /* god knows why timestamp_usec contains crap if timestamp_sec == 0
  * if (pkt-&gt;timestamp_sec || pkt-&gt;timestamp_usec) { */
 if (pkt-&gt;timestamp_sec) {
-ret[ULOG_KEY_OOB_TIME_SEC].u.value.ui32 = pkt-&gt;timestamp_sec;
-ret[ULOG_KEY_OOB_TIME_SEC].flags |= ULOGD_RETF_VALID;
-ret[ULOG_KEY_OOB_TIME_USEC].u.value.ui32 = pkt-&gt;timestamp_usec;
-ret[ULOG_KEY_OOB_TIME_USEC].flags |= ULOGD_RETF_VALID;
+okey_set_u32(&amp;ret[ULOG_KEY_OOB_TIME_SEC], pkt-&gt;timestamp_sec);
+okey_set_u32(&amp;ret[ULOG_KEY_OOB_TIME_USEC], pkt-&gt;timestamp_usec);
 } else {
 ret[ULOG_KEY_OOB_TIME_SEC].flags &amp;= ~ULOGD_RETF_VALID;
 ret[ULOG_KEY_OOB_TIME_USEC].flags &amp;= ~ULOGD_RETF_VALID;
 }
 
-ret[ULOG_KEY_OOB_MARK].u.value.ui32 = pkt-&gt;mark;
-ret[ULOG_KEY_OOB_MARK].flags |= ULOGD_RETF_VALID;
-ret[ULOG_KEY_OOB_IN].u.value.ptr = pkt-&gt;indev_name;
-ret[ULOG_KEY_OOB_IN].flags |= ULOGD_RETF_VALID;
-ret[ULOG_KEY_OOB_OUT].u.value.ptr = pkt-&gt;outdev_name;
-ret[ULOG_KEY_OOB_OUT].flags |= ULOGD_RETF_VALID;
+okey_set_u32(&amp;ret[ULOG_KEY_OOB_MARK], pkt-&gt;mark);
+okey_set_ptr(&amp;ret[ULOG_KEY_OOB_IN], pkt-&gt;indev_name);
+okey_set_ptr(&amp;ret[ULOG_KEY_OOB_OUT], pkt-&gt;outdev_name);
 
-ret[ULOG_KEY_OOB_HOOK].u.value.ui8 = pkt-&gt;hook;
-ret[ULOG_KEY_OOB_HOOK].flags |= ULOGD_RETF_VALID;
+okey_set_u8(&amp;ret[ULOG_KEY_OOB_HOOK], pkt-&gt;hook);
 
 /* ULOG is IPv4 only */
-ret[ULOG_KEY_OOB_FAMILY].u.value.ui8 = AF_INET;
-ret[ULOG_KEY_OOB_FAMILY].flags |= ULOGD_RETF_VALID;
+okey_set_u8(&amp;ret[ULOG_KEY_OOB_FAMILY], AF_INET);
 /* Undef in ULOG but necessary */
-ret[ULOG_KEY_OOB_PROTOCOL].u.value.ui16 = 0;
-ret[ULOG_KEY_OOB_PROTOCOL].flags |= ULOGD_RETF_VALID;
+okey_set_u16(&amp;ret[ULOG_KEY_OOB_PROTOCOL], 0);
 
 ulogd_propagate_results(ip);
 return 0;
diff --git a/output/pcap/ulogd_output_PCAP.c b/output/pcap/ulogd_output_PCAP.c
index ce4393c..09120a1 100644
--- a/output/pcap/ulogd_output_PCAP.c
+++ b/output/pcap/ulogd_output_PCAP.c
&lt; at &gt;&lt; at &gt; -126,7 +126,6 &lt; at &gt;&lt; at &gt; static struct ulogd_key pcap_keys[INTR_IDS] = {
 { .name = "oob.time.usec" },
 };
 
-#define GET_VALUE(res, x)(res[x].u.source-&gt;u.value)
 #define GET_FLAGS(res, x)(res[x].u.source-&gt;flags)
 
 static int interp_pcap(struct ulogd_pluginstance *upi)
&lt; at &gt;&lt; at &gt; -135,13 +134,13 &lt; at &gt;&lt; at &gt; static int interp_pcap(struct ulogd_pluginstance *upi)
 struct ulogd_key *res = upi-&gt;input.keys;
 struct pcap_sf_pkthdr pchdr;
 
-pchdr.caplen = GET_VALUE(res, 2).ui32;
-pchdr.len = GET_VALUE(res, 2).ui32;
+pchdr.caplen = ikey_get_u32(&amp;res[2]);
+pchdr.len = ikey_get_u32(&amp;res[2]);
 
 if (GET_FLAGS(res, 3) &amp; ULOGD_RETF_VALID
     &amp;&amp; GET_FLAGS(res, 4) &amp; ULOGD_RETF_VALID) {
-pchdr.ts.tv_sec = GET_VALUE(res, 3).ui32;
-pchdr.ts.tv_usec = GET_VALUE(res, 4).ui32;
+pchdr.ts.tv_sec = ikey_get_u32(&amp;res[3]);
+pchdr.ts.tv_usec = ikey_get_u32(&amp;res[4]);
 } else {
 /* use current system time */
 struct timeval tv;
&lt; at &gt;&lt; at &gt; -156,7 +155,7 &lt; at &gt;&lt; at &gt; static int interp_pcap(struct ulogd_pluginstance *upi)
   strerror(errno));
 return ULOGD_IRET_ERR;
 }
-if (fwrite(GET_VALUE(res, 0).ptr, pchdr.caplen, 1, pi-&gt;of) != 1) {
+if (fwrite(ikey_get_ptr(&amp;res[0]), pchdr.caplen, 1, pi-&gt;of) != 1) {
 ulogd_log(ULOGD_ERROR, "Error during write: %s\n",
   strerror(errno));
 return ULOGD_IRET_ERR;
diff --git a/output/ulogd_output_NACCT.c b/output/ulogd_output_NACCT.c
index 0ab2be4..f5296e8 100644
--- a/output/ulogd_output_NACCT.c
+++ b/output/ulogd_output_NACCT.c
&lt; at &gt;&lt; at &gt; -125,28 +125,28 &lt; at &gt;&lt; at &gt; nacct_interp(struct ulogd_pluginstance *pi)
 
 /* try to be as close to nacct as possible.  Instead of nacct's
    'timestamp' value use 'flow.end.sec' */
-if (GET_VALUE(inp, KEY_IP_PROTO).ui8 == IPPROTO_ICMP) {
+if (ikey_get_u8(&amp;inp[KEY_IP_PROTO]) == IPPROTO_ICMP) {
 snprintf(buf, sizeof(buf),
  "%u\t%u\t%s\t%u\t%s\t%u\t%u\t%u",
- GET_VALUE(inp, KEY_FLOW_END).ui32,
- GET_VALUE(inp, KEY_IP_PROTO).ui8,
- (char *) GET_VALUE(inp, KEY_IP_SADDR).ptr,
- GET_VALUE(inp, KEY_ICMP_TYPE).ui8,
- (char *) GET_VALUE(inp, KEY_IP_DADDR).ptr,
- GET_VALUE(inp, KEY_ICMP_CODE).ui8,
- GET_VALUE(inp, KEY_RAW_PKTCNT).ui32,
- GET_VALUE(inp, KEY_RAW_PKTLEN).ui32);
+ ikey_get_u32(&amp;inp[KEY_FLOW_END]),
+ ikey_get_u8(&amp;inp[KEY_IP_PROTO]),
+ (char *) ikey_get_ptr(&amp;inp[KEY_IP_SADDR]),
+ ikey_get_u8(&amp;inp[KEY_ICMP_TYPE]),
+ (char *) ikey_get_ptr(&amp;inp[KEY_IP_DADDR]),
+ ikey_get_u8(&amp;inp[KEY_ICMP_CODE]),
+ ikey_get_u32(&amp;inp[KEY_RAW_PKTCNT]),
+ ikey_get_u32(&amp;inp[KEY_RAW_PKTLEN]));
 } else {
 snprintf(buf, sizeof(buf),
  "%u\t%u\t%s\t%u\t%s\t%u\t%u\t%u",
- GET_VALUE(inp, KEY_FLOW_END).ui32,
- GET_VALUE(inp, KEY_IP_PROTO).ui8,
- (char *) GET_VALUE(inp, KEY_IP_SADDR).ptr,
- GET_VALUE(inp, KEY_L4_SPORT).ui16,
- (char *) GET_VALUE(inp, KEY_IP_DADDR).ptr,
- GET_VALUE(inp, KEY_L4_DPORT).ui16,
- GET_VALUE(inp, KEY_RAW_PKTCNT).ui32,
- GET_VALUE(inp, KEY_RAW_PKTLEN).ui32);
+ ikey_get_u32(&amp;inp[KEY_FLOW_END]),
+ ikey_get_u8(&amp;inp[KEY_IP_PROTO]),
+ (char *) ikey_get_ptr(&amp;inp[KEY_IP_SADDR]),
+ ikey_get_u16(&amp;inp[KEY_L4_SPORT]),
+ (char *) ikey_get_ptr(&amp;inp[KEY_IP_DADDR]),
+ ikey_get_u16(&amp;inp[KEY_L4_DPORT]),
+ ikey_get_u32(&amp;inp[KEY_RAW_PKTCNT]),
+ ikey_get_u32(&amp;inp[KEY_RAW_PKTLEN]));
 }
 
 fprintf(priv-&gt;of, "%s\n", buf);
diff --git a/util/printflow.c b/util/printflow.c
index bb3c2c4..7743a6a 100644
--- a/util/printflow.c
+++ b/util/printflow.c
&lt; at &gt;&lt; at &gt; -139,14 +139,14 &lt; at &gt;&lt; at &gt; int printflow_keys_num = sizeof(printflow_keys)/sizeof(*printflow_keys);
 
 #define pp_print(buf_cur, label, res, x, type) \
 if (pp_is_valid(res, x)) \
-buf_cur += sprintf(buf_cur, label"=%u ", GET_VALUE(res, x).type);
+buf_cur += sprintf(buf_cur, label"=%u ", ikey_get_##type(&amp;res[x]));
 
 int printflow_print(struct ulogd_key *res, char *buf)
 {
 char *buf_cur = buf;
 
 if (pp_is_valid(res, PRINTFLOW_EVENT_TYPE)) {
-switch (GET_VALUE(res, PRINTFLOW_EVENT_TYPE).ui32) {
+switch (ikey_get_u32(&amp;res[PRINTFLOW_EVENT_TYPE])) {
 case 1:
 buf_cur += sprintf(buf_cur, "[NEW] ");
 break;
&lt; at &gt;&lt; at &gt; -164,33 +164,33 &lt; at &gt;&lt; at &gt; int printflow_print(struct ulogd_key *res, char *buf)
 if (pp_is_valid(res, PRINTFLOW_ORIG_IP_SADDR))
 buf_cur += sprintf(buf_cur,
    "SRC=%s ", 
-   (char *) GET_VALUE(res, PRINTFLOW_ORIG_IP_SADDR).ptr);
+   (char *) ikey_get_ptr(&amp;res[PRINTFLOW_ORIG_IP_SADDR]));
 
 if (pp_is_valid(res, PRINTFLOW_ORIG_IP_DADDR))
 buf_cur += sprintf(buf_cur,
    "DST=%s ",
-   (char *) GET_VALUE(res, PRINTFLOW_ORIG_IP_DADDR).ptr);
+   (char *) ikey_get_ptr(&amp;res[PRINTFLOW_ORIG_IP_DADDR]));
 
 if (!pp_is_valid(res, PRINTFLOW_ORIG_IP_PROTOCOL))
 goto orig_out;
 
-switch (GET_VALUE(res, PRINTFLOW_ORIG_IP_PROTOCOL).ui8) {
+switch (ikey_get_u8(&amp;res[PRINTFLOW_ORIG_IP_PROTOCOL])) {
 case IPPROTO_TCP:
 buf_cur += sprintf(buf_cur, "PROTO=TCP ");
-pp_print(buf_cur, "SPT", res, PRINTFLOW_ORIG_L4_SPORT, ui16);
-pp_print(buf_cur, "DPT", res, PRINTFLOW_ORIG_L4_DPORT, ui16);
+pp_print(buf_cur, "SPT", res, PRINTFLOW_ORIG_L4_SPORT, u16);
+pp_print(buf_cur, "DPT", res, PRINTFLOW_ORIG_L4_DPORT, u16);
 break;
 
 case IPPROTO_UDP:
 buf_cur += sprintf(buf_cur, "PROTO=UDP ");
-pp_print(buf_cur, "SPT", res, PRINTFLOW_ORIG_L4_SPORT, ui16);
-pp_print(buf_cur, "DPT", res, PRINTFLOW_ORIG_L4_DPORT, ui16);
+pp_print(buf_cur, "SPT", res, PRINTFLOW_ORIG_L4_SPORT, u16);
+pp_print(buf_cur, "DPT", res, PRINTFLOW_ORIG_L4_DPORT, u16);
 break;
 
 case IPPROTO_ICMP:
 buf_cur += sprintf(buf_cur, "PROTO=ICMP ");
-pp_print(buf_cur, "TYPE", res, PRINTFLOW_ICMP_CODE, ui8);
-pp_print(buf_cur, "CODE", res, PRINTFLOW_ICMP_TYPE, ui8);
+pp_print(buf_cur, "TYPE", res, PRINTFLOW_ICMP_CODE, u8);
+pp_print(buf_cur, "CODE", res, PRINTFLOW_ICMP_TYPE, u8);
 break;
 
 case IPPROTO_ESP:
&lt; at &gt;&lt; at &gt; -202,46 +202,46 &lt; at &gt;&lt; at &gt; int printflow_print(struct ulogd_key *res, char *buf)
 break;
 
 default:
-pp_print(buf_cur, "PROTO", res, PRINTFLOW_ORIG_IP_PROTOCOL, ui8);
+pp_print(buf_cur, "PROTO", res, PRINTFLOW_ORIG_IP_PROTOCOL, u8);
 break;
 }
 
 orig_out:
-pp_print(buf_cur, "PKTS", res, PRINTFLOW_ORIG_RAW_PKTCOUNT, ui32);
-pp_print(buf_cur, "BYTES", res, PRINTFLOW_ORIG_RAW_PKTLEN, ui32);
+pp_print(buf_cur, "PKTS", res, PRINTFLOW_ORIG_RAW_PKTCOUNT, u32);
+pp_print(buf_cur, "BYTES", res, PRINTFLOW_ORIG_RAW_PKTLEN, u32);
 
 buf_cur += sprintf(buf_cur, ", REPLY: ");
 
 if (pp_is_valid(res, PRINTFLOW_REPLY_IP_SADDR))
 buf_cur += sprintf(buf_cur,
    "SRC=%s ",
-   (char *) GET_VALUE(res,PRINTFLOW_REPLY_IP_SADDR).ptr);
+   (char *) ikey_get_ptr(&amp;res[PRINTFLOW_REPLY_IP_SADDR]));
 
 if (pp_is_valid(res, PRINTFLOW_REPLY_IP_DADDR))
 buf_cur += sprintf(buf_cur,
    "DST=%s ",
-   (char *) GET_VALUE(res,PRINTFLOW_REPLY_IP_DADDR).ptr);
+   (char *) ikey_get_ptr(&amp;res[PRINTFLOW_REPLY_IP_DADDR]));
 
 if (!pp_is_valid(res, PRINTFLOW_REPLY_IP_PROTOCOL))
 goto reply_out;
 
-switch (GET_VALUE(res, PRINTFLOW_REPLY_IP_PROTOCOL).ui8) {
+switch (ikey_get_u8(&amp;res[PRINTFLOW_REPLY_IP_PROTOCOL])) {
 case IPPROTO_TCP:
 buf_cur += sprintf(buf_cur, "PROTO=TCP ");
-pp_print(buf_cur, "SPT", res, PRINTFLOW_REPLY_L4_SPORT, ui16);
-pp_print(buf_cur, "DPT", res, PRINTFLOW_REPLY_L4_DPORT, ui16);
+pp_print(buf_cur, "SPT", res, PRINTFLOW_REPLY_L4_SPORT, u16);
+pp_print(buf_cur, "DPT", res, PRINTFLOW_REPLY_L4_DPORT, u16);
 break;
 
 case IPPROTO_UDP:
 buf_cur += sprintf(buf_cur, "PROTO=UDP ");
-pp_print(buf_cur, "SPT", res, PRINTFLOW_REPLY_L4_SPORT, ui16);
-pp_print(buf_cur, "DPT", res, PRINTFLOW_REPLY_L4_DPORT, ui16);
+pp_print(buf_cur, "SPT", res, PRINTFLOW_REPLY_L4_SPORT, u16);
+pp_print(buf_cur, "DPT", res, PRINTFLOW_REPLY_L4_DPORT, u16);
 break;
 
 case IPPROTO_ICMP:
 buf_cur += sprintf(buf_cur, "PROTO=ICMP ");
-pp_print(buf_cur, "TYPE", res, PRINTFLOW_ICMP_CODE, ui8);
-pp_print(buf_cur, "CODE", res, PRINTFLOW_ICMP_TYPE, ui8);
+pp_print(buf_cur, "TYPE", res, PRINTFLOW_ICMP_CODE, u8);
+pp_print(buf_cur, "CODE", res, PRINTFLOW_ICMP_TYPE, u8);
 break;
 
 case IPPROTO_ESP:
&lt; at &gt;&lt; at &gt; -253,13 +253,13 &lt; at &gt;&lt; at &gt; orig_out:
 break;
 
 default:
-pp_print(buf_cur, "PROTO", res, PRINTFLOW_REPLY_IP_PROTOCOL, ui8);
+pp_print(buf_cur, "PROTO", res, PRINTFLOW_REPLY_IP_PROTOCOL, u8);
 break;
 }
 
 reply_out:
-pp_print(buf_cur, "PKTS", res, PRINTFLOW_REPLY_RAW_PKTCOUNT, ui32);
-pp_print(buf_cur, "BYTES", res, PRINTFLOW_REPLY_RAW_PKTLEN, ui32);
+pp_print(buf_cur, "PKTS", res, PRINTFLOW_REPLY_RAW_PKTCOUNT, u32);
+pp_print(buf_cur, "BYTES", res, PRINTFLOW_REPLY_RAW_PKTLEN, u32);
 
 strcat(buf_cur, "\n");
 return 0;
diff --git a/util/printpkt.c b/util/printpkt.c
index 29c2ea4..2292377 100644
--- a/util/printpkt.c
+++ b/util/printpkt.c
&lt; at &gt;&lt; at &gt; -119,38 +119,38 &lt; at &gt;&lt; at &gt; static int printpkt_proto(struct ulogd_key *res, char *buf, int protocol)
 }
 
 buf_cur += sprintf(buf_cur, "SPT=%u DPT=%u ",
-   GET_VALUE(res, KEY_TCP_SPORT).ui16,
-   GET_VALUE(res, KEY_TCP_DPORT).ui16);
+   ikey_get_u16(&amp;res[KEY_TCP_SPORT]),
+   ikey_get_u16(&amp;res[KEY_TCP_DPORT]));
 /* FIXME: config */
-buf_cur += sprintf(buf_cur, "SEQ=%u ACK=%u ", 
-   GET_VALUE(res, KEY_TCP_SEQ).ui32,
-   GET_VALUE(res, KEY_TCP_ACKSEQ).ui32);
+buf_cur += sprintf(buf_cur, "SEQ=%u ACK=%u ",
+   ikey_get_u32(&amp;res[KEY_TCP_SEQ]),
+   ikey_get_u32(&amp;res[KEY_TCP_ACKSEQ]));
 
 buf_cur += sprintf(buf_cur, "WINDOW=%u ",
-   GET_VALUE(res, KEY_TCP_WINDOW).ui16);
+   ikey_get_u16(&amp;res[KEY_TCP_WINDOW]));
 
 //buf_cur += sprintf(buf_cur, "RES=0x%02x ", 
 
-if (GET_VALUE(res, KEY_TCP_URG).b)
+if (ikey_get_u8(&amp;res[KEY_TCP_URG]))
 buf_cur += sprintf(buf_cur, "URG ");
 
-if (GET_VALUE(res, KEY_TCP_ACK).b)
+if (ikey_get_u8(&amp;res[KEY_TCP_ACK]))
 buf_cur += sprintf(buf_cur, "ACK ");
 
-if (GET_VALUE(res, KEY_TCP_PSH).b)
+if (ikey_get_u8(&amp;res[KEY_TCP_PSH]))
 buf_cur += sprintf(buf_cur, "PSH ");
 
-if (GET_VALUE(res, KEY_TCP_RST).b)
+if (ikey_get_u8(&amp;res[KEY_TCP_RST]))
 buf_cur += sprintf(buf_cur, "RST ");
 
-if (GET_VALUE(res, KEY_TCP_SYN).b)
+if (ikey_get_u8(&amp;res[KEY_TCP_SYN]))
 buf_cur += sprintf(buf_cur, "SYN ");
 
-if (GET_VALUE(res, KEY_TCP_FIN).b)
+if (ikey_get_u8(&amp;res[KEY_TCP_FIN]))
 buf_cur += sprintf(buf_cur, "FIN ");
 
 buf_cur += sprintf(buf_cur, "URGP=%u ",
-   GET_VALUE(res, KEY_TCP_URGP).ui16);
+   ikey_get_u16(&amp;res[KEY_TCP_URGP]));
 
 break;
 
&lt; at &gt;&lt; at &gt; -163,14 +163,14 &lt; at &gt;&lt; at &gt; static int printpkt_proto(struct ulogd_key *res, char *buf, int protocol)
 }
 
 buf_cur += sprintf(buf_cur, "SPT=%u DPT=%u LEN=%u ", 
-   GET_VALUE(res, KEY_UDP_SPORT).ui16,
-   GET_VALUE(res, KEY_UDP_DPORT).ui16, 
-   GET_VALUE(res, KEY_UDP_LEN).ui16);
+   ikey_get_u16(&amp;res[KEY_UDP_SPORT]),
+   ikey_get_u16(&amp;res[KEY_UDP_DPORT]), 
+   ikey_get_u16(&amp;res[KEY_UDP_LEN]));
 break;
 case IPPROTO_ESP:
 case IPPROTO_AH:
 buf_cur += sprintf(buf_cur, "PROTO=%s ",
-   GET_VALUE(res, KEY_IP_PROTOCOL).ui8 == IPPROTO_ESP ? "ESP" : "AH");
+   ikey_get_u8(&amp;res[KEY_IP_PROTOCOL]) == IPPROTO_ESP ? "ESP" : "AH");
 
 if (!pp_is_valid(res, KEY_AHESP_SPI)) {
 buf_cur += sprintf(buf_cur, "INCOMPLETE");
&lt; at &gt;&lt; at &gt; -178,7 +178,7 &lt; at &gt;&lt; at &gt; static int printpkt_proto(struct ulogd_key *res, char *buf, int protocol)
 }
 
 buf_cur += sprintf(buf_cur, "SPI=0x%x ",
-   GET_VALUE(res, KEY_AHESP_SPI).ui32);
+   ikey_get_u32(&amp;res[KEY_AHESP_SPI]));
 break;
 }
 
&lt; at &gt;&lt; at &gt; -189,43 +189,44 &lt; at &gt;&lt; at &gt; static int printpkt_ipv4(struct ulogd_key *res, char *buf)
 {
 char *buf_cur = buf;
 char tmp[INET_ADDRSTRLEN];
+u_int32_t paddr;
 
 if (pp_is_valid(res, KEY_IP_SADDR))
 buf_cur += sprintf(buf_cur, "SRC=%s ",
-   (char *) GET_VALUE(res, KEY_IP_SADDR).ptr);
+   (char *) ikey_get_ptr(&amp;res[KEY_IP_SADDR]));
 
 if (pp_is_valid(res, KEY_IP_DADDR))
 buf_cur += sprintf(buf_cur, "DST=%s ",
-   (char *) GET_VALUE(res, KEY_IP_DADDR).ptr);
+   (char *) ikey_get_ptr(&amp;res[KEY_IP_DADDR]));
 
 /* FIXME: add pp_is_valid calls to remainder of file */
 buf_cur += sprintf(buf_cur,"LEN=%u TOS=%02X PREC=0x%02X TTL=%u ID=%u ", 
-   GET_VALUE(res, KEY_IP_TOTLEN).ui16,
-   GET_VALUE(res, KEY_IP_TOS).ui8 &amp; IPTOS_TOS_MASK, 
-   GET_VALUE(res, KEY_IP_TOS).ui8 &amp; IPTOS_PREC_MASK,
-   GET_VALUE(res, KEY_IP_TTL).ui8,
-   GET_VALUE(res, KEY_IP_ID).ui16);
+   ikey_get_u16(&amp;res[KEY_IP_TOTLEN]),
+   ikey_get_u8(&amp;res[KEY_IP_TOS]) &amp; IPTOS_TOS_MASK, 
+   ikey_get_u8(&amp;res[KEY_IP_TOS]) &amp; IPTOS_PREC_MASK,
+   ikey_get_u8(&amp;res[KEY_IP_TTL]),
+   ikey_get_u16(&amp;res[KEY_IP_ID]));
 
-if (GET_VALUE(res, KEY_IP_FRAGOFF).ui16 &amp; IP_RF) 
+if (ikey_get_u16(&amp;res[KEY_IP_FRAGOFF]) &amp; IP_RF) 
 buf_cur += sprintf(buf_cur, "CE ");
 
-if (GET_VALUE(res, KEY_IP_FRAGOFF).ui16 &amp; IP_DF)
+if (ikey_get_u16(&amp;res[KEY_IP_FRAGOFF]) &amp; IP_DF)
 buf_cur += sprintf(buf_cur, "DF ");
 
-if (GET_VALUE(res, KEY_IP_FRAGOFF).ui16 &amp; IP_MF)
+if (ikey_get_u16(&amp;res[KEY_IP_FRAGOFF]) &amp; IP_MF)
 buf_cur += sprintf(buf_cur, "MF ");
 
-if (GET_VALUE(res, KEY_IP_FRAGOFF).ui16 &amp; IP_OFFMASK)
+if (ikey_get_u16(&amp;res[KEY_IP_FRAGOFF]) &amp; IP_OFFMASK)
 buf_cur += sprintf(buf_cur, "FRAG:%u ", 
-   GET_VALUE(res, KEY_IP_FRAGOFF).ui16 &amp; IP_OFFMASK);
+   ikey_get_u16(&amp;res[KEY_IP_FRAGOFF]) &amp; IP_OFFMASK);
 
-switch (GET_VALUE(res, KEY_IP_PROTOCOL).ui8) {
+switch (ikey_get_u8(&amp;res[KEY_IP_PROTOCOL])) {
 case IPPROTO_TCP:
 case IPPROTO_UDP:
 case IPPROTO_ESP:
 case IPPROTO_AH:
 buf_cur += printpkt_proto(res, buf_cur,
-  GET_VALUE(res, KEY_IP_PROTOCOL).ui8);
+  ikey_get_u8(&amp;res[KEY_IP_PROTOCOL]));
 break;
 
 case IPPROTO_ICMP:
&lt; at &gt;&lt; at &gt; -237,36 +238,37 &lt; at &gt;&lt; at &gt; static int printpkt_ipv4(struct ulogd_key *res, char *buf)
 }
 
 buf_cur += sprintf(buf_cur, "TYPE=%u CODE=%u ",
-   GET_VALUE(res, KEY_ICMP_TYPE).ui8,
-   GET_VALUE(res, KEY_ICMP_CODE).ui8);
+   ikey_get_u8(&amp;res[KEY_ICMP_TYPE]),
+   ikey_get_u8(&amp;res[KEY_ICMP_CODE]));
 
-switch (GET_VALUE(res, KEY_ICMP_TYPE).ui8) {
+switch (ikey_get_u8(&amp;res[KEY_ICMP_CODE])) {
 case ICMP_ECHO:
 case ICMP_ECHOREPLY:
 buf_cur += sprintf(buf_cur, "ID=%u SEQ=%u ", 
-   GET_VALUE(res, KEY_ICMP_ECHOID).ui16,
-   GET_VALUE(res, KEY_ICMP_ECHOSEQ).ui16);
+   ikey_get_u16(&amp;res[KEY_ICMP_ECHOID]),
+   ikey_get_u16(&amp;res[KEY_ICMP_ECHOSEQ]));
 break;
 case ICMP_PARAMETERPROB:
 buf_cur += sprintf(buf_cur, "PARAMETER=%u ",
-   GET_VALUE(res, KEY_ICMP_GATEWAY).ui32 &gt;&gt; 24);
+   ikey_get_u32(&amp;res[KEY_ICMP_GATEWAY]) &gt;&gt; 24);
 break;
 case ICMP_REDIRECT:
+paddr = ikey_get_u32(&amp;res[KEY_ICMP_GATEWAY]),
 buf_cur += sprintf(buf_cur, "GATEWAY=%s ",
    inet_ntop(AF_INET,
-        &amp;GET_VALUE(res, KEY_ICMP_GATEWAY).ui32,
+     &amp;paddr,
      tmp, sizeof(tmp)));
 break;
 case ICMP_DEST_UNREACH:
-if (GET_VALUE(res, KEY_ICMP_CODE).ui8 == ICMP_FRAG_NEEDED)
+if (ikey_get_u8(&amp;res[KEY_ICMP_CODE]) == ICMP_FRAG_NEEDED)
 buf_cur += sprintf(buf_cur, "MTU=%u ", 
-   GET_VALUE(res, KEY_ICMP_FRAGMTU).ui16);
+   ikey_get_u16(&amp;res[KEY_ICMP_FRAGMTU]));
 break;
 }
 break;
 default:
 buf_cur += sprintf(buf_cur, "PROTO=%u ",
-   GET_VALUE(res, KEY_IP_PROTOCOL).ui8);
+   ikey_get_u8(&amp;res[KEY_IP_PROTOCOL]));
 }
 
 return buf_cur - buf;
&lt; at &gt;&lt; at &gt; -278,41 +280,41 &lt; at &gt;&lt; at &gt; static int printpkt_ipv6(struct ulogd_key *res, char *buf)
 
 if (pp_is_valid(res, KEY_IP_SADDR))
 buf_cur += sprintf(buf_cur, "SRC=%s ",
-   (char *) GET_VALUE(res, KEY_IP_SADDR).ptr);
+   (char *) ikey_get_ptr(&amp;res[KEY_IP_SADDR]));
 
 if (pp_is_valid(res, KEY_IP_DADDR))
 buf_cur += sprintf(buf_cur, "DST=%s ",
-   (char *) GET_VALUE(res, KEY_IP_DADDR).ptr);
+   (char *) ikey_get_ptr(&amp;res[KEY_IP_DADDR]));
 
 if (pp_is_valid(res, KEY_IP6_PAYLOAD_LEN))
 buf_cur += sprintf(buf_cur, "LEN=%Zu ",
-   GET_VALUE(res, KEY_IP6_PAYLOAD_LEN).ui16 +
+   ikey_get_u16(&amp;res[KEY_IP6_PAYLOAD_LEN]) +
    sizeof(struct ip6_hdr));
 
 if (pp_is_valid(res, KEY_IP6_PRIORITY))
 buf_cur += sprintf(buf_cur, "TC=%u ",
-   GET_VALUE(res, KEY_IP6_PRIORITY).ui8);
+   ikey_get_u8(&amp;res[KEY_IP6_PRIORITY]));
 
 if (pp_is_valid(res, KEY_IP6_HOPLIMIT))
 buf_cur += sprintf(buf_cur, "HOPLIMIT=%u ",
-   GET_VALUE(res, KEY_IP6_HOPLIMIT).ui8);
+   ikey_get_u8(&amp;res[KEY_IP6_HOPLIMIT]));
 
 if (pp_is_valid(res, KEY_IP6_FLOWLABEL))
 buf_cur += sprintf(buf_cur, "FLOWLBL=%u ",
-   GET_VALUE(res, KEY_IP6_FLOWLABEL).ui32);
+   ikey_get_u32(&amp;res[KEY_IP6_FLOWLABEL]));
 
 if (pp_is_valid(res, KEY_IP6_FRAG_OFF) &amp;&amp; pp_is_valid(res, KEY_IP6_FRAG_ID))
 buf_cur += sprintf(buf_cur, "FRAG: %u ID: %08x ",
-   GET_VALUE(res, KEY_IP6_FRAG_OFF).ui16,
-   GET_VALUE(res, KEY_IP6_FRAG_ID).ui32);
+   ikey_get_u16(&amp;res[KEY_IP6_FRAG_OFF]),
+   ikey_get_u32(&amp;res[KEY_IP6_FRAG_ID]));
 
-switch (GET_VALUE(res, KEY_IP6_NEXTHDR).ui8) {
+switch (ikey_get_u8(&amp;res[KEY_IP6_NEXTHDR])) {
 case IPPROTO_TCP:
 case IPPROTO_UDP:
 case IPPROTO_ESP:
 case IPPROTO_AH:
 buf_cur += printpkt_proto(res, buf_cur,
-  GET_VALUE(res, KEY_IP6_NEXTHDR).ui8);
+  ikey_get_u8(&amp;res[KEY_IP6_NEXTHDR]));
 break;
 case IPPROTO_ICMPV6:
 buf_cur += sprintf(buf_cur, "PROTO=ICMPv6 ");
&lt; at &gt;&lt; at &gt; -329,15 +331,15 &lt; at &gt;&lt; at &gt; static int printpkt_ipv6(struct ulogd_key *res, char *buf)
 }
 
 buf_cur += sprintf(buf_cur, "TYPE=%u CODE=%u ",
-   GET_VALUE(res, KEY_ICMPV6_TYPE).ui8,
-   GET_VALUE(res, KEY_ICMPV6_CODE).ui8);
+   ikey_get_u8(&amp;res[KEY_ICMPV6_TYPE]),
+   ikey_get_u8(&amp;res[KEY_ICMPV6_CODE]));
 
-switch (GET_VALUE(res, KEY_ICMPV6_TYPE).ui8) {
+switch (ikey_get_u8(&amp;res[KEY_ICMPV6_TYPE])) {
 case ICMP6_ECHO_REQUEST:
 case ICMP6_ECHO_REPLY:
 buf_cur += sprintf(buf_cur, "ID=%u SEQ=%u ", 
-   GET_VALUE(res, KEY_ICMPV6_ECHOID).ui16,
-   GET_VALUE(res, KEY_ICMPV6_ECHOSEQ).ui16);
+   ikey_get_u16(&amp;res[KEY_ICMPV6_ECHOID]),
+   ikey_get_u16(&amp;res[KEY_ICMPV6_ECHOSEQ]));
 break;
 }
 break;
&lt; at &gt;&lt; at &gt; -354,16 +356,16 &lt; at &gt;&lt; at &gt; int printpkt_arp(struct ulogd_key *res, char *buf)
 
 if (pp_is_valid(res, KEY_ARP_SPA))
 buf_cur += sprintf(buf_cur, "SRC=%s ",
-   (char *) GET_VALUE(res, KEY_ARP_SPA).ptr);
+   (char *) ikey_get_ptr(&amp;res[KEY_ARP_SPA]));
 
 if (pp_is_valid(res, KEY_ARP_TPA))
 buf_cur += sprintf(buf_cur, "DST=%s ",
-   (char *) GET_VALUE(res, KEY_ARP_TPA).ptr);
+   (char *) ikey_get_ptr(&amp;res[KEY_ARP_TPA]));
 
 buf_cur += sprintf(buf_cur, "PROTO=ARP ");
 
 if (pp_is_valid(res, KEY_ARP_OPCODE)) {
-code = GET_VALUE(res, KEY_ARP_OPCODE).ui16;
+code = ikey_get_u16(&amp;res[KEY_ARP_OPCODE]);
 switch (code) {
 case ARPOP_REQUEST:
 buf_cur += sprintf(buf_cur, "REQUEST ");
&lt; at &gt;&lt; at &gt; -379,7 +381,7 &lt; at &gt;&lt; at &gt; int printpkt_arp(struct ulogd_key *res, char *buf)
 }
 
 if (pp_is_valid(res, KEY_ARP_SHA) &amp;&amp; (code == ARPOP_REPLY)) {
-mac = GET_VALUE(res, KEY_ARP_SHA).ptr;
+mac = ikey_get_ptr(&amp;res[KEY_ARP_SHA]);
 buf_cur += sprintf(buf_cur, "REPLY_MAC="
    "%02x:%02x:%02x:%02x:%02x:%02x ",
    mac[0], mac[1], mac[2],
&lt; at &gt;&lt; at &gt; -395,7 +397,7 &lt; at &gt;&lt; at &gt; int printpkt_bridge(struct ulogd_key *res, char *buf)
 {
 char *buf_cur = buf;
 
-switch (GET_VALUE(res, KEY_OOB_PROTOCOL).ui16) {
+switch (ikey_get_u16(&amp;res[KEY_OOB_PROTOCOL])) {
 case ETH_P_IP:
 buf_cur += printpkt_ipv4(res, buf_cur);
 break;
&lt; at &gt;&lt; at &gt; -407,7 +409,7 &lt; at &gt;&lt; at &gt; int printpkt_bridge(struct ulogd_key *res, char *buf)
 break;
 default:
 buf_cur += sprintf(buf_cur, "PROTO=%u ",
-   GET_VALUE(res, KEY_OOB_PROTOCOL).ui16);
+   ikey_get_u16(&amp;res[KEY_OOB_PROTOCOL]));
 }
 
 return buf_cur - buf;
&lt; at &gt;&lt; at &gt; -419,17 +421,17 &lt; at &gt;&lt; at &gt; int printpkt_print(struct ulogd_key *res, char *buf)
 
 if (pp_is_valid(res, KEY_OOB_PREFIX))
 buf_cur += sprintf(buf_cur, "%s ",
-   (char *) GET_VALUE(res, KEY_OOB_PREFIX).ptr);
+   (char *) ikey_get_ptr(&amp;res[KEY_OOB_PREFIX]));
 
 if (pp_is_valid(res, KEY_OOB_IN) &amp;&amp; pp_is_valid(res, KEY_OOB_OUT))
 buf_cur += sprintf(buf_cur, "IN=%s OUT=%s ", 
-   (char *) GET_VALUE(res, KEY_OOB_IN).ptr, 
-   (char *) GET_VALUE(res, KEY_OOB_OUT).ptr);
+   (char *) ikey_get_ptr(&amp;res[KEY_OOB_IN]), 
+   (char *) ikey_get_ptr(&amp;res[KEY_OOB_OUT]));
 
 /* FIXME: configurable */
 if (pp_is_valid(res, KEY_RAW_MAC)) {
-unsigned char *mac = (unsigned char *) GET_VALUE(res, KEY_RAW_MAC).ptr;
-int i, len = GET_VALUE(res, KEY_RAW_MACLEN).ui16;
+unsigned char *mac = (unsigned char *) ikey_get_ptr(&amp;res[KEY_RAW_MAC]);
+int i, len = ikey_get_u16(&amp;res[KEY_RAW_MACLEN]);
 
 buf_cur += sprintf(buf_cur, "MAC=");
 for (i = 0; i &lt; len; i++)
&lt; at &gt;&lt; at &gt; -438,7 +440,7 &lt; at &gt;&lt; at &gt; int printpkt_print(struct ulogd_key *res, char *buf)
 } else
 buf_cur += sprintf(buf_cur, "MAC= ");
 
-switch (GET_VALUE(res, KEY_OOB_FAMILY).ui8) {
+switch (ikey_get_u8(&amp;res[KEY_OOB_FAMILY])) {
 case AF_INET:
 buf_cur += printpkt_ipv4(res, buf_cur);
 break;
&lt; at &gt;&lt; at &gt; -452,13 +454,13 &lt; at &gt;&lt; at &gt; int printpkt_print(struct ulogd_key *res, char *buf)
 
 if (pp_is_valid(res, KEY_OOB_UID))
 buf_cur += sprintf(buf_cur, "UID=%u ",
-   GET_VALUE(res, KEY_OOB_UID).ui32);
+   ikey_get_u32(&amp;res[KEY_OOB_UID]));
 if (pp_is_valid(res, KEY_OOB_GID))
 buf_cur += sprintf(buf_cur, "GID=%u ",
-   GET_VALUE(res, KEY_OOB_GID).ui32);
+   ikey_get_u32(&amp;res[KEY_OOB_GID]));
 if (pp_is_valid(res, KEY_OOB_MARK))
 buf_cur += sprintf(buf_cur, "MARK=%x ",
-   GET_VALUE(res, KEY_OOB_MARK).ui32);
+   ikey_get_u32(&amp;res[KEY_OOB_MARK]));
 
 strcat(buf_cur, "\n");
 
</description>
    <dc:creator>Eric Leblond</dc:creator>
    <dc:date>2008-12-01T21:35:59</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/27399">
    <title>[ULOGD2 PATCH 15/18] Introduce config_stop() function</title>
    <link>http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/27399</link>
    <description>This patch adds the config_stop function which is in charge of releasing
ressources allocated for configuration file parsing.

Signed-off-by: Eric Leblond &lt;eric&lt; at &gt;inl.fr&gt;
---
 include/ulogd/conffile.h |    3 +++
 src/conffile.c           |    4 ++++
 src/ulogd.c              |    2 ++
 3 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/include/ulogd/conffile.h b/include/ulogd/conffile.h
index 826d9d5..7431243 100644
--- a/include/ulogd/conffile.h
+++ b/include/ulogd/conffile.h
&lt; at &gt;&lt; at &gt; -67,4 +67,7 &lt; at &gt;&lt; at &gt; int config_register_file(const char *file);
 /* parse the config file */
 int config_parse_file(const char *section, struct config_keyset *kset);
 
+/* release ressource allocated by config file handling */
+void config_stop();
+
 #endif /* ifndef _CONFFILE_H */
diff --git a/src/conffile.c b/src/conffile.c
index 0c1a2a4..b27187e 100644
--- a/src/conffile.c
+++ b/src/conffile.c
&lt; at &gt;&lt; at &gt; -222,3 +222,7 &lt; at &gt;&lt; at &gt; cpf_error:
 return err;
 }
 
+void config_stop()
+{
+free(fname);
+}
diff --git a/src/ulogd.c b/src/ulogd.c
index ae57a38..b079fd2 100644
--- a/src/ulogd.c
+++ b/src/ulogd.c
&lt; at &gt;&lt; at &gt; -1013,6 +1013,8 &lt; at &gt;&lt; at &gt; static void sigterm_handler(int signal)
 if (ulogd_logfile)
 free(ulogd_logfile);
 
+config_stop();
+
 exit(0);
 }
 
</description>
    <dc:creator>Eric Leblond</dc:creator>
    <dc:date>2008-12-01T21:36:13</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/27398">
    <title>[ULOGD2 PATCH 07/18] Add SCTP support to MySQL and PGSQL output.</title>
    <link>http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/27398</link>
    <description>This patch adds support for SCTP in the MySQL and PGSQL
output plugins. It adds a dedicated SCTP table and modifies
the insert_packet_full procedure.

Signed-off-by: Eric Leblond &lt;eric&lt; at &gt;inl.fr&gt;
---
 doc/mysql-ulogd2.sql |   43 ++++++++++++++++++++++++++++++++++++++++---
 doc/pgsql-ulogd2.sql |   41 +++++++++++++++++++++++++++++++++++++++--
 2 files changed, 79 insertions(+), 5 deletions(-)

diff --git a/doc/mysql-ulogd2.sql b/doc/mysql-ulogd2.sql
index f1fc710..0c2973d 100644
--- a/doc/mysql-ulogd2.sql
+++ b/doc/mysql-ulogd2.sql
&lt; at &gt;&lt; at &gt; -31,6 +31,7 &lt; at &gt;&lt; at &gt; DROP TABLE IF EXISTS `mac`;
 DROP TABLE IF EXISTS `hwhdr`;
 DROP TABLE IF EXISTS `tcp`;
 DROP TABLE IF EXISTS `udp`;
+DROP TABLE IF EXISTS `sctp`;
 DROP TABLE IF EXISTS `icmp`;
 DROP TABLE IF EXISTS `icmpv6`;
 DROP TABLE IF EXISTS `nufw`;
&lt; at &gt;&lt; at &gt; -128,6 +129,19 &lt; at &gt;&lt; at &gt; ALTER TABLE udp ADD KEY `index_udp_id` (`_udp_id`);
 ALTER TABLE udp ADD KEY `udp_sport` (`udp_sport`);
 ALTER TABLE udp ADD KEY `udp_dport` (`udp_dport`);
 
+CREATE TABLE `sctp` (
+  `_sctp_id` bigint unsigned NOT NULL,
+  `sctp_sport` int(5) unsigned default NULL,
+  `sctp_dport` int(5) unsigned default NULL,
+  `sctp_csum` int(5) unsigned default NULL
+) ENGINE=INNODB;
+
+ALTER TABLE sctp ADD UNIQUE KEY `_sctp_id` (`_sctp_id`);
+ALTER TABLE sctp ADD KEY `index_sctp_id` (`_sctp_id`);
+ALTER TABLE sctp ADD KEY `sctp_sport` (`sctp_sport`);
+ALTER TABLE sctp ADD KEY `sctp_dport` (`sctp_dport`);
+
+
 CREATE TABLE `icmp` (
   `_icmp_id` bigint unsigned NOT NULL,
   `icmp_type` tinyint(3) unsigned default NULL,
&lt; at &gt;&lt; at &gt; -231,10 +245,14 &lt; at &gt;&lt; at &gt; CREATE SQL SECURITY INVOKER VIEW `ulog` AS
         mac_saddr as mac_saddr_str,
         mac_daddr as mac_daddr_str,
         mac_protocol as oob_protocol,
-        label as raw_label
+        label as raw_label,
+        sctp_sport,
+        sctp_dport,
+        sctp_csum
         FROM ulog2 LEFT JOIN tcp ON ulog2._id = tcp._tcp_id LEFT JOIN udp ON ulog2._id = udp._udp_id
                 LEFT JOIN icmp ON ulog2._id = icmp._icmp_id LEFT JOIN mac ON ulog2.mac_id = mac._mac_id
-LEFT JOIN hwhdr ON ulog2._id = hwhdr._hw_id LEFT JOIN icmpv6 ON ulog2._id = icmpv6._icmpv6_id;
+LEFT JOIN hwhdr ON ulog2._id = hwhdr._hw_id LEFT JOIN icmpv6 ON ulog2._id = icmpv6._icmpv6_id
+LEFT JOIN sctp ON ulog2._id = sctp._sctp_id;
 
 
 -- shortcuts
&lt; at &gt;&lt; at &gt; -579,6 +597,20 &lt; at &gt;&lt; at &gt; END
 $$
 
 delimiter $$
+DROP PROCEDURE IF EXISTS PACKET_ADD_SCTP;
+CREATE PROCEDURE PACKET_ADD_SCTP(
+IN `id` int(10) unsigned,
+IN `_sport` smallint(5) unsigned,
+IN `_dport` smallint(5) unsigned,
+IN `_csum` smallint(5) unsigned
+)
+BEGIN
+INSERT INTO sctp (_sctp_id, sctp_sport, sctp_dport, sctp_csum) VALUES
+(id, _sport, _dport, _csum);
+END
+$$
+
+delimiter $$
 DROP PROCEDURE IF EXISTS PACKET_ADD_ICMP;
 CREATE PROCEDURE PACKET_ADD_ICMP(
 IN `id` int(10) unsigned,
&lt; at &gt;&lt; at &gt; -699,7 +731,10 &lt; at &gt;&lt; at &gt; CREATE FUNCTION INSERT_PACKET_FULL(
 mac_saddr varchar(32),
 mac_daddr varchar(32),
 mac_protocol smallint(5),
-_label tinyint(4) unsigned
+_label tinyint(4) unsigned,
+sctp_sport smallint(5) unsigned,
+sctp_dport smallint(5) unsigned,
+sctp_csum int(10) unsigned
 ) RETURNS bigint unsigned
 READS SQL DATA
 BEGIN
&lt; at &gt;&lt; at &gt; -714,6 +749,8 &lt; at &gt;&lt; at &gt; BEGIN
  tcp_rst, tcp_syn, tcp_fin);
 ELSEIF _ip_protocol = 17 THEN
 CALL PACKET_ADD_UDP(&lt; at &gt;lastid, udp_sport, udp_dport, udp_len);
+ELSEIF _ip_protocol = 132 THEN
+CALL PACKET_ADD_SCTP(&lt; at &gt;lastid, sctp_sport, sctp_dport, sctp_csum);
 ELSEIF _ip_protocol = 1 THEN
 CALL PACKET_ADD_ICMP(&lt; at &gt;lastid, icmp_type, icmp_code, icmp_echoid, icmp_echoseq, 
      icmp_gateway, icmp_fragmtu);
diff --git a/doc/pgsql-ulogd2.sql b/doc/pgsql-ulogd2.sql
index 9340801..73e038d 100644
--- a/doc/pgsql-ulogd2.sql
+++ b/doc/pgsql-ulogd2.sql
&lt; at &gt;&lt; at &gt; -29,6 +29,7 &lt; at &gt;&lt; at &gt; DROP TABLE IF EXISTS mac CASCADE;
 DROP TABLE IF EXISTS hwhdr CASCADE;
 DROP TABLE IF EXISTS tcp CASCADE;
 DROP TABLE IF EXISTS udp CASCADE;
+DROP TABLE IF EXISTS sctp CASCADE;
 DROP TABLE IF EXISTS icmp CASCADE;
 DROP TABLE IF EXISTS icmpv6 CASCADE;
 DROP TABLE IF EXISTS nufw CASCADE;
&lt; at &gt;&lt; at &gt; -119,6 +120,16 &lt; at &gt;&lt; at &gt; CREATE TABLE udp (
 CREATE INDEX udp_sport ON udp(udp_sport);
 CREATE INDEX udp_dport ON udp(udp_dport);
 
+CREATE TABLE sctp (
+  _sctp_id bigint PRIMARY KEY UNIQUE NOT NULL,
+  sctp_sport integer default NULL,
+  sctp_dport integer default NULL,
+  sctp_csum smallint default NULL
+) WITH (OIDS=FALSE);
+
+CREATE INDEX sctp_sport ON sctp(sctp_sport);
+CREATE INDEX sctp_dport ON sctp(sctp_dport);
+
 CREATE TABLE icmp (
   _icmp_id bigint PRIMARY KEY UNIQUE NOT NULL,
   icmp_type smallint default NULL,
&lt; at &gt;&lt; at &gt; -206,8 +217,12 &lt; at &gt;&lt; at &gt; CREATE OR REPLACE VIEW ulog AS
         mac_saddr AS mac_saddr_str,
         mac_daddr AS mac_daddr_str,
         mac_protocol AS oob_protocol,
-        label AS raw_label
+        label AS raw_label,
+        sctp_sport,
+        sctp_dport,
+        sctp_csum
         FROM ulog2 LEFT JOIN tcp ON ulog2._id = tcp._tcp_id LEFT JOIN udp ON ulog2._id = udp._udp_id
+                LEFT JOIN sctp ON ulog2._id = sctp._sctp_id
                 LEFT JOIN icmp ON ulog2._id = icmp._icmp_id
                 LEFT JOIN mac ON ulog2.mac_id = mac._mac_id
                 LEFT JOIN hwhdr ON ulog2._id = hwhdr._hw_id
&lt; at &gt;&lt; at &gt; -291,6 +306,7 &lt; at &gt;&lt; at &gt; INSERT INTO ip_proto (_proto_id,proto_name,proto_desc) VALUES
         (6,'tcp','transmission control protocol'),
         (17,'udp','user datagram protocol'),
         (41,'ipv6','Internet Protocol, version 6'),
+        (132,'sctp','Stream Control Transmission Protocol'),
         (58,'ipv6-icmp','ICMP for IPv6');
 
 -- 
&lt; at &gt;&lt; at &gt; -335,6 +351,7 &lt; at &gt;&lt; at &gt; CREATE OR REPLACE FUNCTION ULOG2_ADD_FOREIGN_KEYS()
 RETURNS void AS $$
   ALTER TABLE tcp  ADD CONSTRAINT tcp_id_fk  FOREIGN KEY (_tcp_id)  REFERENCES ulog2(_id);
   ALTER TABLE udp  ADD CONSTRAINT udp_id_fk  FOREIGN KEY (_udp_id)  REFERENCES ulog2(_id);
+  ALTER TABLE sctp  ADD CONSTRAINT sctp_id_fk  FOREIGN KEY (_sctp_id)  REFERENCES ulog2(_id);
   ALTER TABLE icmp ADD CONSTRAINT icmp_id_fk FOREIGN KEY (_icmp_id) REFERENCES ulog2(_id);
   ALTER TABLE icmpv6 ADD CONSTRAINT icmpv6_id_fk FOREIGN KEY (_icmpv6_id) REFERENCES ulog2(_id);
   ALTER TABLE ulog2 ADD CONSTRAINT mac_id_fk FOREIGN KEY (mac_id) REFERENCES mac(_mac_id);
&lt; at &gt;&lt; at &gt; -424,6 +441,18 &lt; at &gt;&lt; at &gt; RETURNS bigint AS $$
         SELECT currval('ulog2__id_seq');
 $$ LANGUAGE SQL SECURITY INVOKER;
 
+CREATE OR REPLACE FUNCTION INSERT_SCTP(
+                IN sctp_id bigint,
+                IN sctp_sport integer,
+                IN sctp_dport integer,
+                IN sctp_csum integer
+        )
+RETURNS bigint AS $$
+        INSERT INTO sctp (_sctp_id,sctp_sport,sctp_dport,sctp_csum)
+                VALUES ($1,$2,$3,$4);
+        SELECT currval('ulog2__id_seq');
+$$ LANGUAGE SQL SECURITY INVOKER;
+
 CREATE OR REPLACE FUNCTION INSERT_ICMP(
                 IN icmp_id bigint,
                 IN icmp_type integer,
&lt; at &gt;&lt; at &gt; -538,7 +567,10 &lt; at &gt;&lt; at &gt; CREATE OR REPLACE FUNCTION INSERT_PACKET_FULL(
                 IN mac_saddr varchar(32),
                 IN mac_daddr varchar(32),
                 IN mac_protocol integer,
-                IN label integer
+                IN label integer,
+                IN sctp_sport integer,
+                IN sctp_dport integer,
+                IN sctp_csum integer
         )
 RETURNS bigint AS $$
 DECLARE
&lt; at &gt;&lt; at &gt; -550,6 +582,8 &lt; at &gt;&lt; at &gt; BEGIN
                 PERFORM INSERT_TCP_FULL(t_id,$19,$20,$21,$22,$23,$24,$25,$26,$27,$28,$29,$30);
         ELSIF (ip_protocol = 17) THEN
                 PERFORM INSERT_UDP(t_id,$31,$32,$33);
+        ELSIF (ip_protocol = 132) THEN
+                PERFORM INSERT_SCTP(t_id,$51,$52,$53);
         ELSIF (ip_protocol = 1) THEN
                 PERFORM INSERT_ICMP(t_id,$34,$35,$36,$37,$38,$39);
         ELSIF (ip_protocol = 58) THEN
&lt; at &gt;&lt; at &gt; -677,6 +711,7 &lt; at &gt;&lt; at &gt; RETURNS void AS $$
   DELETE FROM icmp  WHERE icmp._icmp_id = $1;
   DELETE FROM tcp   WHERE tcp._tcp_id   = $1;
   DELETE FROM udp   WHERE udp._udp_id   = $1;
+  DELETE FROM sctp   WHERE sctp._sctp_id   = $1;
   DELETE FROM ulog2 WHERE ulog2._id     = $1;
 $$ LANGUAGE SQL SECURITY INVOKER;
 
&lt; at &gt;&lt; at &gt; -717,10 +752,12 &lt; at &gt;&lt; at &gt; RETURNS void AS $$
   -- DELETE FROM tcp WHERE _tcp_id IN (SELECT tcp._tcp_id FROM tcp LEFT OUTER JOIN ulog2  ON (tcp._tcp_id = ulog2._id) WHERE ulog2._id IS NULL);
   DELETE FROM mac WHERE _mac_id NOT IN (SELECT _id FROM ulog2);
   DELETE FROM udp WHERE _udp_id NOT IN (SELECT _id FROM ulog2);
+  DELETE FROM sctp WHERE _sctp_id NOT IN (SELECT _id FROM ulog2);
   DELETE FROM icmp WHERE _icmp_id NOT IN (SELECT _id FROM ulog2);
   -- look for packets in table ulog2 with proto tcp (or ipv6 ?) and not in table tcp
   DELETE FROM ulog2 WHERE ulog2.ip_protocol = '6' AND _id NOT IN (SELECT _tcp_id FROM tcp);
   DELETE FROM ulog2 WHERE ulog2.ip_protocol = '17' AND _id NOT IN (SELECT _udp_id FROM udp);
+  DELETE FROM ulog2 WHERE ulog2.ip_protocol = '132' AND _id NOT IN (SELECT _sctp_id FROM sctp);
   DELETE FROM ulog2 WHERE ulog2.ip_protocol = '2' AND _id NOT IN (SELECT _icmp_id FROM icmp);
 $$ LANGUAGE SQL SECURITY INVOKER;
 
</description>
    <dc:creator>Eric Leblond</dc:creator>
    <dc:date>2008-12-01T21:36:05</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/27397">
    <title>[ULOGD2 PATCH 16/18] Free stacks when exiting.</title>
    <link>http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/27397</link>
    <description>This patch modifies ulogd2 to have it free the stacks when leaving.

Signed-off-by: Eric Leblond &lt;eric&lt; at &gt;inl.fr&gt;
---
 src/ulogd.c |   12 ++++++++++++
 1 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/src/ulogd.c b/src/ulogd.c
index b079fd2..1a1f6af 100644
--- a/src/ulogd.c
+++ b/src/ulogd.c
&lt; at &gt;&lt; at &gt; -994,6 +994,16 &lt; at &gt;&lt; at &gt; static void unload_plugins()
 }
 }
 
+static void stop_stack()
+{
+struct ulogd_pluginstance_stack *stack, *nstack;
+
+llist_for_each_entry_safe(stack, nstack, &amp;ulogd_pi_stacks, stack_list) {
+free(stack);
+}
+}
+
+
 static void sigterm_handler(int signal)
 {
 
&lt; at &gt;&lt; at &gt; -1003,6 +1013,8 &lt; at &gt;&lt; at &gt; static void sigterm_handler(int signal)
 
 stop_pluginstances();
 
+stop_stack();
+
 unload_plugins();
 
 if (logfile != NULL  &amp;&amp; logfile != stdout) {
</description>
    <dc:creator>Eric Leblond</dc:creator>
    <dc:date>2008-12-01T21:36:14</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/27396">
    <title>[ULOGD2 PATCH 04/18] Document group 0 usage and suppress address_family</title>
    <link>http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/27396</link>
    <description>Document the fact that group 0 is used by system logging and
update stack and plugin definition to match the suppression
of the address_family variable.

Signed-off-by: Eric Leblond &lt;eric&lt; at &gt;inl.fr&gt;
---
 ulogd.conf.in |   37 ++++++++++++++++++++-----------------
 1 files changed, 20 insertions(+), 17 deletions(-)

diff --git a/ulogd.conf.in b/ulogd.conf.in
index e24e6b6..a48af3f 100644
--- a/ulogd.conf.in
+++ b/ulogd.conf.in
&lt; at &gt;&lt; at &gt; -45,20 +45,17 &lt; at &gt;&lt; at &gt; plugin="&lt; at &gt;libdir&lt; at &gt;/ulogd/ulogd_output_SYSLOG.so"
 #plugin="&lt; at &gt;libdir&lt; at &gt;/ulogd/ulogd_output_DBI.so"
 plugin="&lt; at &gt;libdir&lt; at &gt;/ulogd/ulogd_raw2packet_BASE.so"
 
-# this is a stack for IPv4 packet-based logging via LOGEMU
+# this is a stack for logging packet send by system via LOGEMU
 #stack=log1:NFLOG,base1:BASE,ifi1:IFINDEX,ip2str1:IP2STR,print1:PRINTPKT,emu1:LOGEMU
 
-# this is a stack for IPv6 packet-based logging via LOGEMU
+# this is a stack for packet-based logging via LOGEMU
 #stack=log2:NFLOG,base1:BASE,ifi1:IFINDEX,ip2str1:IP2STR,print1:PRINTPKT,emu1:LOGEMU
 
-# this is a stack for ebtables packet-based logging via LOGEMU
-#stack=log3:NFLOG,base1:BASE,ifi1:IFINDEX,ip2str1:IP2STR,print1:PRINTPKT,emu1:LOGEMU
-
 # this is a stack for ULOG packet-based logging via LOGEMU
 #stack=ulog1:ULOG,base1:BASE,ip2str1:IP2STR,print1:PRINTPKT,emu1:LOGEMU
 
-# this is a stack for IPv4 packet-based logging via LOGEMU with filtering on MARK
-#stack=log1:NFLOG,mark1:MARK,base1:BASE,ifi1:IFINDEX,ip2str1:IP2STR,print1:PRINTPKT,emu1:LOGEMU
+# this is a stack for packet-based logging via LOGEMU with filtering on MARK
+#stack=log2:NFLOG,mark1:MARK,base1:BASE,ifi1:IFINDEX,ip2str1:IP2STR,print1:PRINTPKT,emu1:LOGEMU
 
 # this is a stack for flow-based logging via LOGEMU
 #stack=ct1:NFCT,ip2str1:IP2STR,print1:PRINTFLOW,emu1:LOGEMU
&lt; at &gt;&lt; at &gt; -67,15 +64,15 &lt; at &gt;&lt; at &gt; plugin="&lt; at &gt;libdir&lt; at &gt;/ulogd/ulogd_raw2packet_BASE.so"
 #stack=ct1:NFCT,op1:OPRINT
 
 # this is a stack for NFLOG packet-based logging to PCAP
-#stack=log1:NFLOG,base1:BASE,pcap1:PCAP
+#stack=log2:NFLOG,base1:BASE,pcap1:PCAP
 
 # this is a stack for logging packet to MySQL
-#stack=log1:NFLOG,base1:BASE,ifi1:IFINDEX,ip2bin1:IP2BIN,mac2str1:MAC2STR,mysql1:MYSQL
+#stack=log2:NFLOG,base1:BASE,ifi1:IFINDEX,ip2bin1:IP2BIN,mac2str1:MAC2STR,mysql1:MYSQL
 
-# this is a stack for logging IPv6 packet to PGsql after a collect via NFLOG
+# this is a stack for logging packet to PGsql after a collect via NFLOG
 #stack=log2:NFLOG,base1:BASE,ifi1:IFINDEX,ip2str1:IP2STR,mac2str1:MAC2STR,pgsql1:PGSQL
 
-# this is a stack for logging ebtables packets to syslog after a collect via NFLOG
+# this is a stack for logging packets to syslog after a collect via NFLOG
 #stack=log3:NFLOG,base1:BASE,ifi1:IFINDEX,ip2str1:IP2STR,print1:PRINTPKT,sys1:SYSLOG
 
 # this is a stack for flow-based logging to MySQL
&lt; at &gt;&lt; at &gt; -100,23 +97,29 &lt; at &gt;&lt; at &gt; plugin="&lt; at &gt;libdir&lt; at &gt;/ulogd/ulogd_raw2packet_BASE.so"
 #netlink_socket_buffer_maxsize=1085440
 hash_enable=0
 
-# IPv4 logging through NFLOG
+# Logging of system packet through NFLOG
 [log1]
 # netlink multicast group (the same as the iptables --nflog-group param)
+# Group O is used by the kernel to log connection tracking invalid message
 group=0
 #netlink_socket_buffer_size=217088
 #netlink_socket_buffer_maxsize=1085440
 
-# IPv6 logging through NFLOG
+# packet logging through NFLOG for group 1
 [log2]
+# netlink multicast group (the same as the iptables --nflog-group param)
 group=1 # Group has to be different from the one use in log1
-addressfamily=10 # 10 is value of AF_INET6
-numeric_label=1 # you can label the log info based on the packet verdict
+#netlink_socket_buffer_size=217088
+#netlink_socket_buffer_maxsize=1085440
 
-# ebtables logging through NFLOG
+# packet logging through NFLOG for group 2, numeric_label is
+# set to 1
 [log3]
+# netlink multicast group (the same as the iptables --nflog-group param)
 group=2 # Group has to be different from the one use in log1/log2
-addressfamily=7 # 7 is value of AF_BRIDGE
+numeric_label=1 # you can label the log info based on the packet verdict
+#netlink_socket_buffer_size=217088
+#netlink_socket_buffer_maxsize=1085440
 
 [ulog1]
 # netlink multicast group (the same as the iptables --ulog-nlgroup param)
</description>
    <dc:creator>Eric Leblond</dc:creator>
    <dc:date>2008-12-01T21:36:02</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/27395">
    <title>[ULOGD2 PATCH 09/18] Fix stop function of NFCT plugin.</title>
    <link>http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/27395</link>
    <description>This patch fixes some crashes in NFCT plugin that were triggered
by the call of the destructor_nfct function (during stop).

Signed-off-by: Eric Leblond &lt;eric&lt; at &gt;inl.fr&gt;
---
 input/flow/ulogd_inpflow_NFCT.c |    2 +-
 src/hash.c                      |    6 ++++--
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/input/flow/ulogd_inpflow_NFCT.c b/input/flow/ulogd_inpflow_NFCT.c
index a33ec35..a39bf08 100644
--- a/input/flow/ulogd_inpflow_NFCT.c
+++ b/input/flow/ulogd_inpflow_NFCT.c
&lt; at &gt;&lt; at &gt; -884,7 +884,7 &lt; at &gt;&lt; at &gt; static int constructor_nfct(struct ulogd_pluginstance *upi)
 
 static int destructor_nfct(struct ulogd_pluginstance *pi)
 {
-struct nfct_pluginstance *cpi = (void *) pi;
+struct nfct_pluginstance *cpi = (void *) pi-&gt;private;
 int rc;
 
 hashtable_destroy(cpi-&gt;ct_active);
diff --git a/src/hash.c b/src/hash.c
index 33541e8..700678c 100644
--- a/src/hash.c
+++ b/src/hash.c
&lt; at &gt;&lt; at &gt; -75,8 +75,10 &lt; at &gt;&lt; at &gt; hashtable_create(int hashsize, int limit, int datasize,
 
 void hashtable_destroy(struct hashtable *h)
 {
-hashtable_flush(h);
-free(h);
+if (h) {
+hashtable_flush(h);
+free(h);
+}
 }
 
 void *hashtable_add(struct hashtable *table, void *data)
</description>
    <dc:creator>Eric Leblond</dc:creator>
    <dc:date>2008-12-01T21:36:07</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/27394">
    <title>[ULOGD2 PATCH 14/18] Unload plugins when quitting.</title>
    <link>http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/27394</link>
    <description>This patch adds unloading of plugins (call dlclose()) in ulogd2. This
make valgrind happy and will be useful for daemon live reconfiguration.

Signed-off-by: Eric Leblond &lt;eric&lt; at &gt;inl.fr&gt;
---
 include/ulogd/ulogd.h |    8 ++++++++
 src/ulogd.c           |   21 ++++++++++++++++++++-
 2 files changed, 28 insertions(+), 1 deletions(-)

diff --git a/include/ulogd/ulogd.h b/include/ulogd/ulogd.h
index 3f6d784..f55d5f1 100644
--- a/include/ulogd/ulogd.h
+++ b/include/ulogd/ulogd.h
&lt; at &gt;&lt; at &gt; -187,6 +187,14 &lt; at &gt;&lt; at &gt; static inline void *ikey_get_ptr(struct ulogd_key *key)
 
 struct ulogd_pluginstance_stack;
 struct ulogd_pluginstance;
+
+struct ulogd_plugin_handle {
+/* global list of plugins */
+struct llist_head list;
+void *handle;
+};
+
+
 struct ulogd_plugin {
 /* global list of plugins */
 struct llist_head list;
diff --git a/src/ulogd.c b/src/ulogd.c
index 2f80913..ae57a38 100644
--- a/src/ulogd.c
+++ b/src/ulogd.c
&lt; at &gt;&lt; at &gt; -83,6 +83,8 &lt; at &gt;&lt; at &gt; static int info_mode = 0;
 
 /* linked list for all registered plugins */
 static LLIST_HEAD(ulogd_plugins);
+/* linked list for all plugins handle */
+static LLIST_HEAD(ulogd_plugins_handle);
 static LLIST_HEAD(ulogd_pi_stacks);
 
 
&lt; at &gt;&lt; at &gt; -580,11 +582,17 &lt; at &gt;&lt; at &gt; pluginstance_alloc_init(struct ulogd_plugin *pl, char *pi_id,
 /* plugin loader to dlopen() a plugins */
 static int load_plugin(const char *file)
 {
-if (!dlopen(file, RTLD_NOW)) {
+void * handle;
+struct ulogd_plugin_handle *ph;
+if ((handle = dlopen(file, RTLD_NOW)) == NULL) {
 ulogd_log(ULOGD_ERROR, "load_plugin: '%s': %s\n", file,
   dlerror());
 return -1;
 }
+
+ph = (struct ulogd_plugin_handle *) calloc(1, sizeof(*ph));
+ph-&gt;handle = handle;
+llist_add(&amp;ph-&gt;list, &amp;ulogd_plugins_handle);
 return 0;
 }
 
&lt; at &gt;&lt; at &gt; -977,6 +985,15 &lt; at &gt;&lt; at &gt; static void stop_pluginstances()
 }
 }
 
+static void unload_plugins()
+{
+struct ulogd_plugin_handle *ph, *nph;
+llist_for_each_entry_safe(ph, nph, &amp;ulogd_plugins_handle, list) {
+dlclose(ph-&gt;handle);
+free(ph);
+}
+}
+
 static void sigterm_handler(int signal)
 {
 
&lt; at &gt;&lt; at &gt; -986,6 +1003,8 &lt; at &gt;&lt; at &gt; static void sigterm_handler(int signal)
 
 stop_pluginstances();
 
+unload_plugins();
+
 if (logfile != NULL  &amp;&amp; logfile != stdout) {
 fclose(logfile);
 logfile = NULL;
</description>
    <dc:creator>Eric Leblond</dc:creator>
    <dc:date>2008-12-01T21:36:12</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/27393">
    <title>[ULOGD2 PATCH 03/18] Get rid of addressfamily variable in NFLOG input plugin</title>
    <link>http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/27393</link>
    <description>The addressfamily configuration variable for NFLOG is used as param
for nflog_bind_pf. This function is used to claim the fetching of
kernel message sent via nf_log_packet() function.

As all kernel messages are sent to the group 0, it is useless to
call nflog_bind_pf when nflog group of the input plugin is not 0.
Furthermore, as only one plugin can be bound to nflog group 0, it
is mandatory to call nflog_bind_pf for all pf family when the group
is 0.

To sum up, this patch suppress the adressfamily parameter (which
simplify the configuration file) and call nflog_bind_pf for all
pf family when the nflog group of the instance is 0.

Signed-off-by: Eric Leblond &lt;eric&lt; at &gt;inl.fr&gt;
---
 input/packet/ulogd_inppkt_NFLOG.c |   59 ++++++++++++++++++-------------------
 1 files changed, 29 insertions(+), 30 deletions(-)

diff --git a/input/packet/ulogd_inppkt_NFLOG.c b/input/packet/ulogd_inppkt_NFLOG.c
index 647b61c..e27355d 100644
--- a/input/packet/ulogd_inppkt_NFLOG.c
+++ b/input/packet/ulogd_inppkt_NFLOG.c
&lt; at &gt;&lt; at &gt; -46,12 +46,6 &lt; at &gt;&lt; at &gt; static struct config_keyset libulog_kset = {
 .u.value = NFLOG_GROUP_DEFAULT,
 },
 {
-.key  = "addressfamily",
-.type = CONFIG_TYPE_INT,
-.options = CONFIG_OPT_NONE,
-.u.value = AF_INET,
-},
-{
 .key = "unbind",
 .type = CONFIG_TYPE_INT,
 .options = CONFIG_OPT_NONE,
&lt; at &gt;&lt; at &gt; -92,13 +86,12 &lt; at &gt;&lt; at &gt; static struct config_keyset libulog_kset = {
 
 #define bufsiz_ce(x)(x-&gt;ces[0])
 #define group_ce(x)(x-&gt;ces[1])
-#define af_ce(x)(x-&gt;ces[2])
-#define unbind_ce(x)(x-&gt;ces[3])
-#define seq_ce(x)(x-&gt;ces[4])
-#define seq_global_ce(x)(x-&gt;ces[5])
-#define label_ce(x)(x-&gt;ces[6])
-#define nlsockbufsize_ce(x) (x-&gt;ces[7])
-#define nlsockbufmaxsize_ce(x) (x-&gt;ces[8])
+#define unbind_ce(x)(x-&gt;ces[2])
+#define seq_ce(x)(x-&gt;ces[3])
+#define seq_global_ce(x)(x-&gt;ces[4])
+#define label_ce(x)(x-&gt;ces[5])
+#define nlsockbufsize_ce(x) (x-&gt;ces[6])
+#define nlsockbufmaxsize_ce(x) (x-&gt;ces[7])
 
 enum nflog_keys {
 NFLOG_KEY_RAW_MAC = 0,
&lt; at &gt;&lt; at &gt; -293,7 +286,8 &lt; at &gt;&lt; at &gt; static struct ulogd_key output_keys[] = {
 };
 
 static inline int
-interp_packet(struct ulogd_pluginstance *upi, struct nflog_data *ldata)
+interp_packet(struct ulogd_pluginstance *upi, u_int8_t pf_family,
+      struct nflog_data *ldata)
 {
 struct ulogd_key *ret = upi-&gt;output.keys;
 
&lt; at &gt;&lt; at &gt; -311,7 +305,7 &lt; at &gt;&lt; at &gt; interp_packet(struct ulogd_pluginstance *upi, struct nflog_data *ldata)
 u_int32_t gid;
 
 okey_set_u8(&amp;ret[NFLOG_KEY_OOB_FAMILY], 
-    af_ce(upi-&gt;config_kset).u.value);
+    pf_family);
 okey_set_u8(&amp;ret[NFLOG_KEY_RAW_LABEL],
     label_ce(upi-&gt;config_kset).u.value);
 
&lt; at &gt;&lt; at &gt; -446,11 +440,11 &lt; at &gt;&lt; at &gt; static int msg_cb(struct nflog_g_handle *gh, struct nfgenmsg *nfmsg,
 /* since we support the re-use of one instance in several 
  * different stacks, we duplicate the message to let them know */
 llist_for_each_entry(npi, &amp;upi-&gt;plist, plist) {
-ret = interp_packet(npi, nfa);
+ret = interp_packet(npi, nfmsg-&gt;nfgen_family, nfa);
 if (ret != 0)
 return ret;
 }
-return interp_packet(upi, nfa);
+return interp_packet(upi, nfmsg-&gt;nfgen_family, nfa);
 }
 
 static int configure(struct ulogd_pluginstance *upi,
&lt; at &gt;&lt; at &gt; -463,28 +457,26 &lt; at &gt;&lt; at &gt; static int configure(struct ulogd_pluginstance *upi,
 return 0;
 }
 
-static int become_system_logging(struct ulogd_pluginstance *upi)
+static int become_system_logging(struct ulogd_pluginstance *upi, u_int8_t pf)
 {
 struct nflog_input *ui = (struct nflog_input *) upi-&gt;private;
 
 if (unbind_ce(upi-&gt;config_kset).u.value &gt; 0) {
 ulogd_log(ULOGD_NOTICE, "forcing unbind of existing log "
 "handler for protocol %d\n",
-af_ce(upi-&gt;config_kset).u.value);
-if (nflog_unbind_pf(ui-&gt;nful_h,
-af_ce(upi-&gt;config_kset).u.value) &lt; 0) {
+pf);
+if (nflog_unbind_pf(ui-&gt;nful_h, pf) &lt; 0) {
 ulogd_log(ULOGD_ERROR, "unable to force-unbind "
 "existing log handler for protocol %d\n",
-af_ce(upi-&gt;config_kset).u.value);
+pf);
 return -1;
 }
 }
 
-ulogd_log(ULOGD_DEBUG, "binding to protocol family %d\n",
-af_ce(upi-&gt;config_kset).u.value);
-if (nflog_bind_pf(ui-&gt;nful_h, af_ce(upi-&gt;config_kset).u.value) &lt; 0) {
-ulogd_log(ULOGD_ERROR, "unable to bind to protocol family %d\n",
-af_ce(upi-&gt;config_kset).u.value);
+ulogd_log(ULOGD_DEBUG, "binding to protocol family %d\n", pf);
+if (nflog_bind_pf(ui-&gt;nful_h, pf) &lt; 0) {
+ulogd_log(ULOGD_ERROR, "unable to bind to"
+" protocol family %d\n", pf);
 return -1;
 }
 return 0;
&lt; at &gt;&lt; at &gt; -506,7 +498,11 &lt; at &gt;&lt; at &gt; static int start(struct ulogd_pluginstance *upi)
 
 /* This is the system logging (conntrack, ...) facility */
 if (group_ce(upi-&gt;config_kset).u.value == 0) {
-if (become_system_logging(upi) == -1)
+if (become_system_logging(upi, AF_INET) == -1)
+goto out_handle;
+if (become_system_logging(upi, AF_INET6) == -1)
+goto out_handle;
+if (become_system_logging(upi, AF_BRIDGE) == -1)
 goto out_handle;
 }
 
&lt; at &gt;&lt; at &gt; -554,8 +550,11 &lt; at &gt;&lt; at &gt; static int start(struct ulogd_pluginstance *upi)
 
 out_bind:
 nflog_close(ui-&gt;nful_h);
-if (group_ce(upi-&gt;config_kset).u.value == 0)
-nflog_unbind_pf(ui-&gt;nful_h, af_ce(upi-&gt;config_kset).u.value);
+if (group_ce(upi-&gt;config_kset).u.value == 0) {
+nflog_unbind_pf(ui-&gt;nful_h, AF_INET);
+nflog_unbind_pf(ui-&gt;nful_h, AF_INET6);
+nflog_unbind_pf(ui-&gt;nful_h, AF_BRIDGE);
+}
 out_handle:
 free(ui-&gt;nfulog_buf);
 out_buf:
</description>
    <dc:creator>Eric Leblond</dc:creator>
    <dc:date>2008-12-01T21:36:01</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/27392">
    <title>[ULOGD2 PATCH 13/18] Add SIGINT to list of terminal signal.</title>
    <link>http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/27392</link>
    <description>This patch modifies ulogd to intercept SIGINT signal
and quit nicely when this signal is received.

Signed-off-by: Eric Leblond &lt;eric&lt; at &gt;inl.fr&gt;
---
 src/ulogd.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/src/ulogd.c b/src/ulogd.c
index d193b26..2f80913 100644
--- a/src/ulogd.c
+++ b/src/ulogd.c
&lt; at &gt;&lt; at &gt; -980,7 +980,7 &lt; at &gt;&lt; at &gt; static void stop_pluginstances()
 static void sigterm_handler(int signal)
 {
 
-ulogd_log(ULOGD_NOTICE, "sigterm received, exiting\n");
+ulogd_log(ULOGD_NOTICE, "Terminal signal received, exiting\n");
 
 deliver_signal_pluginstances(signal);
 
&lt; at &gt;&lt; at &gt; -1173,6 +1173,7 &lt; at &gt;&lt; at &gt; int main(int argc, char* argv[])
 }
 
 signal(SIGTERM, &amp;sigterm_handler);
+signal(SIGINT, &amp;sigterm_handler);
 signal(SIGHUP, &amp;signal_handler);
 signal(SIGALRM, &amp;signal_handler);
 signal(SIGUSR1, &amp;signal_handler);
</description>
    <dc:creator>Eric Leblond</dc:creator>
    <dc:date>2008-12-01T21:36:11</dc:date>
  </item>
  <textinput about="http://search.gmane.org/?group=$group=gmane.comp.security.firewalls.netfilter.devel">
    <title>Search Engine</title>
    <description>Search the mailing list at Gmane</description>
    <name>query</name>
    <link>http://search.gmane.org/?group=$group=gmane.comp.security.firewalls.netfilter.devel</link>
  </textinput>
</rdf:RDF>
