readpacket.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. /*====================================================================*
  2. *
  3. * Copyright (c) 2013 Qualcomm Atheros, Inc.
  4. *
  5. * All rights reserved.
  6. *
  7. *====================================================================*/
  8. /*====================================================================*
  9. *
  10. * ssize_t readpacket (struct channel const * channel, void * memory, ssize_t extent);
  11. *
  12. * channel.h
  13. *
  14. * read one packet from a raw packet channel;
  15. *
  16. * return the packet size on success, 0 on timeout or -1 on error;
  17. * dump packets on stdout when the channel VERBOSE flag is set;
  18. *
  19. * constant __MAGIC__ enables code that reads frames from stdin,
  20. * instead of the network; you may use it whenever a network or
  21. * transmitting device is not available;
  22. *
  23. *
  24. * Contributor(s):
  25. * Charles Maier <cmaier@qca.qualcomm.com>
  26. * Nathaniel Houghton <nhoughto@qca.qualcomm.com>
  27. * Werner Henze <w.henze@avm.de>
  28. *
  29. *--------------------------------------------------------------------*/
  30. #ifndef READPACKET_SOURCE
  31. #define READPACKET_SOURCE
  32. #include <stdlib.h>
  33. #include <unistd.h>
  34. #include <memory.h>
  35. #include <errno.h>
  36. #include "../ether/channel.h"
  37. #include "../tools/memory.h"
  38. #include "../tools/error.h"
  39. #include "../tools/flags.h"
  40. #if defined (__MAGIC__)
  41. #include "../tools/hexload.c"
  42. #endif
  43. ssize_t readpacket (struct channel const * channel, void * memory, ssize_t extent)
  44. {
  45. #if defined (__MAGIC__)
  46. memset (memory, 0, extent);
  47. extent = hexload (memory, extent, stdin);
  48. if (_anyset (channel->flags, CHANNEL_VERBOSE))
  49. {
  50. hexdump (memory, 0, extent, stdout);
  51. }
  52. return (extent);
  53. #elif defined (__linux__)
  54. #include <sys/poll.h>
  55. struct pollfd pollfd =
  56. {
  57. channel->fd,
  58. POLLIN,
  59. 0
  60. };
  61. signed status = poll (& pollfd, 1, channel->capture);
  62. memset (memory, 0, extent);
  63. if ((status < 0) && (errno != EINTR))
  64. {
  65. error (0, errno, "%s can't poll %s", __func__, channel->ifname);
  66. return (- 1);
  67. }
  68. if (status > 0)
  69. {
  70. status = recvfrom (channel->fd, memory, extent, 0, (struct sockaddr *) (0), (socklen_t *) (0));
  71. if (status < 0)
  72. {
  73. error (0, errno, "%s can't read %s", __func__, channel->ifname);
  74. return (- 1);
  75. }
  76. if (status > 0)
  77. {
  78. extent = status;
  79. if (_anyset (channel->flags, CHANNEL_VERBOSE))
  80. {
  81. hexdump (memory, 0, extent, stdout);
  82. }
  83. return (extent);
  84. }
  85. }
  86. #elif defined (__APPLE__) || defined (__OpenBSD__)
  87. struct bpf_hdr * bpf_packet;
  88. struct bpf * bpf = channel->bpf; ;
  89. memset (memory, 0, extent);
  90. if (bpf->bpf_bufused <= 0)
  91. {
  92. bpf->bpf_bufused = read (channel->fd, bpf->bpf_buffer, bpf->bpf_length);
  93. bpf->bpf_bp = bpf->bpf_buffer;
  94. }
  95. if (bpf->bpf_bufused < 0)
  96. {
  97. error (0, errno, "bpf");
  98. return (- 1);
  99. }
  100. if (bpf->bpf_bufused > 0)
  101. {
  102. bpf_packet = (struct bpf_hdr *) (bpf->bpf_bp);
  103. if ((size_t) (extent) > bpf_packet->bh_caplen)
  104. {
  105. extent = bpf_packet->bh_caplen;
  106. }
  107. if ((size_t) (extent) < bpf_packet->bh_caplen)
  108. {
  109. if (_anyset (channel->flags, CHANNEL_VERBOSE))
  110. {
  111. error (0, 0, "Truncated incoming frame (%u -> %zd bytes)", bpf_packet->bh_caplen, extent);
  112. }
  113. }
  114. memcpy (memory, bpf->bpf_bp + bpf_packet->bh_hdrlen, extent);
  115. bpf->bpf_bufused -= BPF_WORDALIGN (bpf_packet->bh_hdrlen + bpf_packet->bh_caplen);
  116. bpf->bpf_bp += BPF_WORDALIGN (bpf_packet->bh_hdrlen + bpf_packet->bh_caplen);
  117. if (_anyset (channel->flags, CHANNEL_VERBOSE))
  118. {
  119. hexdump (memory, 0, extent, stdout);
  120. }
  121. return (extent);
  122. }
  123. #elif defined (WINPCAP) || defined (LIBPCAP)
  124. struct pcap_pkthdr * header;
  125. const uint8_t * data;
  126. signed status = pcap_next_ex (channel->socket, & header, & data);
  127. memset (memory, 0, extent);
  128. if (status < 0)
  129. {
  130. error (0, errno, "pcap_next_ex");
  131. return (- 1);
  132. }
  133. if (status > 0)
  134. {
  135. extent = header->caplen;
  136. memcpy (memory, data, extent);
  137. if (_anyset (channel->flags, CHANNEL_VERBOSE))
  138. {
  139. hexdump (memory, 0, extent, stdout);
  140. }
  141. return (extent);
  142. }
  143. #else
  144. #error "Unknown Environment"
  145. #endif
  146. return (0);
  147. }
  148. #endif