16 #include <arpa/inet.h>   
   18 #include <libmnl/libmnl.h> 
   19 #include <linux/netfilter/nfnetlink.h> 
   20 #include <linux/netfilter/nfnetlink_cthelper.h> 
   22 #include <libnetfilter_cthelper/libnetfilter_cthelper.h> 
   60 #ifndef NF_CT_HELPER_NAME_MAX 
   61 #define NF_CT_HELPER_NAME_MAX 16 
   64 #ifndef NF_CT_HELPER_CLASS_MAX 
   65 #define NF_CT_HELPER_CLASS_MAX 4 
   69         char            name[NF_CT_HELPER_NAME_MAX];
 
   70         uint32_t        expect_timeout;
 
   76         char            name[NF_CT_HELPER_NAME_MAX];
 
   77         uint32_t        priv_data_len;
 
  116         for (i=0; i<NF_CT_HELPER_CLASS_MAX; i++) {
 
  117                 if (h->expect_policy[i])
 
  118                         free(h->expect_policy[i]);
 
  154                             enum nfct_helper_policy_attr_type type,
 
  158         case NFCTH_ATTR_POLICY_NAME:
 
  159                 strncpy(p->name, data, NF_CT_HELPER_NAME_MAX);
 
  160                 p->name[NF_CT_HELPER_NAME_MAX-1] = 
'\0';
 
  161                 p->bitset |= (1 << NFCTH_ATTR_POLICY_NAME);
 
  163         case NFCTH_ATTR_POLICY_TIMEOUT:
 
  164                 p->expect_timeout = *((uint32_t *) data);
 
  165                 p->bitset |= (1 << NFCTH_ATTR_POLICY_TIMEOUT);
 
  167         case NFCTH_ATTR_POLICY_MAX:
 
  168                 p->expect_max = *((uint32_t *) data);
 
  169                 p->bitset |= (1 << NFCTH_ATTR_POLICY_MAX);
 
  183                                 enum nfct_helper_policy_attr_type type,
 
  192                                 enum nfct_helper_policy_attr_type type,
 
  197 EXPORT_SYMBOL(nfct_helper_policy_attr_set_u32);
 
  207                      enum nfct_helper_attr_type type, 
const void *data)
 
  210         case NFCTH_ATTR_NAME:
 
  211                 strncpy(h->name, data, NF_CT_HELPER_NAME_MAX);
 
  212                 h->name[NF_CT_HELPER_NAME_MAX-1] = 
