void __build_filter_dump(struct nfnlhdr *req, size_t size, const struct nfct_filter_dump *filter_dump) { if (filter_dump->set & (1 << NFCT_FILTER_DUMP_MARK)) { nfnl_addattr32(&req->nlh, size, CTA_MARK, htonl(filter_dump->mark.val)); nfnl_addattr32(&req->nlh, size, CTA_MARK_MASK, htonl(filter_dump->mark.mask)); } if (filter_dump->set & (1 << NFCT_FILTER_DUMP_L3NUM)) { struct nfgenmsg *nfg = NLMSG_DATA(&req->nlh); nfg->nfgen_family = filter_dump->l3num; } }
void __build_status(struct nfnlhdr *req, size_t size, const struct nf_conntrack *ct) { nfnl_addattr32(&req->nlh, size, CTA_STATUS, htonl(ct->status | IPS_CONFIRMED)); }
static inline void __nat_seq_adj(struct nfnlhdr *req, size_t size, const struct nf_conntrack *ct, int dir) { nfnl_addattr32(&req->nlh, size, CTA_NAT_SEQ_CORRECTION_POS, htonl(ct->tuple[dir].natseq.correction_pos)); nfnl_addattr32(&req->nlh, size, CTA_NAT_SEQ_OFFSET_BEFORE, htonl(ct->tuple[dir].natseq.offset_before)); nfnl_addattr32(&req->nlh, size, CTA_NAT_SEQ_OFFSET_AFTER, htonl(ct->tuple[dir].natseq.offset_after)); }
int nflog_set_qthresh(struct nflog_g_handle *gh, u_int32_t qthresh) { char buf[NFNL_HEADER_LEN+NFA_LENGTH(sizeof(u_int32_t))]; struct nlmsghdr *nmh = (struct nlmsghdr *) buf; nfnl_fill_hdr(gh->h->nfnlssh, nmh, 0, AF_UNSPEC, gh->id, NFULNL_MSG_CONFIG, NLM_F_REQUEST|NLM_F_ACK); nfnl_addattr32(nmh, sizeof(buf), NFULA_CFG_QTHRESH, htonl(qthresh)); return nfnl_talk(gh->h->nfnlh, nmh, 0, 0, NULL, NULL, NULL); }
/** * nflog_set_qthresh - set the maximum amount of logs in buffer for this group * \param gh Netfilter log handle obtained by call to nflog_bind_group(). * \param qthresh Maximum number of log entries * * This function determines the maximum number of log entries in the buffer * until it is pushed to userspace. * * \return -1 in case of error and errno is explicity set. */ int nflog_set_qthresh(struct nflog_g_handle *gh, uint32_t qthresh) { union { char buf[NFNL_HEADER_LEN+NFA_LENGTH(sizeof(uint32_t))]; struct nlmsghdr nmh; } u; nfnl_fill_hdr(gh->h->nfnlssh, &u.nmh, 0, AF_UNSPEC, gh->id, NFULNL_MSG_CONFIG, NLM_F_REQUEST|NLM_F_ACK); nfnl_addattr32(&u.nmh, sizeof(u), NFULA_CFG_QTHRESH, htonl(qthresh)); return nfnl_query(gh->h->nfnlh, &u.nmh); }
int nflog_set_nlbufsiz(struct nflog_g_handle *gh, u_int32_t nlbufsiz) { char buf[NFNL_HEADER_LEN+NFA_LENGTH(sizeof(u_int32_t))]; struct nlmsghdr *nmh = (struct nlmsghdr *) buf; int status; nfnl_fill_hdr(gh->h->nfnlssh, nmh, 0, AF_UNSPEC, gh->id, NFULNL_MSG_CONFIG, NLM_F_REQUEST|NLM_F_ACK); nfnl_addattr32(nmh, sizeof(buf), NFULA_CFG_NLBUFSIZ, htonl(nlbufsiz)); status = nfnl_talk(gh->h->nfnlh, nmh, 0, 0, NULL, NULL, NULL); /* we try to have space for at least 10 messages in the socket buffer */ if (status >= 0) nfnl_rcvbufsiz(gh->h->nfnlh, 10*nlbufsiz); return status; }
static void __build_flags(struct nfnlhdr *req, size_t size, const struct nf_expect *exp) { nfnl_addattr32(&req->nlh, size, CTA_EXPECT_FLAGS,htonl(exp->flags)); }
static void __build_timeout(struct nfnlhdr *req, size_t size, const struct nf_expect *exp) { nfnl_addattr32(&req->nlh, size, CTA_EXPECT_TIMEOUT,htonl(exp->timeout)); }
void __build_secmark(struct nfnlhdr *req, size_t size, const struct nf_conntrack *ct) { nfnl_addattr32(&req->nlh, size, CTA_SECMARK, htonl(ct->secmark)); }
void __build_timeout(struct nfnlhdr *req, size_t size, const struct nf_conntrack *ct) { nfnl_addattr32(&req->nlh, size, CTA_TIMEOUT, htonl(ct->timeout)); }
static void __build_protoinfo(struct nfnlhdr *req, size_t size, const struct nf_conntrack *ct) { struct nfattr *nest, *nest_proto; switch(ct->tuple[__DIR_ORIG].protonum) { case IPPROTO_TCP: nest = nfnl_nest(&req->nlh, size, CTA_PROTOINFO); nest_proto = nfnl_nest(&req->nlh, size, CTA_PROTOINFO_TCP); if (test_bit(ATTR_TCP_STATE, ct->set)) nfnl_addattr_l(&req->nlh, size, CTA_PROTOINFO_TCP_STATE, &ct->protoinfo.tcp.state, sizeof(u_int8_t)); if (test_bit(ATTR_TCP_FLAGS_ORIG, ct->set) && test_bit(ATTR_TCP_MASK_ORIG, ct->set)) nfnl_addattr_l(&req->nlh, size, CTA_PROTOINFO_TCP_FLAGS_ORIGINAL, &ct->protoinfo.tcp.flags[0], sizeof(u_int16_t)); if (test_bit(ATTR_TCP_FLAGS_REPL, ct->set) && test_bit(ATTR_TCP_MASK_REPL, ct->set)) nfnl_addattr_l(&req->nlh, size, CTA_PROTOINFO_TCP_FLAGS_REPLY, &ct->protoinfo.tcp.flags[1], sizeof(u_int16_t)); nfnl_nest_end(&req->nlh, nest_proto); nfnl_nest_end(&req->nlh, nest); break; case IPPROTO_SCTP: nest = nfnl_nest(&req->nlh, size, CTA_PROTOINFO); nest_proto = nfnl_nest(&req->nlh, size, CTA_PROTOINFO_SCTP); if (test_bit(ATTR_SCTP_STATE, ct->set)) nfnl_addattr_l(&req->nlh, size, CTA_PROTOINFO_SCTP_STATE, &ct->protoinfo.sctp.state, sizeof(u_int8_t)); if (test_bit(ATTR_SCTP_VTAG_ORIG, ct->set)) nfnl_addattr32(&req->nlh, size, CTA_PROTOINFO_SCTP_VTAG_ORIGINAL, htonl(ct->protoinfo.sctp.vtag[__DIR_ORIG])); if (test_bit(ATTR_SCTP_VTAG_REPL, ct->set)) nfnl_addattr32(&req->nlh, size, CTA_PROTOINFO_SCTP_VTAG_REPLY, htonl(ct->protoinfo.sctp.vtag[__DIR_REPL])); nfnl_nest_end(&req->nlh, nest_proto); nfnl_nest_end(&req->nlh, nest); break; case IPPROTO_DCCP: nest = nfnl_nest(&req->nlh, size, CTA_PROTOINFO); nest_proto = nfnl_nest(&req->nlh, size, CTA_PROTOINFO_DCCP); if (test_bit(ATTR_DCCP_STATE, ct->set)) nfnl_addattr_l(&req->nlh, size, CTA_PROTOINFO_DCCP_STATE, &ct->protoinfo.dccp.state, sizeof(u_int8_t)); if (test_bit(ATTR_DCCP_ROLE, ct->set)) nfnl_addattr_l(&req->nlh, size, CTA_PROTOINFO_DCCP_ROLE, &ct->protoinfo.dccp.role, sizeof(u_int8_t)); if (test_bit(ATTR_DCCP_HANDSHAKE_SEQ, ct->set)) { /* FIXME: use __cpu_to_be64() instead which is the * correct operation. This is a semantic abuse but * we have no function to do it in libnfnetlink. */ u_int64_t handshake_seq = __be64_to_cpu(ct->protoinfo.dccp.handshake_seq); nfnl_addattr_l(&req->nlh, size, CTA_PROTOINFO_DCCP_SEQ, &handshake_seq, sizeof(u_int64_t)); } nfnl_nest_end(&req->nlh, nest_proto); nfnl_nest_end(&req->nlh, nest); default: break; } }
static void __build_protoinfo(struct nfnlhdr *req, size_t size, const struct nf_conntrack *ct) { struct nfattr *nest, *nest_proto; switch(ct->head.orig.protonum) { case IPPROTO_TCP: /* Preliminary attribute check to avoid sending an empty * CTA_PROTOINFO_TCP nest, which results in EINVAL in * Linux kernel <= 2.6.25. */ if (!(test_bit(ATTR_TCP_STATE, ct->head.set) || test_bit(ATTR_TCP_FLAGS_ORIG, ct->head.set) || test_bit(ATTR_TCP_FLAGS_REPL, ct->head.set) || test_bit(ATTR_TCP_MASK_ORIG, ct->head.set) || test_bit(ATTR_TCP_MASK_REPL, ct->head.set) || test_bit(ATTR_TCP_WSCALE_ORIG, ct->head.set) || test_bit(ATTR_TCP_WSCALE_REPL, ct->head.set))) { break; } nest = nfnl_nest(&req->nlh, size, CTA_PROTOINFO); nest_proto = nfnl_nest(&req->nlh, size, CTA_PROTOINFO_TCP); if (test_bit(ATTR_TCP_STATE, ct->head.set)) nfnl_addattr_l(&req->nlh, size, CTA_PROTOINFO_TCP_STATE, &ct->protoinfo.tcp.state, sizeof(u_int8_t)); if (test_bit(ATTR_TCP_FLAGS_ORIG, ct->head.set) && test_bit(ATTR_TCP_MASK_ORIG, ct->head.set)) nfnl_addattr_l(&req->nlh, size, CTA_PROTOINFO_TCP_FLAGS_ORIGINAL, &ct->protoinfo.tcp.flags[0], sizeof(struct nf_ct_tcp_flags)); if (test_bit(ATTR_TCP_FLAGS_REPL, ct->head.set) && test_bit(ATTR_TCP_MASK_REPL, ct->head.set)) nfnl_addattr_l(&req->nlh, size, CTA_PROTOINFO_TCP_FLAGS_REPLY, &ct->protoinfo.tcp.flags[1], sizeof(struct nf_ct_tcp_flags)); if (test_bit(ATTR_TCP_WSCALE_ORIG, ct->head.set)) nfnl_addattr_l(&req->nlh, size, CTA_PROTOINFO_TCP_WSCALE_ORIGINAL, &ct->protoinfo.tcp.wscale[__DIR_ORIG], sizeof(u_int8_t)); if (test_bit(ATTR_TCP_WSCALE_REPL, ct->head.set)) nfnl_addattr_l(&req->nlh, size, CTA_PROTOINFO_TCP_WSCALE_REPLY, &ct->protoinfo.tcp.wscale[__DIR_REPL], sizeof(u_int8_t)); nfnl_nest_end(&req->nlh, nest_proto); nfnl_nest_end(&req->nlh, nest); break; case IPPROTO_SCTP: /* See comment above on TCP. */ if (!(test_bit(ATTR_SCTP_STATE, ct->head.set) || test_bit(ATTR_SCTP_VTAG_ORIG, ct->head.set) || test_bit(ATTR_SCTP_VTAG_REPL, ct->head.set))) { break; } nest = nfnl_nest(&req->nlh, size, CTA_PROTOINFO); nest_proto = nfnl_nest(&req->nlh, size, CTA_PROTOINFO_SCTP); if (test_bit(ATTR_SCTP_STATE, ct->head.set)) nfnl_addattr_l(&req->nlh, size, CTA_PROTOINFO_SCTP_STATE, &ct->protoinfo.sctp.state, sizeof(u_int8_t)); if (test_bit(ATTR_SCTP_VTAG_ORIG, ct->head.set)) nfnl_addattr32(&req->nlh, size, CTA_PROTOINFO_SCTP_VTAG_ORIGINAL, htonl(ct->protoinfo.sctp.vtag[__DIR_ORIG])); if (test_bit(ATTR_SCTP_VTAG_REPL, ct->head.set)) nfnl_addattr32(&req->nlh, size, CTA_PROTOINFO_SCTP_VTAG_REPLY, htonl(ct->protoinfo.sctp.vtag[__DIR_REPL])); nfnl_nest_end(&req->nlh, nest_proto); nfnl_nest_end(&req->nlh, nest); break; case IPPROTO_DCCP: /* See comment above on TCP. */ if (!(test_bit(ATTR_DCCP_STATE, ct->head.set) || test_bit(ATTR_DCCP_ROLE, ct->head.set) || test_bit(ATTR_DCCP_HANDSHAKE_SEQ, ct->head.set))) { break; } nest = nfnl_nest(&req->nlh, size, CTA_PROTOINFO); nest_proto = nfnl_nest(&req->nlh, size, CTA_PROTOINFO_DCCP); if (test_bit(ATTR_DCCP_STATE, ct->head.set)) nfnl_addattr_l(&req->nlh, size, CTA_PROTOINFO_DCCP_STATE, &ct->protoinfo.dccp.state, sizeof(u_int8_t)); if (test_bit(ATTR_DCCP_ROLE, ct->head.set)) nfnl_addattr_l(&req->nlh, size, CTA_PROTOINFO_DCCP_ROLE, &ct->protoinfo.dccp.role, sizeof(u_int8_t)); if (test_bit(ATTR_DCCP_HANDSHAKE_SEQ, ct->head.set)) { /* FIXME: use __cpu_to_be64() instead which is the * correct operation. This is a semantic abuse but * we have no function to do it in libnfnetlink. */ u_int64_t handshake_seq = __be64_to_cpu(ct->protoinfo.dccp.handshake_seq); nfnl_addattr_l(&req->nlh, size, CTA_PROTOINFO_DCCP_HANDSHAKE_SEQ, &handshake_seq, sizeof(u_int64_t)); } nfnl_nest_end(&req->nlh, nest_proto); nfnl_nest_end(&req->nlh, nest); default: break; } }