fragroute.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. /*
  2. * fragroute.c
  3. *
  4. * Copyright (c) 2001 Dug Song <dugsong@monkey.org>
  5. * Copyright (c) 2007-2008 Aaron Turner.
  6. * $Id: fragroute.c 2000 2008-04-27 06:17:35Z aturner $
  7. */
  8. #include "config.h"
  9. #include "defines.h"
  10. #include "common.h"
  11. #include <signal.h>
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <string.h>
  15. #include <unistd.h>
  16. /* need to undef these which are pulled in via defines.h, prior to importing dnet.h */
  17. #undef icmp_id
  18. #undef icmp_seq
  19. #undef icmp_data
  20. #undef icmp_mask
  21. #include <dnet.h>
  22. #include "fragroute.h"
  23. #include "pkt.h"
  24. #include "mod.h"
  25. // #include "tun.h"
  26. void
  27. fragroute_close(fragroute_t *ctx)
  28. {
  29. free(ctx->pktq);
  30. free(ctx);
  31. ctx = NULL;
  32. }
  33. int
  34. fragroute_process(fragroute_t *ctx, void *buf, size_t len)
  35. {
  36. struct pkt *pkt;
  37. int l2len;
  38. assert(ctx);
  39. assert(buf);
  40. ctx->first_packet = 0;
  41. /* save the l2 header of the original packet for later */
  42. ctx->l2len = get_l2len(buf, len, ctx->dlt);
  43. memcpy(ctx->l2header, buf, ctx->l2len);
  44. if ((pkt = pkt_new()) == NULL) {
  45. strcpy(ctx->errbuf, "unable to pkt_new()");
  46. return -1;
  47. }
  48. if (len > PKT_BUF_LEN) {
  49. sprintf(ctx->errbuf, "skipping oversized packet: %zu", len);
  50. return -1;
  51. }
  52. memcpy(pkt->pkt_data, buf, len);
  53. pkt->pkt_end = pkt->pkt_data + len;
  54. pkt_decorate(pkt);
  55. if (pkt->pkt_ip == NULL) {
  56. strcpy(ctx->errbuf, "skipping non-IP packet");
  57. return -1;
  58. }
  59. ip_checksum(pkt->pkt_ip, len);
  60. TAILQ_INIT(ctx->pktq);
  61. TAILQ_INSERT_TAIL(ctx->pktq, pkt, pkt_next);
  62. mod_apply(ctx->pktq);
  63. return 0;
  64. }
  65. /*
  66. * keep calling this after fragroute_process() to get all the fragments.
  67. * Each call returns the fragment length which is stored in **packet.
  68. * Returns 0 when no more fragments remain or -1 on error
  69. */
  70. int
  71. fragroute_getfragment(fragroute_t *ctx, char **packet)
  72. {
  73. static struct pkt *pkt = NULL;
  74. static struct pkt *next = NULL;
  75. char *pkt_data = *packet;
  76. u_int32_t length;
  77. if (ctx->first_packet != 0) {
  78. pkt = next;
  79. } else {
  80. ctx->first_packet = 1;
  81. pkt = TAILQ_FIRST(ctx->pktq);
  82. }
  83. if (pkt != TAILQ_END(&(ctx->pktq))) {
  84. next = TAILQ_NEXT(pkt, pkt_next);
  85. memcpy(pkt_data, pkt->pkt_data, pkt->pkt_end - pkt->pkt_data);
  86. /* return the original L2 header */
  87. memcpy(pkt_data, ctx->l2header, ctx->l2len);
  88. length = pkt->pkt_end - pkt->pkt_data;
  89. pkt = next;
  90. return length;
  91. }
  92. return 0; // nothing
  93. }
  94. fragroute_t *
  95. fragroute_init(const int mtu, const int dlt, const char *config, char *errbuf)
  96. {
  97. fragroute_t *ctx;
  98. if (dlt != DLT_EN10MB) {
  99. sprintf(errbuf, "Fragroute only supports DLT_EN10MB pcap files");
  100. return NULL;
  101. }
  102. ctx = (fragroute_t *)safe_malloc(sizeof(fragroute_t));
  103. ctx->pktq = (struct pktq *)safe_malloc(sizeof(struct pktq));
  104. ctx->dlt = dlt;
  105. pkt_init(128);
  106. ctx->mtu = mtu;
  107. /* parse the config */
  108. if (mod_open(config, errbuf) < 0) {
  109. fragroute_close(ctx);
  110. return NULL;
  111. }
  112. return ctx;
  113. }