00001
00002
00003
00004
00005
00006
00007
00008 #include "internal/internal.h"
00009
00010 static int __parse_message(const struct nlmsghdr *nlh)
00011 {
00012 u_int16_t type = NFNL_MSG_TYPE(nlh->nlmsg_type);
00013 u_int16_t flags = nlh->nlmsg_flags;
00014 int ret = NFCT_T_UNKNOWN;
00015
00016 switch(type) {
00017 case IPCTNL_MSG_CT_NEW:
00018 if (flags & (NLM_F_CREATE|NLM_F_EXCL))
00019 ret = NFCT_T_NEW;
00020 else
00021 ret = NFCT_T_UPDATE;
00022 break;
00023 case IPCTNL_MSG_CT_DELETE:
00024 ret = NFCT_T_DESTROY;
00025 break;
00026 }
00027 return ret;
00028 }
00029
00030 int __callback(struct nlmsghdr *nlh, struct nfattr *nfa[], void *data)
00031 {
00032 int ret = NFNL_CB_STOP;
00033 unsigned int type;
00034 struct nf_conntrack *ct = NULL;
00035 struct nf_expect *exp = NULL;
00036 struct __data_container *container = data;
00037 u_int8_t subsys = NFNL_SUBSYS_ID(nlh->nlmsg_type);
00038
00039 if (nlh->nlmsg_len < NLMSG_LENGTH(sizeof(struct nfgenmsg))) {
00040 errno = EINVAL;
00041 return NFNL_CB_FAILURE;
00042 }
00043 type = __parse_message(nlh);
00044 if (!(type & container->type))
00045 return NFNL_CB_CONTINUE;
00046
00047 switch(subsys) {
00048 case NFNL_SUBSYS_CTNETLINK:
00049 ct = nfct_new();
00050 if (ct == NULL)
00051 return NFNL_CB_FAILURE;
00052
00053 __parse_conntrack(nlh, nfa, ct);
00054
00055 if (container->h->cb) {
00056 ret = container->h->cb(type, ct, container->data);
00057 } else if (container->h->cb2) {
00058 ret = container->h->cb2(nlh, type, ct,
00059 container->data);
00060 }
00061 break;
00062 case NFNL_SUBSYS_CTNETLINK_EXP:
00063 exp = nfexp_new();
00064 if (exp == NULL)
00065 return NFNL_CB_FAILURE;
00066
00067 __parse_expect(nlh, nfa, exp);
00068
00069 if (container->h->expect_cb) {
00070 ret = container->h->expect_cb(type, exp,
00071 container->data);
00072 } else if (container->h->expect_cb2) {
00073 ret = container->h->expect_cb2(nlh, type, exp,
00074 container->data);
00075 }
00076 break;
00077 default:
00078 errno = ENOTSUP;
00079 ret = NFNL_CB_FAILURE;
00080 break;
00081 }
00082
00083 switch(ret) {
00084 case NFCT_CB_FAILURE:
00085 if (ct)
00086 free(ct);
00087 if (exp)
00088 free(exp);
00089 ret = NFNL_CB_FAILURE;
00090 break;
00091 case NFCT_CB_STOP:
00092 if (ct)
00093 free(ct);
00094 if (exp)
00095 free(exp);
00096 ret = NFNL_CB_STOP;
00097 break;
00098 case NFCT_CB_CONTINUE:
00099 if (ct)
00100 free(ct);
00101 if (exp)
00102 free(exp);
00103 ret = NFNL_CB_CONTINUE;
00104 break;
00105 case NFCT_CB_STOLEN:
00106 ret = NFNL_CB_CONTINUE;
00107 break;
00108 }
00109 return ret;
00110 }