snoop.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. /* $Id: snoop.c 767 2004-10-06 12:48:49Z aturner $ */
  2. /*
  3. * Copyright (c) 2001-2004 Aaron Turner, Matt Bing.
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions
  8. * are met:
  9. *
  10. * 1. Redistributions of source code must retain the above copyright
  11. * notice, this list of conditions and the following disclaimer.
  12. * 2. Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in the
  14. * documentation and/or other materials provided with the distribution.
  15. * 3. Neither the names of the copyright owners nor the names of its
  16. * contributors may be used to endorse or promote products derived from
  17. * this software without specific prior written permission.
  18. *
  19. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
  20. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  21. * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  22. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  23. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  24. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
  25. * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  26. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
  27. * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  28. * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  29. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30. */
  31. #include "config.h"
  32. #include <fcntl.h>
  33. #include <stdio.h>
  34. #include <string.h>
  35. #include <unistd.h>
  36. #include <netinet/in.h>
  37. #include <sys/time.h>
  38. #include <sys/types.h>
  39. #include "capinfo.h"
  40. #include "snoop.h"
  41. #include "err.h"
  42. char *snoop_links[] = {
  43. "ethernet",
  44. "unknown",
  45. "token ring",
  46. "unknown",
  47. "ethernet",
  48. "HDLC",
  49. "character synchronous",
  50. "IBM channel to channel",
  51. "FDDI bitswapped",
  52. "unknown",
  53. "frame relay LAPD",
  54. "frame relay",
  55. "character asynchronous (PPP/SLIP)",
  56. "X.25",
  57. "loopback",
  58. "unknown",
  59. "fibre channel",
  60. "ATM",
  61. "ATM",
  62. "X.25 LAPB",
  63. "ISDN",
  64. "HIPPI",
  65. "100VG-AnyLAN ethernet",
  66. "100VG-AnyLAN token ring",
  67. "ethernet",
  68. "100Base-T ethernet",
  69. NULL
  70. };
  71. #define LINKSIZE (sizeof(snoop_links) / sizeof(snoop_links[0]) - 1)
  72. struct snoop_hdr shdr;
  73. int
  74. is_snoop(int fd)
  75. {
  76. char *snoop_magic = SNOOP_MAGIC;
  77. if (lseek(fd, SEEK_SET, 0) != 0) {
  78. err(1, "Unable to seek to start of file");
  79. }
  80. if (read(fd, &shdr, sizeof(shdr)) != sizeof(shdr))
  81. return 0;
  82. if (memcmp(&shdr.magic, snoop_magic, sizeof(shdr.magic)) == 0) {
  83. shdr.version = ntohl(shdr.version);
  84. shdr.network = ntohl(shdr.network);
  85. /* Dunno about snoop format history, but 2 definately works */
  86. if (shdr.version != 2)
  87. return 0;
  88. return 1;
  89. }
  90. return 0;
  91. }
  92. int
  93. get_next_snoop(int fd, struct packet *pkt)
  94. {
  95. struct snoop_rec rec;
  96. int pad;
  97. if (read(fd, &rec, sizeof(rec)) != sizeof(rec))
  98. return 0;
  99. pkt->len = ntohl(rec.incl_len);
  100. pkt->actual_len = ntohl(rec.orig_len);
  101. pkt->ts.tv_sec = ntohl(rec.ts_sec);
  102. pkt->ts.tv_usec = ntohl(rec.ts_usec);
  103. if (read(fd, &pkt->data, pkt->len) != pkt->len)
  104. return 0;
  105. /* Skip padding */
  106. pad = ntohl(rec.rec_len) - (sizeof(rec) + pkt->len);
  107. if (lseek(fd, pad, SEEK_CUR) == -1)
  108. return 0;
  109. return pkt->len;
  110. }
  111. void
  112. stat_snoop(int fd, struct snoop_info *p)
  113. {
  114. struct packet pkt;
  115. p->version = shdr.version;
  116. if (shdr.network > LINKSIZE)
  117. p->linktype = "unknown linktype";
  118. else
  119. p->linktype = snoop_links[shdr.network];
  120. p->bytes = p->trunc = 0;
  121. for (p->cnt = 0; get_next_snoop(fd, &pkt); p->cnt++) {
  122. /* grab time of the first packet */
  123. if (p->cnt == 0)
  124. TIMEVAL_TO_TIMESPEC(&pkt.ts, &p->start_tm);
  125. /* count truncated packets */
  126. p->bytes += pkt.len;
  127. if (pkt.actual_len > pkt.len)
  128. p->trunc++;
  129. }
  130. /* grab time of the last packet */
  131. TIMEVAL_TO_TIMESPEC(&pkt.ts, &p->finish_tm);
  132. }