mod.c 3.7 KB

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