fragroute.c 3.5 KB

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