'\0';
 
  213                 h->bitset |= (1 << NFCTH_ATTR_NAME);
 
  215         case NFCTH_ATTR_QUEUE_NUM:
 
  216                 h->queue_num = *((uint32_t *) data);
 
  217                 h->bitset |= (1 << NFCTH_ATTR_QUEUE_NUM);
 
  219         case NFCTH_ATTR_PROTO_L3NUM:
 
  220                 h->tuple.l3num = *((uint16_t *) data);
 
  221                 h->bitset |= (1 << NFCTH_ATTR_PROTO_L3NUM);
 
  223         case NFCTH_ATTR_PROTO_L4NUM:
 
  224                 h->tuple.l4num = *((uint8_t *) data);
 
  225                 h->bitset |= (1 << NFCTH_ATTR_PROTO_L4NUM);
 
  227         case NFCTH_ATTR_PRIV_DATA_LEN:
 
  228                 h->priv_data_len = *((uint32_t *) data);
 
  229                 h->bitset |= (1 << NFCTH_ATTR_PRIV_DATA_LEN);
 
  231         case NFCTH_ATTR_POLICY1:
 
  233                 h->bitset |= (1 << NFCTH_ATTR_POLICY1);
 
  235         case NFCTH_ATTR_POLICY2:
 
  237                 h->bitset |= (1 << NFCTH_ATTR_POLICY2);
 
  239         case NFCTH_ATTR_POLICY3:
 
  241                 h->bitset |= (1 << NFCTH_ATTR_POLICY3);
 
  243         case NFCTH_ATTR_POLICY4:
 
  245                 h->bitset |= (1 << NFCTH_ATTR_POLICY4);
 
  247         case NFCTH_ATTR_STATUS:
 
  248                 h->status = *((uint32_t *) data);
 
  249                 h->bitset |= (1 << NFCTH_ATTR_STATUS);
 
  271                          enum nfct_helper_attr_type type, uint8_t value)
 
  275 EXPORT_SYMBOL(nfct_helper_attr_set_u8);
 
  279                          enum nfct_helper_attr_type type, uint16_t value)
 
  283 EXPORT_SYMBOL(nfct_helper_attr_set_u16);
 
  287                          enum nfct_helper_attr_type type, uint32_t value)
 
  291 EXPORT_SYMBOL(nfct_helper_attr_set_u32);
 
  302         case NFCTH_ATTR_NAME:
 
  303                 nfct_helper->bitset &= ~(1 << NFCTH_ATTR_NAME);
 
  321                                  enum nfct_helper_attr_type type)
 
  323         const void *ret = NULL;
 
  326         case NFCTH_ATTR_NAME:
 
  329         case NFCTH_ATTR_QUEUE_NUM:
 
  330                 ret = &helper->queue_num;
 
  332         case NFCTH_ATTR_PROTO_L3NUM:
 
  333                 ret = &helper->tuple.l3num;
 
  335         case NFCTH_ATTR_PROTO_L4NUM:
 
  336                 ret = &helper->tuple.l4num;
 
  338         case NFCTH_ATTR_PRIV_DATA_LEN:
 
  339                 ret = &helper->priv_data_len;
 
  341         case NFCTH_ATTR_POLICY1:
 
  342                 ret = helper->expect_policy[0];
 
  344         case NFCTH_ATTR_POLICY2:
 
  345                 ret = helper->expect_policy[1];
 
  347         case NFCTH_ATTR_POLICY3:
 
  348                 ret = helper->expect_policy[2];
 
  350         case NFCTH_ATTR_POLICY4:
 
  351                 ret = helper->expect_policy[3];
 
  353         case NFCTH_ATTR_STATUS:
 
  354                 ret = &helper->status;
 
  373                          enum nfct_helper_attr_type type)
 
  388                                   enum nfct_helper_attr_type type)
 
  403                                   enum nfct_helper_attr_type type)
 
  418                                   enum nfct_helper_attr_type type)
 
  436                          unsigned int type, 
