libnl
3.2.3
|
00001 /* 00002 * lib/route/cls/ematch/text.c Text Search 00003 * 00004 * This library is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU Lesser General Public 00006 * License as published by the Free Software Foundation version 2.1 00007 * of the License. 00008 * 00009 * Copyright (c) 2010 Thomas Graf <tgraf@suug.ch> 00010 */ 00011 00012 /** 00013 * @ingroup ematch 00014 * @defgroup em_text Text Search 00015 * 00016 * @{ 00017 */ 00018 00019 #include <netlink-local.h> 00020 #include <netlink-tc.h> 00021 #include <netlink/netlink.h> 00022 #include <netlink/route/cls/ematch.h> 00023 #include <netlink/route/cls/ematch/text.h> 00024 00025 struct text_data 00026 { 00027 struct tcf_em_text cfg; 00028 char * pattern; 00029 }; 00030 00031 void rtnl_ematch_text_set_from(struct rtnl_ematch *e, uint8_t layer, 00032 uint16_t offset) 00033 { 00034 struct text_data *t = rtnl_ematch_data(e); 00035 t->cfg.from_offset = offset; 00036 t->cfg.from_layer = layer; 00037 } 00038 00039 uint16_t rtnl_ematch_text_get_from_offset(struct rtnl_ematch *e) 00040 { 00041 return ((struct text_data *) rtnl_ematch_data(e))->cfg.from_offset; 00042 } 00043 00044 uint8_t rtnl_ematch_text_get_from_layer(struct rtnl_ematch *e) 00045 { 00046 return ((struct text_data *) rtnl_ematch_data(e))->cfg.from_layer; 00047 } 00048 00049 void rtnl_ematch_text_set_to(struct rtnl_ematch *e, uint8_t layer, 00050 uint16_t offset) 00051 { 00052 struct text_data *t = rtnl_ematch_data(e); 00053 t->cfg.to_offset = offset; 00054 t->cfg.to_layer = layer; 00055 } 00056 00057 uint16_t rtnl_ematch_text_get_to_offset(struct rtnl_ematch *e) 00058 { 00059 return ((struct text_data *) rtnl_ematch_data(e))->cfg.to_offset; 00060 } 00061 00062 uint8_t rtnl_ematch_text_get_to_layer(struct rtnl_ematch *e) 00063 { 00064 return ((struct text_data *) rtnl_ematch_data(e))->cfg.to_layer; 00065 } 00066 00067 void rtnl_ematch_text_set_pattern(struct rtnl_ematch *e, 00068 char *pattern, size_t len) 00069 { 00070 struct text_data *t = rtnl_ematch_data(e); 00071 00072 if (t->pattern) 00073 free(t->pattern); 00074 00075 t->pattern = pattern; 00076 t->cfg.pattern_len = len; 00077 } 00078 00079 char *rtnl_ematch_text_get_pattern(struct rtnl_ematch *e) 00080 { 00081 return ((struct text_data *) rtnl_ematch_data(e))->pattern; 00082 } 00083 00084 size_t rtnl_ematch_text_get_len(struct rtnl_ematch *e) 00085 { 00086 return ((struct text_data *) rtnl_ematch_data(e))->cfg.pattern_len; 00087 } 00088 00089 void rtnl_ematch_text_set_algo(struct rtnl_ematch *e, const char *algo) 00090 { 00091 struct text_data *t = rtnl_ematch_data(e); 00092 00093 strncpy(t->cfg.algo, algo, sizeof(t->cfg.algo)); 00094 } 00095 00096 char *rtnl_ematch_text_get_algo(struct rtnl_ematch *e) 00097 { 00098 struct text_data *t = rtnl_ematch_data(e); 00099 00100 return t->cfg.algo[0] ? t->cfg.algo : NULL; 00101 } 00102 00103 static int text_parse(struct rtnl_ematch *e, void *data, size_t len) 00104 { 00105 struct text_data *t = rtnl_ematch_data(e); 00106 size_t hdrlen = sizeof(struct tcf_em_text); 00107 size_t plen = len - hdrlen; 00108 00109 memcpy(&t->cfg, data, hdrlen); 00110 00111 if (t->cfg.pattern_len > plen) 00112 return -NLE_INVAL; 00113 00114 if (t->cfg.pattern_len > 0) { 00115 if (!(t->pattern = calloc(1, t->cfg.pattern_len))) 00116 return -NLE_NOMEM; 00117 00118 memcpy(t->pattern, data + hdrlen, t->cfg.pattern_len); 00119 } 00120 00121 return 0; 00122 } 00123 00124 static void text_dump(struct rtnl_ematch *e, struct nl_dump_params *p) 00125 { 00126 struct text_data *t = rtnl_ematch_data(e); 00127 char buf[64]; 00128 00129 nl_dump(p, "text(%s \"%s\"", 00130 t->cfg.algo[0] ? t->cfg.algo : "no-algo", 00131 t->pattern ? : "no-pattern"); 00132 00133 if (t->cfg.from_layer || t->cfg.from_offset) { 00134 nl_dump(p, " from %s", 00135 rtnl_ematch_offset2txt(t->cfg.from_layer, 00136 t->cfg.from_offset, 00137 buf, sizeof(buf))); 00138 } 00139 00140 if (t->cfg.to_layer || t->cfg.to_offset) { 00141 nl_dump(p, " to %s", 00142 rtnl_ematch_offset2txt(t->cfg.to_layer, 00143 t->cfg.to_offset, 00144 buf, sizeof(buf))); 00145 } 00146 00147 nl_dump(p, ")"); 00148 } 00149 00150 static int text_fill(struct rtnl_ematch *e, struct nl_msg *msg) 00151 { 00152 struct text_data *t = rtnl_ematch_data(e); 00153 int err; 00154 00155 if ((err = nlmsg_append(msg, &t->cfg, sizeof(t->cfg), 0)) < 0) 00156 return err; 00157 00158 return nlmsg_append(msg, t->pattern, t->cfg.pattern_len, 0); 00159 } 00160 00161 static void text_free(struct rtnl_ematch *e) 00162 { 00163 struct text_data *t = rtnl_ematch_data(e); 00164 free(t->pattern); 00165 } 00166 00167 static struct rtnl_ematch_ops text_ops = { 00168 .eo_kind = TCF_EM_TEXT, 00169 .eo_name = "text", 00170 .eo_minlen = sizeof(struct tcf_em_text), 00171 .eo_datalen = sizeof(struct text_data), 00172 .eo_parse = text_parse, 00173 .eo_dump = text_dump, 00174 .eo_fill = text_fill, 00175 .eo_free = text_free, 00176 }; 00177 00178 static void __init text_init(void) 00179 { 00180 rtnl_ematch_register(&text_ops); 00181 } 00182 00183 /** @} */