libnl
3.2.3
|
00001 /* 00002 * lib/route/cls/ematch/nbyte.c Nbyte comparison 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_nbyte N-Byte Comparison 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/nbyte.h> 00024 00025 struct nbyte_data 00026 { 00027 struct tcf_em_nbyte cfg; 00028 uint8_t * pattern; 00029 }; 00030 00031 void rtnl_ematch_nbyte_set_offset(struct rtnl_ematch *e, uint8_t layer, 00032 uint16_t offset) 00033 { 00034 struct nbyte_data *n = rtnl_ematch_data(e); 00035 n->cfg.off = offset; 00036 n->cfg.layer = layer; 00037 } 00038 00039 uint16_t rtnl_ematch_nbyte_get_offset(struct rtnl_ematch *e) 00040 { 00041 return ((struct nbyte_data *) rtnl_ematch_data(e))->cfg.off; 00042 } 00043 00044 uint8_t rtnl_ematch_nbyte_get_layer(struct rtnl_ematch *e) 00045 { 00046 return ((struct nbyte_data *) rtnl_ematch_data(e))->cfg.layer; 00047 } 00048 00049 void rtnl_ematch_nbyte_set_pattern(struct rtnl_ematch *e, 00050 uint8_t *pattern, size_t len) 00051 { 00052 struct nbyte_data *n = rtnl_ematch_data(e); 00053 00054 if (n->pattern) 00055 free(n->pattern); 00056 00057 n->pattern = pattern; 00058 n->cfg.len = len; 00059 } 00060 00061 uint8_t *rtnl_ematch_nbyte_get_pattern(struct rtnl_ematch *e) 00062 { 00063 return ((struct nbyte_data *) rtnl_ematch_data(e))->pattern; 00064 } 00065 00066 size_t rtnl_ematch_nbyte_get_len(struct rtnl_ematch *e) 00067 { 00068 return ((struct nbyte_data *) rtnl_ematch_data(e))->cfg.len; 00069 } 00070 00071 static const char *layer_txt(struct tcf_em_nbyte *nbyte) 00072 { 00073 switch (nbyte->layer) { 00074 case TCF_LAYER_LINK: 00075 return "link"; 00076 case TCF_LAYER_NETWORK: 00077 return "net"; 00078 case TCF_LAYER_TRANSPORT: 00079 return "trans"; 00080 default: 00081 return "?"; 00082 } 00083 } 00084 00085 static int nbyte_parse(struct rtnl_ematch *e, void *data, size_t len) 00086 { 00087 struct nbyte_data *n = rtnl_ematch_data(e); 00088 size_t hdrlen = sizeof(struct tcf_em_nbyte); 00089 size_t plen = len - hdrlen; 00090 00091 memcpy(&n->cfg, data, hdrlen); 00092 if (plen > 0) { 00093 if (!(n->pattern = calloc(1, plen))) 00094 return -NLE_NOMEM; 00095 00096 memcpy(n->pattern, data + hdrlen, plen); 00097 } 00098 00099 return 0; 00100 } 00101 00102 static void nbyte_dump(struct rtnl_ematch *e, struct nl_dump_params *p) 00103 { 00104 struct nbyte_data *n = rtnl_ematch_data(e); 00105 int i; 00106 00107 nl_dump(p, "pattern(%u:[", n->cfg.len); 00108 00109 for (i = 0; i < n->cfg.len; i++) { 00110 nl_dump(p, "%02x", n->pattern[i]); 00111 if (i+1 < n->cfg.len) 00112 nl_dump(p, " "); 00113 } 00114 00115 nl_dump(p, "] at %s+%u)", layer_txt(&n->cfg), n->cfg.off); 00116 } 00117 00118 static void nbyte_free(struct rtnl_ematch *e) 00119 { 00120 struct nbyte_data *n = rtnl_ematch_data(e); 00121 free(n->pattern); 00122 } 00123 00124 static struct rtnl_ematch_ops nbyte_ops = { 00125 .eo_kind = TCF_EM_NBYTE, 00126 .eo_name = "nbyte", 00127 .eo_minlen = sizeof(struct tcf_em_nbyte), 00128 .eo_datalen = sizeof(struct nbyte_data), 00129 .eo_parse = nbyte_parse, 00130 .eo_dump = nbyte_dump, 00131 .eo_free = nbyte_free, 00132 }; 00133 00134 static void __init nbyte_init(void) 00135 { 00136 rtnl_ematch_register(&nbyte_ops); 00137 } 00138 00139 /** @} */