libnetfilter_conntrack  1.0.6
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 
12 static int __parse_message(const struct nlmsghdr *nlh)
13 {
14  uint16_t type = NFNL_MSG_TYPE(nlh->nlmsg_type);
15  uint16_t flags = nlh->nlmsg_flags;
16  int ret = NFCT_T_UNKNOWN;
17 
18  switch(type) {
19  case IPCTNL_MSG_CT_NEW: /* same value for IPCTNL_MSG_EXP_NEW. */
20  if (flags & (NLM_F_CREATE|NLM_F_EXCL))
21  ret = NFCT_T_NEW;
22  else
23  ret = NFCT_T_UPDATE;
24  break;
25  case IPCTNL_MSG_CT_DELETE: /* same value for IPCTNL_MSG_EXP_DELETE. */
26  ret = NFCT_T_DESTROY;
27  break;
28  }
29  return ret;
30 }
31 
32 int __callback(struct nlmsghdr *nlh, struct nfattr *nfa[], void *data)
33 {
34  int ret = NFNL_CB_STOP;
35  unsigned int type;
36  struct nf_conntrack *ct = NULL;
37  struct nf_expect *exp = NULL;
38  struct __data_container *container = data;
39  uint8_t subsys = NFNL_SUBSYS_ID(nlh->nlmsg_type);
40 
41  if (nlh->nlmsg_len < NLMSG_LENGTH(sizeof(struct nfgenmsg))) {
42  errno = EINVAL;
43  return NFNL_CB_FAILURE;
44  }
45  type = __parse_message(nlh);
46  if (!(type & container->type))
47  return NFNL_CB_CONTINUE;
48 
49  switch(subsys) {
50  case NFNL_SUBSYS_CTNETLINK:
51  ct = nfct_new();
52  if (ct == NULL)
53  return NFNL_CB_FAILURE;
54 
55  __parse_conntrack(nlh, nfa, ct);
56 
57  if (container->h->cb) {
58  ret = container->h->cb(type, ct, container->data);
59  } else if (container->h->cb2) {
60  ret = container->h->cb2(nlh, type, ct,
61  container->data);
62  }
63  break;
64  case NFNL_SUBSYS_CTNETLINK_EXP:
65  exp = nfexp_new();
66  if (exp == NULL)
67  return NFNL_CB_FAILURE;
68 
69  __parse_expect(nlh, nfa, exp);
70 
71  if (container->h->expect_cb) {
72  ret = container->h->expect_cb(type, exp,
73  container->data);
74  } else if (container->h->expect_cb2) {
75  ret = container->h->expect_cb2(nlh, type, exp,
76  container->data);
77  }
78  break;
79  default:
80  errno = ENOTSUP;
81  ret = NFNL_CB_FAILURE;
82  break;
83  }
84 
85  if (ret == NFCT_CB_STOLEN)
86  return NFNL_CB_CONTINUE;
87 
88  if (ct)
89  nfct_destroy(ct);
90  if (exp)
91  nfexp_destroy(exp);
92 
93  return ret;
94 }
void nfct_destroy(struct nf_conntrack *ct)
Definition: conntrack/api.c:92
struct nf_expect * nfexp_new(void)
Definition: expect/api.c:28
struct nf_conntrack * nfct_new(void)
Definition: conntrack/api.c:75
void nfexp_destroy(struct nf_expect *exp)
Definition: expect/api.c:45