text.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. /*
  2. * lib/route/cls/ematch/text.c Text Search
  3. *
  4. * This library is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU Lesser General Public
  6. * License as published by the Free Software Foundation version 2.1
  7. * of the License.
  8. *
  9. * Copyright (c) 2010-2013 Thomas Graf <tgraf@suug.ch>
  10. */
  11. /**
  12. * @ingroup ematch
  13. * @defgroup em_text Text Search
  14. *
  15. * @{
  16. */
  17. #include <netlink-private/netlink.h>
  18. #include <netlink-private/tc.h>
  19. #include <netlink/netlink.h>
  20. #include <netlink/route/cls/ematch.h>
  21. #include <netlink/route/cls/ematch/text.h>
  22. struct text_data
  23. {
  24. struct tcf_em_text cfg;
  25. char * pattern;
  26. };
  27. void rtnl_ematch_text_set_from(struct rtnl_ematch *e, uint8_t layer,
  28. uint16_t offset)
  29. {
  30. struct text_data *t = rtnl_ematch_data(e);
  31. t->cfg.from_offset = offset;
  32. t->cfg.from_layer = layer;
  33. }
  34. uint16_t rtnl_ematch_text_get_from_offset(struct rtnl_ematch *e)
  35. {
  36. return ((struct text_data *) rtnl_ematch_data(e))->cfg.from_offset;
  37. }
  38. uint8_t rtnl_ematch_text_get_from_layer(struct rtnl_ematch *e)
  39. {
  40. return ((struct text_data *) rtnl_ematch_data(e))->cfg.from_layer;
  41. }
  42. void rtnl_ematch_text_set_to(struct rtnl_ematch *e, uint8_t layer,
  43. uint16_t offset)
  44. {
  45. struct text_data *t = rtnl_ematch_data(e);
  46. t->cfg.to_offset = offset;
  47. t->cfg.to_layer = layer;
  48. }
  49. uint16_t rtnl_ematch_text_get_to_offset(struct rtnl_ematch *e)
  50. {
  51. return ((struct text_data *) rtnl_ematch_data(e))->cfg.to_offset;
  52. }
  53. uint8_t rtnl_ematch_text_get_to_layer(struct rtnl_ematch *e)
  54. {
  55. return ((struct text_data *) rtnl_ematch_data(e))->cfg.to_layer;
  56. }
  57. void rtnl_ematch_text_set_pattern(struct rtnl_ematch *e,
  58. char *pattern, size_t len)
  59. {
  60. struct text_data *t = rtnl_ematch_data(e);
  61. if (t->pattern)
  62. free(t->pattern);
  63. t->pattern = pattern;
  64. t->cfg.pattern_len = len;
  65. }
  66. char *rtnl_ematch_text_get_pattern(struct rtnl_ematch *e)
  67. {
  68. return ((struct text_data *) rtnl_ematch_data(e))->pattern;
  69. }
  70. size_t rtnl_ematch_text_get_len(struct rtnl_ematch *e)
  71. {
  72. return ((struct text_data *) rtnl_ematch_data(e))->cfg.pattern_len;
  73. }
  74. void rtnl_ematch_text_set_algo(struct rtnl_ematch *e, const char *algo)
  75. {
  76. struct text_data *t = rtnl_ematch_data(e);
  77. strncpy(t->cfg.algo, algo, sizeof(t->cfg.algo));
  78. }
  79. char *rtnl_ematch_text_get_algo(struct rtnl_ematch *e)
  80. {
  81. struct text_data *t = rtnl_ematch_data(e);
  82. return t->cfg.algo[0] ? t->cfg.algo : NULL;
  83. }
  84. static int text_parse(struct rtnl_ematch *e, void *data, size_t len)
  85. {
  86. struct text_data *t = rtnl_ematch_data(e);
  87. size_t hdrlen = sizeof(struct tcf_em_text);
  88. size_t plen = len - hdrlen;
  89. memcpy(&t->cfg, data, hdrlen);
  90. if (t->cfg.pattern_len > plen)
  91. return -NLE_INVAL;
  92. if (t->cfg.pattern_len > 0) {
  93. if (!(t->pattern = calloc(1, t->cfg.pattern_len)))
  94. return -NLE_NOMEM;
  95. memcpy(t->pattern, data + hdrlen, t->cfg.pattern_len);
  96. }
  97. return 0;
  98. }
  99. static void text_dump(struct rtnl_ematch *e, struct nl_dump_params *p)
  100. {
  101. struct text_data *t = rtnl_ematch_data(e);
  102. char buf[64];
  103. nl_dump(p, "text(%s \"%s\"",
  104. t->cfg.algo[0] ? t->cfg.algo : "no-algo",
  105. t->pattern ? : "no-pattern");
  106. if (t->cfg.from_layer || t->cfg.from_offset) {
  107. nl_dump(p, " from %s",
  108. rtnl_ematch_offset2txt(t->cfg.from_layer,
  109. t->cfg.from_offset,
  110. buf, sizeof(buf)));
  111. }
  112. if (t->cfg.to_layer || t->cfg.to_offset) {
  113. nl_dump(p, " to %s",
  114. rtnl_ematch_offset2txt(t->cfg.to_layer,
  115. t->cfg.to_offset,
  116. buf, sizeof(buf)));
  117. }
  118. nl_dump(p, ")");
  119. }
  120. static int text_fill(struct rtnl_ematch *e, struct nl_msg *msg)
  121. {
  122. struct text_data *t = rtnl_ematch_data(e);
  123. int err;
  124. if ((err = nlmsg_append(msg, &t->cfg, sizeof(t->cfg), 0)) < 0)
  125. return err;
  126. return nlmsg_append(msg, t->pattern, t->cfg.pattern_len, 0);
  127. }
  128. static void text_free(struct rtnl_ematch *e)
  129. {
  130. struct text_data *t = rtnl_ematch_data(e);
  131. free(t->pattern);
  132. }
  133. static struct rtnl_ematch_ops text_ops = {
  134. .eo_kind = TCF_EM_TEXT,
  135. .eo_name = "text",
  136. .eo_minlen = sizeof(struct tcf_em_text),
  137. .eo_datalen = sizeof(struct text_data),
  138. .eo_parse = text_parse,
  139. .eo_dump = text_dump,
  140. .eo_fill = text_fill,
  141. .eo_free = text_free,
  142. };
  143. static void __init text_init(void)
  144. {
  145. rtnl_ematch_register(&text_ops);
  146. }
  147. /** @} */