1
0

mod.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  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 "mod.h"
  10. #include "defines.h"
  11. #include "config.h"
  12. #include "common.h"
  13. #include "argv.h"
  14. #include "lib/queue.h"
  15. #include <ctype.h>
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include <string.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[] = {&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. static TAILQ_HEAD(head, rule) rules;
  62. void
  63. mod_usage(void)
  64. {
  65. struct mod **m;
  66. for (m = mods; *m != NULL; m++) {
  67. fprintf(stderr, " %s\n", (*m)->usage);
  68. }
  69. }
  70. int
  71. mod_open(const char *script, char *errbuf)
  72. {
  73. FILE *fp;
  74. struct mod **m;
  75. struct rule *rule = NULL;
  76. char *argv[MAX_ARGS], buf[BUFSIZ];
  77. int i, argc, ret = 0;
  78. TAILQ_INIT(&rules);
  79. /* open the config/script file */
  80. if ((fp = fopen(script, "r")) == NULL) {
  81. sprintf(errbuf, "couldn't open %s", script);
  82. return (-1);
  83. }
  84. dbg(1, "opened config file...");
  85. /* read the file, one line at a time... */
  86. for (i = 1; fgets(buf, sizeof(buf), fp) != NULL; i++) {
  87. /* skip comments & blank lines */
  88. if (*buf == '#' || *buf == '\r' || *buf == '\n')
  89. continue;
  90. /* parse the line into an array */
  91. if ((argc = argv_create(buf, MAX_ARGS, argv)) < 1) {
  92. sprintf(errbuf, "couldn't parse arguments (line %d)", i);
  93. ret = -1;
  94. break;
  95. }
  96. dbgx(1, "argc = %d, %s, %s, %s", argc, argv[0], argv[1], argv[2]);
  97. /* check first keyword against modules */
  98. for (m = mods; *m != NULL; m++) {
  99. if (strcasecmp((*m)->name, argv[0]) == 0) {
  100. dbgx(1, "comparing %s to %s", argv[0], (*m)->name);
  101. break;
  102. }
  103. }
  104. /* do we have a match? */
  105. if (*m == NULL) {
  106. sprintf(errbuf, "unknown directive '%s' (line %d)", argv[0], i);
  107. ret = -1;
  108. break;
  109. }
  110. /* allocate memory for our rule */
  111. if ((rule = calloc(1, sizeof(*rule))) == NULL) {
  112. sprintf(errbuf, "calloc");
  113. ret = -1;
  114. break;
  115. }
  116. rule->mod = *m;
  117. /* pass the remaining args to the rule */
  118. if (rule->mod->open != NULL && (rule->data = rule->mod->open(argc, argv)) == NULL) {
  119. sprintf(errbuf, "invalid argument to directive '%s' (line %d)", rule->mod->name, i);
  120. ret = -1;
  121. break;
  122. }
  123. /* append the rule to the rule list */
  124. TAILQ_INSERT_TAIL(&rules, rule, next);
  125. }
  126. /* close the file */
  127. fclose(fp);
  128. dbg(1, "close file...");
  129. if (ret == 0) {
  130. buf[0] = '\0';
  131. TAILQ_FOREACH(rule, &rules, next)
  132. {
  133. strlcat(buf, rule->mod->name, sizeof(buf));
  134. strlcat(buf, " -> ", sizeof(buf));
  135. }
  136. buf[strlen(buf) - 4] = '\0';
  137. sprintf(errbuf, "wtf: %s", buf);
  138. }
  139. if (rule)
  140. free(rule);
  141. return (ret);
  142. }
  143. void
  144. mod_apply(struct pktq *pktq)
  145. {
  146. struct rule *rule;
  147. TAILQ_FOREACH(rule, &rules, next)
  148. {
  149. rule->mod->apply(rule->data, pktq);
  150. }
  151. }
  152. void
  153. mod_close(void)
  154. {
  155. struct rule *rule;
  156. TAILQ_FOREACH_REVERSE(rule, &rules, next, head)
  157. {
  158. if (rule->mod->close != NULL)
  159. rule->data = rule->mod->close(rule->data);
  160. TAILQ_REMOVE(&rules, rule, next);
  161. }
  162. }