00001
00002
00003
00004
00005
00006
00007
00008 #include <stdlib.h>
00009 #include <string.h>
00010 #include <errno.h>
00011 #include <assert.h>
00012
00013 #include "internal/internal.h"
00014
00026 struct nf_expect *nfexp_new(void)
00027 {
00028 struct nf_expect *exp;
00029
00030 exp = malloc(sizeof(struct nf_expect));
00031 if (!exp)
00032 return NULL;
00033
00034 memset(exp, 0, sizeof(struct nf_expect));
00035
00036 return exp;
00037 }
00038
00043 void nfexp_destroy(struct nf_expect *exp)
00044 {
00045 assert(exp != NULL);
00046 free(exp);
00047 exp = NULL;
00048 }
00049
00054 size_t nfexp_sizeof(const struct nf_expect *exp)
00055 {
00056 assert(exp != NULL);
00057 return sizeof(*exp);
00058 }
00059
00074 size_t nfexp_maxsize(void)
00075 {
00076 return sizeof(struct nf_expect);
00077 }
00078
00086 struct nf_expect *nfexp_clone(const struct nf_expect *exp)
00087 {
00088 struct nf_expect *clone;
00089
00090 assert(exp != NULL);
00091
00092 if ((clone = nfexp_new()) == NULL)
00093 return NULL;
00094 memcpy(clone, exp, sizeof(*exp));
00095
00096 return clone;
00097 }
00098
00121 int nfexp_callback_register(struct nfct_handle *h,
00122 enum nf_conntrack_msg_type type,
00123 int (*cb)(enum nf_conntrack_msg_type type,
00124 struct nf_expect *exp,
00125 void *data),
00126 void *data)
00127 {
00128 struct __data_container *container;
00129
00130 assert(h != NULL);
00131
00132 container = malloc(sizeof(struct __data_container));
00133 if (!container)
00134 return -1;
00135 memset(container, 0, sizeof(struct __data_container));
00136
00137 h->expect_cb = cb;
00138 container->h = h;
00139 container->type = type;
00140 container->data = data;
00141
00142 h->nfnl_cb_exp.call = __callback;
00143 h->nfnl_cb_exp.data = container;
00144 h->nfnl_cb_exp.attr_count = CTA_EXPECT_MAX;
00145
00146 nfnl_callback_register(h->nfnlssh_exp,
00147 IPCTNL_MSG_EXP_NEW,
00148 &h->nfnl_cb_exp);
00149
00150 nfnl_callback_register(h->nfnlssh_exp,
00151 IPCTNL_MSG_EXP_DELETE,
00152 &h->nfnl_cb_exp);
00153
00154 return 0;
00155 }
00156
00161 void nfexp_callback_unregister(struct nfct_handle *h)
00162 {
00163 assert(h != NULL);
00164
00165 nfnl_callback_unregister(h->nfnlssh_exp, IPCTNL_MSG_EXP_NEW);
00166 nfnl_callback_unregister(h->nfnlssh_exp, IPCTNL_MSG_EXP_DELETE);
00167
00168 h->expect_cb = NULL;
00169 free(h->nfnl_cb_exp.data);
00170
00171 h->nfnl_cb_exp.call = NULL;
00172 h->nfnl_cb_exp.data = NULL;
00173 h->nfnl_cb_exp.attr_count = 0;
00174 }
00175
00195 int nfexp_callback_register2(struct nfct_handle *h,
00196 enum nf_conntrack_msg_type type,
00197 int (*cb)(const struct nlmsghdr *nlh,
00198 enum nf_conntrack_msg_type type,
00199 struct nf_expect *exp,
00200 void *data),
00201 void *data)
00202 {
00203 struct __data_container *container;
00204
00205 assert(h != NULL);
00206
00207 container = malloc(sizeof(struct __data_container));
00208 if (!container)
00209 return -1;
00210 memset(container, 0, sizeof(struct __data_container));
00211
00212 h->expect_cb2 = cb;
00213 container->h = h;
00214 container->type = type;
00215 container->data = data;
00216
00217 h->nfnl_cb_exp.call = __callback;
00218 h->nfnl_cb_exp.data = container;
00219 h->nfnl_cb_exp.attr_count = CTA_EXPECT_MAX;
00220
00221 nfnl_callback_register(h->nfnlssh_exp,
00222 IPCTNL_MSG_EXP_NEW,
00223 &h->nfnl_cb_exp);
00224
00225 nfnl_callback_register(h->nfnlssh_exp,
00226 IPCTNL_MSG_EXP_DELETE,
00227 &h->nfnl_cb_exp);
00228
00229 return 0;
00230 }
00231
00236 void nfexp_callback_unregister2(struct nfct_handle *h)
00237 {
00238 assert(h != NULL);
00239
00240 nfnl_callback_unregister(h->nfnlssh_exp, IPCTNL_MSG_EXP_NEW);
00241 nfnl_callback_unregister(h->nfnlssh_exp, IPCTNL_MSG_EXP_DELETE);
00242
00243 h->expect_cb2 = NULL;
00244 free(h->nfnl_cb_exp.data);
00245
00246 h->nfnl_cb_exp.call = NULL;
00247 h->nfnl_cb_exp.data = NULL;
00248 h->nfnl_cb_exp.attr_count = 0;
00249 }
00250
00272 void nfexp_set_attr(struct nf_expect *exp,
00273 const enum nf_expect_attr type,
00274 const void *value)
00275 {
00276 assert(exp != NULL);
00277 assert(value != NULL);
00278
00279 if (type >= ATTR_EXP_MAX)
00280 return;
00281
00282 if (set_exp_attr_array[type]) {
00283 set_exp_attr_array[type](exp, value);
00284 set_bit(type, exp->set);
00285 }
00286 }
00287
00294 void nfexp_set_attr_u8(struct nf_expect *exp,
00295 const enum nf_expect_attr type,
00296 u_int8_t value)
00297 {
00298 nfexp_set_attr(exp, type, &value);
00299 }
00300
00307 void nfexp_set_attr_u16(struct nf_expect *exp,
00308 const enum nf_expect_attr type,
00309 u_int16_t value)
00310 {
00311 nfexp_set_attr(exp, type, &value);
00312 }
00313
00320 void nfexp_set_attr_u32(struct nf_expect *exp,
00321 const enum nf_expect_attr type,
00322 u_int32_t value)
00323 {
00324 nfexp_set_attr(exp, type, &value);
00325 }
00326
00335 const void *nfexp_get_attr(const struct nf_expect *exp,
00336 const enum nf_expect_attr type)
00337 {
00338 assert(exp != NULL);
00339
00340 if (type >= ATTR_EXP_MAX) {
00341 errno = EINVAL;
00342 return NULL;
00343 }
00344
00345 if (!test_bit(type, exp->set)) {
00346 errno = ENODATA;
00347 return NULL;
00348 }
00349
00350 return get_exp_attr_array[type](exp);
00351 }
00352
00362 u_int8_t nfexp_get_attr_u8(const struct nf_expect *exp,
00363 const enum nf_expect_attr type)
00364 {
00365 const u_int8_t *ret = nfexp_get_attr(exp, type);
00366 return ret == NULL ? 0 : *ret;
00367 }
00368
00378 u_int16_t nfexp_get_attr_u16(const struct nf_expect *exp,
00379 const enum nf_expect_attr type)
00380 {
00381 const u_int16_t *ret = nfexp_get_attr(exp, type);
00382 return ret == NULL ? 0 : *ret;
00383 }
00384
00394 u_int32_t nfexp_get_attr_u32(const struct nf_expect *exp,
00395 const enum nf_expect_attr type)
00396 {
00397 const u_int32_t *ret = nfexp_get_attr(exp, type);
00398 return ret == NULL ? 0 : *ret;
00399 }
00400
00409 int nfexp_attr_is_set(const struct nf_expect *exp,
00410 const enum nf_expect_attr type)
00411 {
00412 assert(exp != NULL);
00413
00414 if (type >= ATTR_EXP_MAX) {
00415 errno = EINVAL;
00416 return -1;
00417 }
00418 return test_bit(type, exp->set);
00419 }
00420
00429 int nfexp_attr_unset(struct nf_expect *exp,
00430 const enum nf_expect_attr type)
00431 {
00432 assert(exp != NULL);
00433
00434 if (type >= ATTR_EXP_MAX) {
00435 errno = EINVAL;
00436 return -1;
00437 }
00438 unset_bit(type, exp->set);
00439
00440 return 0;
00441 }
00442
00468 int nfexp_build_expect(struct nfnl_subsys_handle *ssh,
00469 void *req,
00470 size_t size,
00471 u_int16_t type,
00472 u_int16_t flags,
00473 const struct nf_expect *exp)
00474 {
00475 assert(ssh != NULL);
00476 assert(req != NULL);
00477 assert(exp != NULL);
00478
00479 return __build_expect(ssh, req, size, type, flags, exp);
00480 }
00481
00512 int nfexp_build_query(struct nfnl_subsys_handle *ssh,
00513 const enum nf_conntrack_query qt,
00514 const void *data,
00515 void *buffer,
00516 unsigned int size)
00517 {
00518 struct nfnlhdr *req = buffer;
00519 const u_int8_t *family = data;
00520
00521 assert(ssh != NULL);
00522 assert(data != NULL);
00523 assert(req != NULL);
00524
00525 memset(req, 0, size);
00526
00527 switch(qt) {
00528 case NFCT_Q_CREATE:
00529 nfexp_build_expect(ssh, req, size, IPCTNL_MSG_EXP_NEW, NLM_F_REQUEST|NLM_F_CREATE|NLM_F_ACK|NLM_F_EXCL, data);
00530 break;
00531 case NFCT_Q_GET:
00532 nfexp_build_expect(ssh, req, size, IPCTNL_MSG_EXP_GET, NLM_F_REQUEST|NLM_F_ACK, data);
00533 break;
00534 case NFCT_Q_DESTROY:
00535 nfexp_build_expect(ssh, req, size, IPCTNL_MSG_EXP_DELETE, NLM_F_REQUEST|NLM_F_ACK, data);
00536 break;
00537 case NFCT_Q_FLUSH:
00538 nfnl_fill_hdr(ssh, &req->nlh, 0, *family, 0, IPCTNL_MSG_EXP_DELETE, NLM_F_REQUEST|NLM_F_ACK);
00539 break;
00540 case NFCT_Q_DUMP:
00541 nfnl_fill_hdr(ssh, &req->nlh, 0, *family, 0, IPCTNL_MSG_EXP_GET, NLM_F_REQUEST|NLM_F_DUMP);
00542 break;
00543 default:
00544 errno = ENOTSUP;
00545 return -1;
00546 }
00547 return 1;
00548 }
00549
00574 int nfexp_parse_expect(enum nf_conntrack_msg_type type,
00575 const struct nlmsghdr *nlh,
00576 struct nf_expect *exp)
00577 {
00578 unsigned int flags;
00579 int len = nlh->nlmsg_len;
00580 struct nfgenmsg *nfhdr = NLMSG_DATA(nlh);
00581 struct nfattr *cda[CTA_EXPECT_MAX];
00582
00583 assert(nlh != NULL);
00584 assert(exp != NULL);
00585
00586 len -= NLMSG_LENGTH(sizeof(struct nfgenmsg));
00587 if (len < 0) {
00588 errno = EINVAL;
00589 return NFCT_T_ERROR;
00590 }
00591
00592 flags = __parse_expect_message_type(nlh);
00593 if (!(flags & type))
00594 return 0;
00595
00596 nfnl_parse_attr(cda, CTA_EXPECT_MAX, NFA_DATA(nfhdr), len);
00597
00598 __parse_expect(nlh, cda, exp);
00599
00600 return flags;
00601 }
00602
00621 int nfexp_query(struct nfct_handle *h,
00622 const enum nf_conntrack_query qt,
00623 const void *data)
00624 {
00625 size_t size = 4096;
00626 union {
00627 char buffer[size];
00628 struct nfnlhdr req;
00629 } u;
00630
00631 assert(h != NULL);
00632 assert(data != NULL);
00633
00634 if (nfexp_build_query(h->nfnlssh_exp, qt, data, &u.req, size) == -1)
00635 return -1;
00636
00637 return nfnl_query(h->nfnlh, &u.req.nlh);
00638 }
00639
00648 int nfexp_catch(struct nfct_handle *h)
00649 {
00650 assert(h != NULL);
00651
00652 return nfnl_catch(h->nfnlh);
00653 }
00654
00689 int nfexp_snprintf(char *buf,
00690 unsigned int size,
00691 const struct nf_expect *exp,
00692 unsigned int msg_type,
00693 unsigned int out_type,
00694 unsigned int flags)
00695 {
00696 assert(buf != NULL);
00697 assert(size > 0);
00698 assert(exp != NULL);
00699
00700 return __snprintf_expect(buf, size, exp, msg_type, out_type, flags);
00701 }
00702