summaryrefslogtreecommitdiffstats
path: root/src/build.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/build.c')
-rw-r--r--src/build.c202
1 files changed, 99 insertions, 103 deletions
diff --git a/src/build.c b/src/build.c
index be33c86..5143048 100644
--- a/src/build.c
+++ b/src/build.c
@@ -1,5 +1,5 @@
/*
- * (C) 2006-2007 by Pablo Neira Ayuso <pablo@netfilter.org>
+ * (C) 2006-2008 by Pablo Neira Ayuso <pablo@netfilter.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,143 +20,139 @@
#include <libnetfilter_conntrack/libnetfilter_conntrack.h>
#include "network.h"
-static void addattr(struct netpld *pld, int attr, const void *data, size_t len)
+static inline void *
+put_header(struct netpld *pld, int attr, size_t len)
{
- struct netattr *nta;
- int tlen = NTA_LENGTH(len);
-
- nta = PLD_TAIL(pld);
+ struct netattr *nta = PLD_TAIL(pld);
+ pld->len += NTA_ALIGN(NTA_LENGTH(len));
nta->nta_attr = htons(attr);
nta->nta_len = htons(len);
- memcpy(NTA_DATA(nta), data, len);
- pld->len += NTA_ALIGN(tlen);
+ return NTA_DATA(nta);
}
-static void __build_u8(const struct nf_conntrack *ct,
- struct netpld *pld,
- int attr)
+static inline void
+addattr(struct netpld *pld, int attr, const void *data, size_t len)
{
- uint8_t data = nfct_get_attr_u8(ct, attr);
- addattr(pld, attr, &data, sizeof(uint8_t));
+ void *ptr = put_header(pld, attr, len);
+ memcpy(ptr, data, len);
}
-static void __build_u16(const struct nf_conntrack *ct,
- struct netpld *pld,
- int attr)
+static inline void
+__build_u8(const struct nf_conntrack *ct, int a, struct netpld *pld, int b)
{
- uint16_t data = nfct_get_attr_u16(ct, attr);
- data = htons(data);
- addattr(pld, attr, &data, sizeof(uint16_t));
+ void *ptr = put_header(pld, b, sizeof(uint8_t));
+ memcpy(ptr, nfct_get_attr(ct, a), sizeof(uint8_t));
}
-static void __build_u32(const struct nf_conntrack *ct,
- struct netpld *pld,
- int attr)
+static inline void
+__build_u16(const struct nf_conntrack *ct, int a, struct netpld *pld, int b)
{
- uint32_t data = nfct_get_attr_u32(ct, attr);
- data = htonl(data);
- addattr(pld, attr, &data, sizeof(uint32_t));
+ uint32_t data = nfct_get_attr_u16(ct, a);
+ data = htons(data);
+ addattr(pld, b, &data, sizeof(uint16_t));
}
-static void __build_pointer_be(const struct nf_conntrack *ct,
- struct netpld *pld,
- int attr,
- size_t size)
+static inline void
+__build_u32(const struct nf_conntrack *ct, int a, struct netpld *pld, int b)
{
- addattr(pld, attr, nfct_get_attr(ct, attr), size);
+ uint32_t data = nfct_get_attr_u32(ct, a);
+ data = htonl(data);
+ addattr(pld, b, &data, sizeof(uint32_t));
}
-static void __nat_build_u32(uint32_t data, struct netpld *pld, int attr)
+static inline void
+__build_group(const struct nf_conntrack *ct, int a, struct netpld *pld,
+ int b, int size)
{
- data = htonl(data);
- addattr(pld, attr, &data, sizeof(uint32_t));
+ void *ptr = put_header(pld, b, size);
+ nfct_get_attr_grp(ct, a, ptr);
}
-static void __nat_build_u16(uint16_t data, struct netpld *pld, int attr)
+static inline void
+__build_natseqadj(const struct nf_conntrack *ct, struct netpld *pld)
{
- data = htons(data);
- addattr(pld, attr, &data, sizeof(uint16_t));
+ struct nta_attr_natseqadj data = {
+ .orig_seq_correction_pos =
+ htonl(nfct_get_attr_u32(ct, ATTR_ORIG_NAT_SEQ_CORRECTION_POS)),
+ .orig_seq_offset_before =
+ htonl(nfct_get_attr_u32(ct, ATTR_ORIG_NAT_SEQ_OFFSET_BEFORE)),
+ .orig_seq_offset_after =
+ htonl(nfct_get_attr_u32(ct, ATTR_ORIG_NAT_SEQ_OFFSET_AFTER)),
+ .repl_seq_correction_pos =
+ htonl(nfct_get_attr_u32(ct, ATTR_REPL_NAT_SEQ_CORRECTION_POS)),
+ .repl_seq_offset_before =
+ htonl(nfct_get_attr_u32(ct, ATTR_REPL_NAT_SEQ_OFFSET_BEFORE)),
+ .repl_seq_offset_after =
+ htonl(nfct_get_attr_u32(ct, ATTR_REPL_NAT_SEQ_OFFSET_AFTER))
+ };
+ addattr(pld, NTA_NAT_SEQ_ADJ, &data, sizeof(struct nta_attr_natseqadj));
}
+static enum nf_conntrack_attr nat_type[] =
+ { ATTR_ORIG_NAT_SEQ_CORRECTION_POS, ATTR_ORIG_NAT_SEQ_OFFSET_BEFORE,
+ ATTR_ORIG_NAT_SEQ_OFFSET_AFTER, ATTR_REPL_NAT_SEQ_CORRECTION_POS,
+ ATTR_REPL_NAT_SEQ_OFFSET_BEFORE, ATTR_REPL_NAT_SEQ_OFFSET_AFTER };
+
/* XXX: ICMP not supported */
void build_netpld(struct nf_conntrack *ct, struct netpld *pld, int query)
{
- if (nfct_attr_is_set(ct, ATTR_IPV4_SRC))
- __build_pointer_be(ct, pld, ATTR_IPV4_SRC, sizeof(uint32_t));
- if (nfct_attr_is_set(ct, ATTR_IPV4_DST))
- __build_pointer_be(ct, pld, ATTR_IPV4_DST, sizeof(uint32_t));
- if (nfct_attr_is_set(ct, ATTR_IPV6_SRC))
- __build_pointer_be(ct, pld, ATTR_IPV6_SRC, sizeof(uint32_t)*4);
- if (nfct_attr_is_set(ct, ATTR_IPV6_DST))
- __build_pointer_be(ct, pld, ATTR_IPV6_DST, sizeof(uint32_t)*4);
- if (nfct_attr_is_set(ct, ATTR_L3PROTO))
- __build_u8(ct, pld, ATTR_L3PROTO);
- if (nfct_attr_is_set(ct, ATTR_PORT_SRC))
- __build_u16(ct, pld, ATTR_PORT_SRC);
- if (nfct_attr_is_set(ct, ATTR_PORT_DST))
- __build_u16(ct, pld, ATTR_PORT_DST);
- if (nfct_attr_is_set(ct, ATTR_L4PROTO)) {
- uint8_t proto;
-
- __build_u8(ct, pld, ATTR_L4PROTO);
- proto = nfct_get_attr_u8(ct, ATTR_L4PROTO);
- if (proto == IPPROTO_TCP) {
- if (nfct_attr_is_set(ct, ATTR_TCP_STATE))
- __build_u8(ct, pld, ATTR_TCP_STATE);
- }
+ if (nfct_attr_grp_is_set(ct, ATTR_GRP_ORIG_IPV4)) {
+ __build_group(ct, ATTR_GRP_ORIG_IPV4, pld, NTA_IPV4,
+ sizeof(struct nfct_attr_grp_ipv4));
+ } else if (nfct_attr_grp_is_set(ct, ATTR_GRP_ORIG_IPV6)) {
+ __build_group(ct, ATTR_GRP_ORIG_IPV6, pld, NTA_IPV6,
+ sizeof(struct nfct_attr_grp_ipv6));
+ }
+
+ __build_u8(ct, ATTR_L4PROTO, pld, NTA_L4PROTO);
+ if (nfct_attr_grp_is_set(ct, ATTR_GRP_ORIG_PORT)) {
+ __build_group(ct, ATTR_GRP_ORIG_PORT, pld, NTA_PORT,
+ sizeof(struct nfct_attr_grp_port));
}
+
+ __build_u32(ct, ATTR_STATUS, pld, NTA_STATUS);
+
+ if (nfct_attr_is_set(ct, ATTR_TCP_STATE))
+ __build_u8(ct, ATTR_TCP_STATE, pld, NTA_STATE);
if (nfct_attr_is_set(ct, ATTR_TIMEOUT))
- __build_u32(ct, pld, ATTR_TIMEOUT);
+ __build_u32(ct, ATTR_TIMEOUT, pld, NTA_TIMEOUT);
if (nfct_attr_is_set(ct, ATTR_MARK))
- __build_u32(ct, pld, ATTR_MARK);
- if (nfct_attr_is_set(ct, ATTR_STATUS))
- __build_u32(ct, pld, ATTR_STATUS);
+ __build_u32(ct, ATTR_MARK, pld, NTA_MARK);
/* setup the master conntrack */
- if (nfct_attr_is_set(ct, ATTR_MASTER_IPV4_SRC))
- __build_u32(ct, pld, ATTR_MASTER_IPV4_SRC);
- if (nfct_attr_is_set(ct, ATTR_MASTER_IPV4_DST))
- __build_u32(ct, pld, ATTR_MASTER_IPV4_DST);
- if (nfct_attr_is_set(ct, ATTR_MASTER_L3PROTO))
- __build_u8(ct, pld, ATTR_MASTER_L3PROTO);
- if (nfct_attr_is_set(ct, ATTR_MASTER_PORT_SRC))
- __build_u16(ct, pld, ATTR_MASTER_PORT_SRC);
- if (nfct_attr_is_set(ct, ATTR_MASTER_PORT_DST))
- __build_u16(ct, pld, ATTR_MASTER_PORT_DST);
- if (nfct_attr_is_set(ct, ATTR_MASTER_L4PROTO))
- __build_u8(ct, pld, ATTR_MASTER_L4PROTO);
+ if (nfct_attr_grp_is_set(ct, ATTR_GRP_MASTER_IPV4)) {
+ __build_group(ct, ATTR_GRP_MASTER_IPV4, pld, NTA_MASTER_IPV4,
+ sizeof(struct nfct_attr_grp_ipv4));
+ __build_u8(ct, ATTR_MASTER_L4PROTO, pld, NTA_MASTER_L4PROTO);
+ if (nfct_attr_grp_is_set(ct, ATTR_GRP_MASTER_PORT)) {
+ __build_group(ct, ATTR_GRP_MASTER_PORT,
+ pld, NTA_MASTER_PORT,
+ sizeof(struct nfct_attr_grp_port));
+ }
+ } else if (nfct_attr_grp_is_set(ct, ATTR_GRP_MASTER_IPV6)) {
+ __build_group(ct, ATTR_GRP_MASTER_IPV6, pld, NTA_MASTER_IPV6,
+ sizeof(struct nfct_attr_grp_ipv6));
+ __build_u8(ct, ATTR_MASTER_L4PROTO, pld, NTA_MASTER_L4PROTO);
+ if (nfct_attr_grp_is_set(ct, ATTR_GRP_MASTER_PORT)) {
+ __build_group(ct, ATTR_GRP_MASTER_PORT,
+ pld, NTA_MASTER_PORT,
+ sizeof(struct nfct_attr_grp_port));
+ }
+ }
/* NAT */
- if (nfct_getobjopt(ct, NFCT_GOPT_IS_SNAT)) {
- uint32_t data = nfct_get_attr_u32(ct, ATTR_REPL_IPV4_DST);
- __nat_build_u32(data, pld, ATTR_SNAT_IPV4);
- }
- if (nfct_getobjopt(ct, NFCT_GOPT_IS_DNAT)) {
- uint32_t data = nfct_get_attr_u32(ct, ATTR_REPL_IPV4_SRC);
- __nat_build_u32(data, pld, ATTR_DNAT_IPV4);
- }
- if (nfct_getobjopt(ct, NFCT_GOPT_IS_SPAT)) {
- uint16_t data = nfct_get_attr_u16(ct, ATTR_REPL_PORT_DST);
- __nat_build_u16(data, pld, ATTR_SNAT_PORT);
- }
- if (nfct_getobjopt(ct, NFCT_GOPT_IS_DPAT)) {
- uint16_t data = nfct_get_attr_u16(ct, ATTR_REPL_PORT_SRC);
- __nat_build_u16(data, pld, ATTR_DNAT_PORT);
- }
+ if (nfct_getobjopt(ct, NFCT_GOPT_IS_SNAT))
+ __build_u32(ct, ATTR_REPL_IPV4_DST, pld, NTA_SNAT_IPV4);
+ if (nfct_getobjopt(ct, NFCT_GOPT_IS_DNAT))
+ __build_u32(ct, ATTR_REPL_IPV4_SRC, pld, NTA_DNAT_IPV4);
+ if (nfct_getobjopt(ct, NFCT_GOPT_IS_SPAT))
+ __build_u16(ct, ATTR_REPL_PORT_DST, pld, NTA_SPAT_PORT);
+ if (nfct_getobjopt(ct, NFCT_GOPT_IS_DPAT))
+ __build_u16(ct, ATTR_REPL_PORT_SRC, pld, NTA_DPAT_PORT);
/* NAT sequence adjustment */
- if (nfct_attr_is_set(ct, ATTR_ORIG_NAT_SEQ_CORRECTION_POS))
- __build_u32(ct, pld, ATTR_ORIG_NAT_SEQ_CORRECTION_POS);
- if (nfct_attr_is_set(ct, ATTR_ORIG_NAT_SEQ_OFFSET_BEFORE))
- __build_u32(ct, pld, ATTR_ORIG_NAT_SEQ_OFFSET_BEFORE);
- if (nfct_attr_is_set(ct, ATTR_ORIG_NAT_SEQ_OFFSET_AFTER))
- __build_u32(ct, pld, ATTR_ORIG_NAT_SEQ_OFFSET_AFTER);
- if (nfct_attr_is_set(ct, ATTR_REPL_NAT_SEQ_CORRECTION_POS))
- __build_u32(ct, pld, ATTR_REPL_NAT_SEQ_CORRECTION_POS);
- if (nfct_attr_is_set(ct, ATTR_REPL_NAT_SEQ_OFFSET_BEFORE))
- __build_u32(ct, pld, ATTR_REPL_NAT_SEQ_OFFSET_BEFORE);
- if (nfct_attr_is_set(ct, ATTR_REPL_NAT_SEQ_OFFSET_AFTER))
- __build_u32(ct, pld, ATTR_REPL_NAT_SEQ_OFFSET_AFTER);
+ if (nfct_attr_is_set_array(ct, nat_type, 6))
+ __build_natseqadj(ct, pld);
pld->query = query;