static int string_mt_check(const struct xt_mtchk_param *par) { struct xt_string_info *conf = par->matchinfo; struct ts_config *ts_conf; int flags = TS_AUTOLOAD; /* Damn, can't handle this case properly with iptables... */ if (conf->from_offset > conf->to_offset) return false; if (conf->algo[XT_STRING_MAX_ALGO_NAME_SIZE - 1] != '\0') return false; if (conf->patlen > XT_STRING_MAX_PATTERN_SIZE) return false; if (par->match->revision == 1) { if (conf->u.v1.flags & ~(XT_STRING_FLAG_IGNORECASE | XT_STRING_FLAG_INVERT)) return false; if (conf->u.v1.flags & XT_STRING_FLAG_IGNORECASE) flags |= TS_IGNORECASE; } ts_conf = textsearch_prepare(conf->algo, conf->pattern, conf->patlen, GFP_KERNEL, flags); if (IS_ERR(ts_conf)) return false; conf->config = ts_conf; return true; }
static int checkentry(const char *tablename, const void *ip, const struct xt_match *match, void *matchinfo, unsigned int matchsize, unsigned int hook_mask) { struct xt_string_info *conf = matchinfo; struct ts_config *ts_conf; /* Damn, can't handle this case properly with iptables... */ if (conf->from_offset > conf->to_offset) return 0; if (conf->algo[XT_STRING_MAX_ALGO_NAME_SIZE - 1] != '\0') return 0; if (conf->patlen > XT_STRING_MAX_PATTERN_SIZE) return 0; ts_conf = textsearch_prepare(conf->algo, conf->pattern, conf->patlen, GFP_KERNEL, TS_AUTOLOAD); if (IS_ERR(ts_conf)) return 0; conf->config = ts_conf; return 1; }
static int checkentry(const char *tablename, const struct ipt_ip *ip, void *matchinfo, unsigned int matchsize, unsigned int hook_mask) { struct ipt_string_info *conf = matchinfo; struct ts_config *ts_conf; if (matchsize != IPT_ALIGN(sizeof(struct ipt_string_info))) return 0; /* Damn, can't handle this case properly with iptables... */ if (conf->from_offset > conf->to_offset) return 0; ts_conf = textsearch_prepare(conf->algo, conf->pattern, conf->patlen, GFP_KERNEL, TS_AUTOLOAD); if (IS_ERR(ts_conf)) return 0; conf->config = ts_conf; return 1; }
static int em_text_change(struct tcf_proto *tp, void *data, int len, struct tcf_ematch *m) { struct text_match *tm; struct tcf_em_text *conf = data; struct ts_config *ts_conf; int flags = 0; if (len < sizeof(*conf) || len < (sizeof(*conf) + conf->pattern_len)) return -EINVAL; if (conf->from_layer > conf->to_layer) return -EINVAL; if (conf->from_layer == conf->to_layer && conf->from_offset > conf->to_offset) return -EINVAL; retry: ts_conf = textsearch_prepare(conf->algo, (u8 *) conf + sizeof(*conf), conf->pattern_len, GFP_KERNEL, flags); if (flags & TS_AUTOLOAD) rtnl_lock(); if (IS_ERR(ts_conf)) { if (PTR_ERR(ts_conf) == -ENOENT && !(flags & TS_AUTOLOAD)) { rtnl_unlock(); flags |= TS_AUTOLOAD; goto retry; } else return PTR_ERR(ts_conf); } else if (flags & TS_AUTOLOAD) { textsearch_destroy(ts_conf); return -EAGAIN; } tm = kmalloc(sizeof(*tm), GFP_KERNEL); if (tm == NULL) { textsearch_destroy(ts_conf); return -ENOBUFS; } tm->from_offset = conf->from_offset; tm->to_offset = conf->to_offset; tm->from_layer = conf->from_layer; tm->to_layer = conf->to_layer; tm->config = ts_conf; m->datalen = sizeof(*tm); m->data = (unsigned long) tm; return 0; }
static int __init ip_conntrack_amanda_init(void) { int ret, i; ret = -ENOMEM; for (i = 0; i < ARRAY_SIZE(search); i++) { search[i].ts = textsearch_prepare(ts_algo, search[i].string, search[i].len, GFP_KERNEL, TS_AUTOLOAD); if (search[i].ts == NULL) goto err; } ret = ip_conntrack_helper_register(&amanda_helper); if (ret < 0) goto err; return 0; err: for (; i >= 0; i--) { if (search[i].ts) textsearch_destroy(search[i].ts); } return ret; }
static bool wildstring_mt_check(const struct xt_mtchk_param *par) { struct xt_wildstring_info *conf = par->matchinfo; struct ts_config *ts_conf; int flags = TS_AUTOLOAD; char *s; char delim[2] = "*"; /* Damn, can't handle this case properly with iptables... */ if (conf->from_offset > conf->to_offset) return false; if (conf->algo[XT_WILDSTRING_MAX_ALGO_NAME_SIZE - 1] != '\0') return false; if (conf->patlen > XT_WILDSTRING_MAX_PATTERN_SIZE) return false; if (par->match->revision == 1) { if (conf->u.v1.flags & ~(XT_WILDSTRING_FLAG_IGNORECASE | XT_WILDSTRING_FLAG_INVERT)) return false; if (conf->u.v1.flags & XT_WILDSTRING_FLAG_IGNORECASE) flags |= TS_IGNORECASE; } /* a new wild logic appears, maybe lists.. */ s = (char *)conf->pattern; /* pattern1 */ conf->pattern_part1 = strsep(&s, delim); if (!conf->pattern_part1) return false; conf->patlen_part1 = strlen(conf->pattern_part1); ts_conf = textsearch_prepare(conf->algo, conf->pattern_part1, conf->patlen_part1, GFP_KERNEL, flags); if (IS_ERR(ts_conf)) return false; conf->config_part1 = ts_conf; /* pattern2 */ conf->pattern_part2 = strsep(&s, delim); if (!conf->pattern_part2) return true; conf->patlen_part2 = strlen(conf->pattern_part2); ts_conf = textsearch_prepare(conf->algo, conf->pattern_part2, conf->patlen_part2, GFP_KERNEL, flags); if (IS_ERR(ts_conf)) return false; conf->config_part2 = ts_conf; /* pattern3 */ conf->pattern_part3 = strsep(&s, delim); if (!conf->pattern_part3) return true; conf->patlen_part3 = strlen(conf->pattern_part3); ts_conf = textsearch_prepare(conf->algo, conf->pattern_part3, conf->patlen_part3, GFP_KERNEL, flags); if (IS_ERR(ts_conf)) return false; conf->config_part3 = ts_conf; return true; }