mod.c 3.7 KB

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