libpcap.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. /* $Id: libpcap.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 <stdio.h>
  33. #include <unistd.h>
  34. #include <sys/types.h>
  35. #include "capinfo.h"
  36. #include "libpcap.h"
  37. #include "err.h"
  38. #include "fakepcap.h"
  39. /* state of the current pcap file */
  40. struct pcap_file_header phdr;
  41. int modified;
  42. int swapped;
  43. /* return flag if this is a pcap file */
  44. int
  45. is_pcap(int fd)
  46. {
  47. if (lseek(fd, SEEK_SET, 0) != 0) {
  48. err(1, "Unable to seek to start of file");
  49. }
  50. if (read(fd, (void *)&phdr, sizeof(phdr)) != sizeof(phdr))
  51. return 0;
  52. switch (phdr.magic) {
  53. case PCAP_MAGIC:
  54. swapped = 0;
  55. modified = 0;
  56. break;
  57. case PCAP_SWAPPED_MAGIC:
  58. swapped = 1;
  59. modified = 0;
  60. break;
  61. case PCAP_MODIFIED_MAGIC:
  62. swapped = 0;
  63. modified = 1;
  64. break;
  65. case PCAP_SWAPPED_MODIFIED_MAGIC:
  66. swapped = 1;
  67. modified = 1;
  68. break;
  69. default:
  70. return 0;
  71. }
  72. /* ensure everything is in host-byte order */
  73. if (swapped) {
  74. phdr.version_major = SWAPSHORT(phdr.version_major);
  75. phdr.version_minor = SWAPSHORT(phdr.version_minor);
  76. phdr.snaplen = SWAPLONG(phdr.snaplen);
  77. phdr.linktype = SWAPLONG(phdr.linktype);
  78. }
  79. /* version, snaplen, & linktype magic */
  80. if (phdr.version_major != 2)
  81. return 0;
  82. return 1;
  83. }
  84. int
  85. get_next_pcap(int fd, struct packet *pkt)
  86. {
  87. struct pcap_pkthdr p1, *p;
  88. struct pcap_mod_pkthdr p2;
  89. if (modified) {
  90. if (read(fd, &p2, sizeof(p2)) != sizeof(p2))
  91. return 0;
  92. p = &p2.hdr;
  93. }
  94. else {
  95. if (read(fd, &p1, sizeof(p1)) != sizeof(p1))
  96. return 0;
  97. p = &p1;
  98. }
  99. if (swapped) {
  100. pkt->len = SWAPLONG(p->caplen);
  101. pkt->ts.tv_sec = SWAPLONG(p->ts.tv_sec);
  102. pkt->ts.tv_usec = SWAPLONG(p->ts.tv_usec);
  103. pkt->actual_len = SWAPLONG(p->len);
  104. }
  105. else {
  106. pkt->len = p->caplen;
  107. pkt->ts = p->ts;
  108. pkt->actual_len = p->len;
  109. }
  110. if (read(fd, &pkt->data, pkt->len) != pkt->len)
  111. return 0;
  112. return pkt->len;
  113. }
  114. /*
  115. * Print statistics about a pcap file. is_pcap() must be called first
  116. * to read the pcap header.
  117. */
  118. void
  119. stat_pcap(int fd, struct pcap_info *p)
  120. {
  121. struct packet pkt;
  122. char *endian[2];
  123. #ifdef LIBNET_LIL_ENDIAN
  124. endian[0] = "little endian";
  125. endian[1] = "big endian";
  126. #else
  127. endian[0] = "big endian";
  128. endian[1] = "little endian";
  129. #endif
  130. p->modified = modified;
  131. p->swapped = swapped ? endian[1] : endian[0];
  132. p->phdr = phdr;
  133. p->linktype = pcap_datalink_val_to_description(phdr.linktype);
  134. p->bytes = p->trunc = 0;
  135. for (p->cnt = 0; get_next_pcap(fd, &pkt); p->cnt++) {
  136. /* grab time of the first packet */
  137. if (p->cnt == 0)
  138. TIMEVAL_TO_TIMESPEC(&pkt.ts, &p->start_tm);
  139. /* count p->truncated packets */
  140. p->bytes += pkt.len;
  141. if (pkt.actual_len > phdr.snaplen)
  142. p->trunc++;
  143. }
  144. /* grab time of the last packet */
  145. TIMEVAL_TO_TIMESPEC(&pkt.ts, &p->finish_tm);
  146. }