mod_ip_chaff.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. /*
  2. * mod_ip_chaff.c
  3. *
  4. * Copyright (c) 2001 Dug Song <dugsong@monkey.org>
  5. *
  6. * $Id: mod_ip_chaff.c 2000 2008-04-27 06:17:35Z aturner $
  7. */
  8. #include "config.h"
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include "mod.h"
  13. #include "pkt.h"
  14. #include "randutil.h"
  15. #define CHAFF_TYPE_DUP 1
  16. #define CHAFF_TYPE_OPT 2
  17. #define CHAFF_TYPE_TTL 3
  18. struct ip_chaff_data {
  19. rand_t *rnd;
  20. int type;
  21. int ttl;
  22. struct pktq *pktq;
  23. };
  24. void *
  25. ip_chaff_close(void *d)
  26. {
  27. struct ip_chaff_data *data = (struct ip_chaff_data *)d;
  28. if (data != NULL) {
  29. rand_close(data->rnd);
  30. free(data);
  31. }
  32. return (NULL);
  33. }
  34. void *
  35. ip_chaff_open(int argc, char *argv[])
  36. {
  37. struct ip_chaff_data *data;
  38. if (argc < 2)
  39. return (NULL);
  40. if ((data = calloc(1, sizeof(*data))) == NULL)
  41. return (NULL);
  42. data->rnd = rand_open();
  43. if (strcasecmp(argv[1], "dup") == 0) {
  44. data->type = CHAFF_TYPE_DUP;
  45. } else if (strcasecmp(argv[1], "opt") == 0) {
  46. data->type = CHAFF_TYPE_OPT;
  47. } else if ((data->ttl = atoi(argv[1])) >= 0 && data->ttl < 256) {
  48. data->type = CHAFF_TYPE_TTL;
  49. } else
  50. return (ip_chaff_close(data));
  51. return (data);
  52. }
  53. int
  54. ip_chaff_apply(void *d, struct pktq *pktq)
  55. {
  56. struct ip_chaff_data *data = (struct ip_chaff_data *)d;
  57. struct pkt *pkt, *new, *next;
  58. struct ip_opt opt;
  59. int i;
  60. for (pkt = TAILQ_FIRST(pktq); pkt != TAILQ_END(pktq); pkt = next) {
  61. next = TAILQ_NEXT(pkt, pkt_next);
  62. if (pkt->pkt_ip_data == NULL)
  63. continue;
  64. new = pkt_dup(pkt);
  65. rand_strset(data->rnd, new->pkt_ip_data,
  66. new->pkt_end - new->pkt_ip_data + 1);
  67. switch (data->type) {
  68. case CHAFF_TYPE_DUP:
  69. new->pkt_ts.tv_usec = 1;
  70. ip_checksum(new->pkt_ip, new->pkt_ip_data -
  71. new->pkt_eth_data);
  72. break;
  73. case CHAFF_TYPE_OPT:
  74. opt.opt_type = 0x42;
  75. opt.opt_len = IP_OPT_LEN;
  76. i = ip_add_option(new->pkt_ip,
  77. PKT_BUF_LEN - ETH_HDR_LEN, IP_PROTO_IP,
  78. &opt, opt.opt_len);
  79. /* XXX - whack opt with random crap */
  80. *(uint32_t *)new->pkt_ip_data = rand_uint32(data->rnd);
  81. new->pkt_ip_data += i;
  82. new->pkt_end += i;
  83. ip_checksum(new->pkt_ip, new->pkt_ip_data -
  84. new->pkt_eth_data);
  85. break;
  86. case CHAFF_TYPE_TTL:
  87. new->pkt_ip->ip_ttl = data->ttl;
  88. ip_checksum(new->pkt_ip, new->pkt_ip_data -
  89. new->pkt_eth_data);
  90. break;
  91. }
  92. /* Minimal random reordering. */
  93. if ((pkt->pkt_ip->ip_sum & 1) == 0)
  94. TAILQ_INSERT_BEFORE(pkt, new, pkt_next);
  95. else
  96. TAILQ_INSERT_AFTER(pktq, pkt, new, pkt_next);
  97. }
  98. return (0);
  99. }
  100. struct mod mod_ip_chaff = {
  101. "ip_chaff", /* name */
  102. "ip_chaff dup|opt|<ttl>", /* usage */
  103. ip_chaff_open, /* open */
  104. ip_chaff_apply, /* apply */
  105. ip_chaff_close /* close */
  106. };