libnetfilter_conntrack  1.0.8
callback.c
1 /*
2  * (C) 2005-2011 by Pablo Neira Ayuso <pablo@netfilter.org>
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  */
9 
10 #include "internal/internal.h"
11 #include <libmnl/libmnl.h>
12 
13 static int __parse_message(const struct nlmsghdr *nlh)
14 {
15  uint16_t type = NFNL_MSG_TYPE(nlh->nlmsg_type);
16  uint16_t flags = nlh->nlmsg_flags;
17  int ret = NFCT_T_UNKNOWN;
18 
19  switch(type) {
20  case IPCTNL_MSG_CT_NEW: /* same value for IPCTNL_MSG_EXP_NEW. */
21  if (flags & (NLM_F_CREATE|NLM_F_EXCL))
22  ret = NFCT_T_NEW;
23  else
24  ret = NFCT_T_UPDATE;
25  break;
26  case IPCTNL_MSG_CT_DELETE: /* same value for IPCTNL_MSG_EXP_DELETE. */
27  ret = NFCT_T_DESTROY;
28  break;
29  }
30  return ret;
31 }
32 
33 /* This function uses libmnl helpers, the nfa[] array is intentionally not used
34  * since it has a different layout.
35  */
36 int __callback(struct nlmsghdr *nlh, struct nfattr *nfa[], void *data)
37 {
38  int ret = NFNL_CB_STOP;
39  unsigned int type;
40  struct nf_conntrack *ct = NULL;
41  struct nf_expect *exp = NULL;
42  struct __data_container *container = data;
43  uint8_t subsys = NFNL_SUBSYS_ID(nlh->nlmsg_type);
44 
45  if (nlh->nlmsg_len < NLMSG_LENGTH(sizeof(struct nfgenmsg))) {
46  errno = EINVAL;
47  return NFNL_CB_FAILURE;
48  }
49  type = __parse_message(nlh);
50  if (!(type & container->type))
51  return NFNL_CB_CONTINUE;
52 
53  switch(subsys) {
54  case NFNL_SUBSYS_CTNETLINK:
55  ct = nfct_new();
56  if (ct == NULL)
57  return NFNL_CB_FAILURE;
58 
59  nfct_nlmsg_parse(nlh, ct);
60 
61  if (container->h->cb) {
62  ret = container->h->cb(type, ct, container->data);
63  } else if (container->h->cb2) {
64  ret = container->h->cb2(nlh, type, ct,
65  container->data);
66  }
67  break;
68  case NFNL_SUBSYS_CTNETLINK_EXP:
69  exp = nfexp_new();
70  if (exp == NULL)
71  return NFNL_CB_FAILURE;
72 
73  nfexp_nlmsg_parse(nlh, exp);
74 
75  if (container->h->expect_cb) {
76  ret = container->h->expect_cb(type, exp,
77  container->data);
78  } else if (container->h->expect_cb2) {
79  ret = container->h->expect_cb2(nlh, type, exp,
80  container->data);
81  }
82  break;
83  default:
84  errno = ENOTSUP;
85  ret = NFNL_CB_FAILURE;
86  break;
87  }
88 
89  if (ret == NFCT_CB_STOLEN)
90  return NFNL_CB_CONTINUE;
91 
92  if (ct)
93  nfct_destroy(ct);
94  if (exp)
95  nfexp_destroy(exp);
96 
97  return ret;
98 }
void nfct_destroy(struct nf_conntrack *ct)
Definition: conntrack/api.c:93
struct nf_conntrack * nfct_new(void)
Definition: conntrack/api.c:76
struct nf_expect * nfexp_new(void)
Definition: expect/api.c:29
void nfexp_destroy(struct nf_expect *exp)
Definition: expect/api.c:46