mod.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. /*
  2. * mod.c
  3. *
  4. * Copyright (c) 2001 Dug Song <dugsong@monkey.org>
  5. * Copyright (c) 2007-2010 Aaron Turner.
  6. *
  7. * $Id$
  8. */
  9. #include "config.h"
  10. #include "lib/queue.h"
  11. #include "defines.h"
  12. #include "common.h"
  13. #include <ctype.h>
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <string.h>
  17. #include "argv.h"
  18. #include "mod.h"
  19. #define MAX_ARGS 128
  20. struct rule {
  21. struct mod *mod;
  22. void *data;
  23. TAILQ_ENTRY(rule) next;
  24. };
  25. /*
  26. * new modules must be registered here.
  27. */
  28. extern struct mod mod_delay;
  29. extern struct mod mod_drop;
  30. extern struct mod mod_dup;
  31. extern struct mod mod_echo;
  32. extern struct mod mod_ip_chaff;
  33. extern struct mod mod_ip_frag;
  34. extern struct mod mod_ip_opt;
  35. extern struct mod mod_ip_ttl;
  36. extern struct mod mod_ip_tos;
  37. extern struct mod mod_ip6_qos;
  38. extern struct mod mod_ip6_opt;
  39. extern struct mod mod_order;
  40. extern struct mod mod_print;
  41. extern struct mod mod_tcp_chaff;
  42. extern struct mod mod_tcp_opt;
  43. extern struct mod mod_tcp_seg;
  44. static struct mod *mods[] = {
  45. &mod_delay,
  46. &mod_drop,
  47. &mod_dup,
  48. &mod_echo,
  49. &mod_ip_chaff,
  50. &mod_ip_frag,
  51. &mod_ip_opt,
  52. &mod_ip_ttl,
  53. &mod_ip_tos,
  54. &mod_ip6_qos,
  55. &mod_ip6_opt,
  56. &mod_order,
  57. &mod_print,
  58. &mod_tcp_chaff,
  59. &mod_tcp_opt,
  60. &mod_tcp_seg,
  61. NULL
  62. };
  63. static TAILQ_HEAD(head, rule) rules;
  64. void
  65. mod_usage(void)
  66. {
  67. struct mod **m;
  68. for (m = mods; *m != NULL; m++) {
  69. fprintf(stderr, " %s\n", (*m)->usage);
  70. }
  71. }
  72. int
  73. mod_open(const char *script, char *errbuf)
  74. {
  75. FILE *fp;
  76. struct mod **m;
  77. struct rule *rule = NULL;
  78. char *argv[MAX_ARGS], buf[BUFSIZ];
  79. int i, argc, ret = 0;
  80. TAILQ_INIT(&rules);
  81. /* open the config/script file */
  82. if ((fp = fopen(script, "r")) == NULL) {
  83. sprintf(errbuf, "couldn't open %s", script);
  84. return (-1);
  85. }
  86. dbg(1, "opened config file...");
  87. /* read the file, one line at a time... */
  88. for (i = 1; fgets(buf, sizeof(buf), fp) != NULL; i++) {
  89. /* skip comments & blank lines */
  90. if (*buf == '#' || *buf == '\r' || *buf == '\n')
  91. continue;
  92. /* parse the line into an array */
  93. if ((argc = argv_create(buf, MAX_ARGS, argv)) < 1) {
  94. sprintf(errbuf, "couldn't parse arguments (line %d)", i);
  95. ret = -1;
  96. break;
  97. }
  98. dbgx(1, "argc = %d, %s, %s, %s", argc, argv[0], argv[1], argv[2]);
  99. /* check first keyword against modules */
  100. for (m = mods; *m != NULL; m++) {
  101. if (strcasecmp((*m)->name, argv[0]) == 0) {
  102. dbgx(1, "comparing %s to %s", argv[0], (*m)->name);
  103. break;
  104. }
  105. }
  106. /* do we have a match? */
  107. if (*m == NULL) {
  108. sprintf(errbuf, "unknown directive '%s' (line %d)", argv[0], i);
  109. ret = -1;
  110. break;
  111. }
  112. /* allocate memory for our rule */
  113. if ((rule = calloc(1, sizeof(*rule))) == NULL) {
  114. sprintf(errbuf, "calloc");
  115. ret = -1;
  116. break;
  117. }
  118. rule->mod = *m;
  119. /* pass the remaining args to the rule */
  120. if (rule->mod->open != NULL &&
  121. (rule->data = rule->mod->open(argc, argv)) == NULL) {
  122. sprintf(errbuf, "invalid argument to directive '%s' (line %d)",
  123. rule->mod->name, i);
  124. ret = -1;
  125. break;
  126. }
  127. /* append the rule to the rule list */
  128. TAILQ_INSERT_TAIL(&rules, rule, next);
  129. }
  130. /* close the file */
  131. fclose(fp);
  132. dbg(1, "close file...");
  133. if (ret == 0) {
  134. buf[0] = '\0';
  135. TAILQ_FOREACH(rule, &rules, next) {
  136. strlcat(buf, rule->mod->name, sizeof(buf));
  137. strlcat(buf, " -> ", sizeof(buf));
  138. }
  139. buf[strlen(buf) - 4] = '\0';
  140. sprintf(errbuf, "wtf: %s", buf);
  141. }
  142. if (rule)
  143. free(rule);
  144. return (ret);
  145. }
  146. void
  147. mod_apply(struct pktq *pktq)
  148. {
  149. struct rule *rule;
  150. TAILQ_FOREACH(rule, &rules, next) {
  151. rule->mod->apply(rule->data, pktq);
  152. }
  153. }
  154. void
  155. mod_close(void)
  156. {
  157. struct rule *rule;
  158. TAILQ_FOREACH_REVERSE(rule, &rules, next, head) {
  159. if (rule->mod->close != NULL)
  160. rule->data = rule->mod->close(rule->data);
  161. TAILQ_REMOVE(&rules, rule, next);
  162. }
  163. }