unsigned int flags)
 
  440         ret = snprintf(buf, size, 
"{\n" 
  442                                   "\t.queuenum = %u,\n" 
  443                                   "\t.l3protonum = %u,\n" 
  444                                   "\t.l4protonum = %u,\n" 
  445                                   "\t.priv_data_len = %u,\n" 
  446                                   "\t.status = %s,\n};",
 
  453                         "enabled" : 
"disabled");
 
  495                             uint16_t flags, uint32_t seq)
 
  497         struct nlmsghdr *nlh;
 
  498         struct nfgenmsg *nfh;
 
  500         nlh = mnl_nlmsg_put_header(buf);
 
  501         nlh->nlmsg_type = (NFNL_SUBSYS_CTHELPER << 8) | cmd;
 
  502         nlh->nlmsg_flags = NLM_F_REQUEST | flags;
 
  503         nlh->nlmsg_seq = seq;
 
  505         nfh = mnl_nlmsg_put_extra_header(nlh, 
sizeof(
struct nfgenmsg));
 
  506         nfh->nfgen_family = AF_UNSPEC;
 
  507         nfh->version = NFNETLINK_V0;
 
  515 nfct_helper_nlmsg_build_policy(
struct nlmsghdr *nlh,
 
  520         nest = mnl_attr_nest_start(nlh, NFCTH_POLICY_SET);
 
  521         mnl_attr_put_strz(nlh, NFCTH_POLICY_NAME, p->name);
 
  522         mnl_attr_put_u32(nlh, NFCTH_POLICY_EXPECT_MAX, htonl(p->expect_max));
 
  523         mnl_attr_put_u32(nlh, NFCTH_POLICY_EXPECT_TIMEOUT,
 
  524                         htonl(p->expect_timeout));
 
  525         mnl_attr_nest_end(nlh, nest);
 
  539         if (h->bitset & (1 << NFCTH_ATTR_NAME))
 
  540                 mnl_attr_put_strz(nlh, NFCTH_NAME, h->name);
 
  542         if (h->bitset & (1 << NFCTH_ATTR_QUEUE_NUM))
 
  543                 mnl_attr_put_u32(nlh, NFCTH_QUEUE_NUM, htonl(h->queue_num));
 
  545         if (h->bitset & (1 << NFCTH_ATTR_PRIV_DATA_LEN)) {
 
  546                 mnl_attr_put_u32(nlh, NFCTH_PRIV_DATA_LEN,
 
  547                                         htonl(h->priv_data_len));
 
  550         if (h->bitset & (1 << NFCTH_ATTR_PROTO_L3NUM) ||
 
  551             h->bitset & (1 << NFCTH_ATTR_PROTO_L4NUM)) {
 
  552                 nest = mnl_attr_nest_start(nlh, NFCTH_TUPLE);
 
  553                 mnl_attr_put_u16(nlh, NFCTH_TUPLE_L3PROTONUM,
 
  554                                         htons(h->tuple.l3num));
 
  555                 mnl_attr_put_u8(nlh, NFCTH_TUPLE_L4PROTONUM, h->tuple.l4num);
 
  556                 mnl_attr_nest_end(nlh, nest);
 
  559         if (h->bitset & (1 << NFCTH_ATTR_POLICY1) ||
 
  560             h->bitset & (1 << NFCTH_ATTR_POLICY2) ||
 
  561             h->bitset & (1 << NFCTH_ATTR_POLICY3) ||
 
  562             h->bitset & (1 << NFCTH_ATTR_POLICY4)) {
 
  563                 nest = mnl_attr_nest_start(nlh, NFCTH_POLICY);
 
  564                 int policy_set_num = 0;
 
  566                 if (h->bitset & (1 << NFCTH_ATTR_POLICY1)) {
 
  567                         nfct_helper_nlmsg_build_policy(nlh,
 
  568                                                         h->expect_policy[0]);
 
  571                 if (h->bitset & (1 << NFCTH_ATTR_POLICY2)) {
 
  572                         nfct_helper_nlmsg_build_policy(nlh,
 
  573                                                         h->expect_policy[1]);
 
  576                 if (h->bitset & (1 << NFCTH_ATTR_POLICY3)) {
 
  577                         nfct_helper_nlmsg_build_policy(nlh,
 
  578                                                         h->expect_policy[2]);
 
  581                 if (h->bitset & (1 << NFCTH_ATTR_POLICY4)) {
 
  582                         nfct_helper_nlmsg_build_policy(nlh,
 
  583                                                         h->expect_policy[3]);
 
  587                 mnl_attr_put_u32(nlh, NFCTH_POLICY_SET_NUM,
 
  588                                         htonl(policy_set_num));
 
  590                 mnl_attr_nest_end(nlh, nest);
 
  593         if (h->bitset & (1 << NFCTH_ATTR_STATUS))
 
  594                 mnl_attr_put_u32(nlh, NFCTH_STATUS, ntohl(h->status));
 
  599 nfct_helper_nlmsg_parse_tuple_cb(
const struct nlattr *attr, 
void *data)
 
  601         const struct nlattr **tb = data;
 
  602         int type = mnl_attr_get_type(attr);
 
  604         if (mnl_attr_type_valid(attr, NFCTH_TUPLE_MAX) < 0)
 
  608         case NFCTH_TUPLE_L3PROTONUM:
 
  609                 if (mnl_attr_validate(attr, MNL_TYPE_U16) < 0) {
 
  610                         perror(
"mnl_attr_validate");
 
  614         case NFCTH_TUPLE_L4PROTONUM:
 
  615                 if (mnl_attr_validate(attr, MNL_TYPE_U8) < 0) {
 
  616                         perror(
"mnl_attr_validate");
 
  628 nfct_helper_nlmsg_parse_tuple(
const struct nlattr *attr,
 
  631         struct nlattr *tb[NFCTH_TUPLE_MAX+1] = {};
 
  633         mnl_attr_parse_nested(attr, nfct_helper_nlmsg_parse_tuple_cb, tb);
 
  634         if (tb[NFCTH_TUPLE_L3PROTONUM]) {
 
  635                 nfct_helper_attr_set_u16(helper, NFCTH_ATTR_PROTO_L3NUM,
 
  636                         ntohs(mnl_attr_get_u16(tb[NFCTH_TUPLE_L3PROTONUM])));
 
  638         if (tb[NFCTH_TUPLE_L4PROTONUM]) {
 
  639                 nfct_helper_attr_set_u8(helper, NFCTH_ATTR_PROTO_L4NUM,
 
  640                         mnl_attr_get_u8(tb[NFCTH_TUPLE_L4PROTONUM]));
 
  645 nfct_helper_nlmsg_parse_policy_cb(
const struct nlattr *attr, 
void *data)
 
  647         const struct nlattr **tb = data;
 
  648         int type = mnl_attr_get_type(attr);
 
  650         if (mnl_attr_type_valid(attr, NFCTH_POLICY_MAX) < 0)
 
  654         case NFCTH_POLICY_NAME:
 
  655                 if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0) {
 
  656                         perror(
"mnl_attr_validate");
 
  660         case NFCTH_POLICY_EXPECT_MAX:
 
  661                 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
 
  662                         perror(
"mnl_attr_validate");
 
  666         case NFCTH_POLICY_EXPECT_TIMEOUT:
 
  667                 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
 
  668                         perror(
"mnl_attr_validate");
 
  680 nfct_helper_nlmsg_parse_policy_set_cb(
const struct nlattr *attr, 
void *data)
 
  682         const struct nlattr **tb = data;
 
  683         int type = mnl_attr_get_type(attr);
 
  685         if (mnl_attr_type_valid(attr, NFCTH_POLICY_SET_MAX) < 0)
 
  689         case NFCTH_POLICY_SET_NUM:
 
  690                 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
 
  691                         perror(
"mnl_attr_validate");
 
  704 nfct_helper_nlmsg_parse_policy(
const struct nlattr *attr,
 
  707         struct nlattr *tb[NFCTH_POLICY_MAX+1] = {};
 
  714         mnl_attr_parse_nested(attr, nfct_helper_nlmsg_parse_policy_cb, tb);
 
  715         if (tb[NFCTH_POLICY_NAME]) {
 
  717                         mnl_attr_get_str(tb[NFCTH_POLICY_NAME]));
 
  719         if (tb[NFCTH_POLICY_EXPECT_MAX]) {
 
  720                 nfct_helper_policy_attr_set_u32(p, NFCTH_ATTR_POLICY_MAX,
 
  721                         ntohl(mnl_attr_get_u32(tb[NFCTH_POLICY_EXPECT_MAX])));
 
  723         if (tb[NFCTH_POLICY_EXPECT_TIMEOUT]) {
 
  724                 nfct_helper_policy_attr_set_u32(p, NFCTH_ATTR_POLICY_TIMEOUT,
 
  725                         ntohl(mnl_attr_get_u32(tb[NFCTH_POLICY_EXPECT_TIMEOUT])));
 
  728         helper->expect_policy[helper->policy_num++] = p;
 
  732 nfct_helper_nlmsg_parse_policy_set(
const struct nlattr *attr,
 
  735         struct nlattr *tb[NFCTH_POLICY_SET_MAX+1] = {};
 
  738         mnl_attr_parse_nested(attr, nfct_helper_nlmsg_parse_policy_set_cb, tb);
 
  739         if (tb[NFCTH_POLICY_SET_NUM]) {
 
  741                         ntohl(mnl_attr_get_u32(tb[NFCTH_POLICY_SET_NUM]));
 
  743         for (i=0; i<helper->policy_num; i++) {
 
  744                 if (tb[NFCTH_POLICY_SET+i]) {
 
  745                         nfct_helper_nlmsg_parse_policy(tb[NFCTH_POLICY_SET+i],
 
  752 nfct_helper_nlmsg_parse_attr_cb(
const struct nlattr *attr, 
void *data)
 
  754         const struct nlattr **tb = data;
 
  755         int type = mnl_attr_get_type(attr);
 
  757         if (mnl_attr_type_valid(attr, NFCTH_MAX) < 0)
 
  762                 if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0) {
 
  763                         perror(
"mnl_attr_validate");
 
  767         case NFCTH_QUEUE_NUM:
 
  768                 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
 
  769                         perror(
"mnl_attr_validate");
 
  774                 if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0) {
 
  775                         perror(
"mnl_attr_validate");
 
  780                 if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0) {
 
  781                         perror(
"mnl_attr_validate");
 
  802         struct nlattr *tb[NFCTH_MAX+1] = {};
 
  803         struct nfgenmsg *nfg = mnl_nlmsg_get_payload(nlh);
 
  805         mnl_attr_parse(nlh, 
sizeof(*nfg), nfct_helper_nlmsg_parse_attr_cb, tb);
 
  806         if (!tb[NFCTH_NAME] || !tb[NFCTH_QUEUE_NUM] ||
 
  807             !tb[NFCTH_TUPLE] || !tb[NFCTH_POLICY] || !tb[NFCTH_STATUS])
 
  810         if (tb[NFCTH_NAME]) {
 
  812                                  mnl_attr_get_str(tb[NFCTH_NAME]));
 
  814         if (tb[NFCTH_ATTR_QUEUE_NUM]) {
 
  815                 nfct_helper_attr_set_u32(h, NFCTH_ATTR_QUEUE_NUM,
 
  816                                  ntohl(mnl_attr_get_u32(tb[NFCTH_QUEUE_NUM])));
 
  819                 nfct_helper_nlmsg_parse_tuple(tb[NFCTH_TUPLE], h);
 
  821         if (tb[NFCTH_POLICY])
 
  822                 nfct_helper_nlmsg_parse_policy_set(tb[NFCTH_POLICY], h);
 
  824         if (tb[NFCTH_PRIV_DATA_LEN]) {
 
  825                 nfct_helper_attr_set_u32(h, NFCTH_ATTR_PRIV_DATA_LEN,
 
  826                         ntohl(mnl_attr_get_u32(tb[NFCTH_PRIV_DATA_LEN])));
 
  829         if (tb[NFCTH_STATUS]) {
 
  830                 nfct_helper_attr_set_u32(h, NFCTH_ATTR_STATUS,
 
  831                                  ntohl(mnl_attr_get_u32(tb[NFCTH_STATUS])));
 
int nfct_helper_nlmsg_parse_payload(const struct nlmsghdr *nlh, struct nfct_helper *h)
void nfct_helper_attr_set_str(struct nfct_helper *nfct_helper, enum nfct_helper_attr_type type, const char *name)
void nfct_helper_policy_attr_set(struct nfct_helper_policy *p, enum nfct_helper_policy_attr_type type, const void *data)
struct nfct_helper * nfct_helper_alloc(void)
void nfct_helper_policy_free(struct nfct_helper_policy *p)
struct nfct_helper_policy * nfct_helper_policy_alloc(void)
const void * nfct_helper_attr_get(struct nfct_helper *helper, enum nfct_helper_attr_type type)
uint16_t nfct_helper_attr_get_u16(struct nfct_helper *nfct_helper, enum nfct_helper_attr_type type)
void nfct_helper_nlmsg_build_payload(struct nlmsghdr *nlh, struct nfct_helper *h)
int nfct_helper_snprintf(char *buf, size_t size, struct nfct_helper *helper, unsigned int type, unsigned int flags)
void nfct_helper_policy_attr_set_str(struct nfct_helper_policy *p, enum nfct_helper_policy_attr_type type, const char *name)
uint8_t nfct_helper_attr_get_u8(struct nfct_helper *nfct_helper, enum nfct_helper_attr_type type)
struct nlmsghdr * nfct_helper_nlmsg_build_hdr(char *buf, uint8_t cmd, uint16_t flags, uint32_t seq)
uint32_t nfct_helper_attr_get_u32(struct nfct_helper *nfct_helper, enum nfct_helper_attr_type type)
void nfct_helper_attr_set(struct nfct_helper *h, enum nfct_helper_attr_type type, const void *data)
const char * nfct_helper_attr_get_str(struct nfct_helper *nfct_helper, enum nfct_helper_attr_type type)
void nfct_helper_free(struct nfct_helper *h)
void nfct_helper_attr_unset(struct nfct_helper *nfct_helper, enum nfct_helper_attr_type type)