udpdump.c 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. /*
  2. * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy)
  3. * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California)
  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 name of the Politecnico di Torino, CACE Technologies
  16. * nor the names of its contributors may be used to endorse or promote
  17. * products derived from this software without specific prior written
  18. * permission.
  19. *
  20. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  21. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  22. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  23. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  24. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  25. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  26. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  27. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  28. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  29. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  30. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31. *
  32. */
  33. #include <pcap.h>
  34. #include <time.h>
  35. #include <Winsock2.h>
  36. #include <tchar.h>
  37. BOOL LoadNpcapDlls()
  38. {
  39. _TCHAR npcap_dir[512];
  40. UINT len;
  41. len = GetSystemDirectory(npcap_dir, 480);
  42. if (!len) {
  43. fprintf(stderr, "Error in GetSystemDirectory: %x", GetLastError());
  44. return FALSE;
  45. }
  46. _tcscat_s(npcap_dir, 512, _T("\\Npcap"));
  47. if (SetDllDirectory(npcap_dir) == 0) {
  48. fprintf(stderr, "Error in SetDllDirectory: %x", GetLastError());
  49. return FALSE;
  50. }
  51. return TRUE;
  52. }
  53. /* 4 bytes IP address */
  54. typedef struct ip_address{
  55. u_char byte1;
  56. u_char byte2;
  57. u_char byte3;
  58. u_char byte4;
  59. }ip_address;
  60. /* IPv4 header */
  61. typedef struct ip_header{
  62. u_char ver_ihl; // Version (4 bits) + Internet header length (4 bits)
  63. u_char tos; // Type of service
  64. u_short tlen; // Total length
  65. u_short identification; // Identification
  66. u_short flags_fo; // Flags (3 bits) + Fragment offset (13 bits)
  67. u_char ttl; // Time to live
  68. u_char proto; // Protocol
  69. u_short crc; // Header checksum
  70. ip_address saddr; // Source address
  71. ip_address daddr; // Destination address
  72. u_int op_pad; // Option + Padding
  73. }ip_header;
  74. /* UDP header*/
  75. typedef struct udp_header{
  76. u_short sport; // Source port
  77. u_short dport; // Destination port
  78. u_short len; // Datagram length
  79. u_short crc; // Checksum
  80. }udp_header;
  81. /* prototype of the packet handler */
  82. void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data);
  83. int main()
  84. {
  85. pcap_if_t *alldevs;
  86. pcap_if_t *d;
  87. int inum;
  88. int i=0;
  89. pcap_t *adhandle;
  90. char errbuf[PCAP_ERRBUF_SIZE];
  91. u_int netmask;
  92. char packet_filter[] = "ip and udp";
  93. struct bpf_program fcode;
  94. /* Load Npcap and its functions. */
  95. if (!LoadNpcapDlls())
  96. {
  97. fprintf(stderr, "Couldn't load Npcap\n");
  98. exit(1);
  99. }
  100. /* Retrieve the device list */
  101. if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1)
  102. {
  103. fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf);
  104. exit(1);
  105. }
  106. /* Print the list */
  107. for(d=alldevs; d; d=d->next)
  108. {
  109. printf("%d. %s", ++i, d->name);
  110. if (d->description)
  111. printf(" (%s)\n", d->description);
  112. else
  113. printf(" (No description available)\n");
  114. }
  115. if(i==0)
  116. {
  117. printf("\nNo interfaces found! Make sure Npcap is installed.\n");
  118. return -1;
  119. }
  120. printf("Enter the interface number (1-%d):",i);
  121. scanf_s("%d", &inum);
  122. if(inum < 1 || inum > i)
  123. {
  124. printf("\nInterface number out of range.\n");
  125. /* Free the device list */
  126. pcap_freealldevs(alldevs);
  127. return -1;
  128. }
  129. /* Jump to the selected adapter */
  130. for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++);
  131. /* Open the adapter */
  132. if ( (adhandle= pcap_open(d->name, // name of the device
  133. 65536, // portion of the packet to capture.
  134. // 65536 grants that the whole packet will be captured on all the MACs.
  135. PCAP_OPENFLAG_PROMISCUOUS, // promiscuous mode
  136. 1000, // read timeout
  137. NULL, // remote authentication
  138. errbuf // error buffer
  139. ) ) == NULL)
  140. {
  141. fprintf(stderr,"\nUnable to open the adapter. %s is not supported by Npcap\n", d->name);
  142. /* Free the device list */
  143. pcap_freealldevs(alldevs);
  144. return -1;
  145. }
  146. /* Check the link layer. We support only Ethernet for simplicity. */
  147. if(pcap_datalink(adhandle) != DLT_EN10MB)
  148. {
  149. fprintf(stderr,"\nThis program works only on Ethernet networks.\n");
  150. /* Free the device list */
  151. pcap_freealldevs(alldevs);
  152. return -1;
  153. }
  154. if(d->addresses != NULL)
  155. /* Retrieve the mask of the first address of the interface */
  156. netmask=((struct sockaddr_in *)(d->addresses->netmask))->sin_addr.S_un.S_addr;
  157. else
  158. /* If the interface is without addresses we suppose to be in a C class network */
  159. netmask=0xffffff;
  160. //compile the filter
  161. if (pcap_compile(adhandle, &fcode, packet_filter, 1, netmask) <0 )
  162. {
  163. fprintf(stderr,"\nUnable to compile the packet filter. Check the syntax.\n");
  164. /* Free the device list */
  165. pcap_freealldevs(alldevs);
  166. return -1;
  167. }
  168. //set the filter
  169. if (pcap_setfilter(adhandle, &fcode)<0)
  170. {
  171. fprintf(stderr,"\nError setting the filter.\n");
  172. /* Free the device list */
  173. pcap_freealldevs(alldevs);
  174. return -1;
  175. }
  176. printf("\nlistening on %s...\n", d->description);
  177. /* At this point, we don't need any more the device list. Free it */
  178. pcap_freealldevs(alldevs);
  179. /* start the capture */
  180. pcap_loop(adhandle, 0, packet_handler, NULL);
  181. return 0;
  182. }
  183. /* Callback function invoked by libpcap for every incoming packet */
  184. void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data)
  185. {
  186. struct tm ltime;
  187. char timestr[16];
  188. ip_header *ih;
  189. udp_header *uh;
  190. u_int ip_len;
  191. u_short sport,dport;
  192. time_t local_tv_sec;
  193. /*
  194. * Unused variable
  195. */
  196. (VOID)(param);
  197. /* convert the timestamp to readable format */
  198. local_tv_sec = header->ts.tv_sec;
  199. localtime_s(&ltime, &local_tv_sec);
  200. strftime( timestr, sizeof timestr, "%H:%M:%S", &ltime);
  201. /* print timestamp and length of the packet */
  202. printf("%s.%.6d len:%d ", timestr, header->ts.tv_usec, header->len);
  203. /* retireve the position of the ip header */
  204. ih = (ip_header *) (pkt_data +
  205. 14); //length of ethernet header
  206. /* retireve the position of the udp header */
  207. ip_len = (ih->ver_ihl & 0xf) * 4;
  208. uh = (udp_header *) ((u_char*)ih + ip_len);
  209. /* convert from network byte order to host byte order */
  210. sport = ntohs( uh->sport );
  211. dport = ntohs( uh->dport );
  212. /* print ip addresses and udp ports */
  213. printf("%d.%d.%d.%d.%d -> %d.%d.%d.%d.%d\n",
  214. ih->saddr.byte1,
  215. ih->saddr.byte2,
  216. ih->saddr.byte3,
  217. ih->saddr.byte4,
  218. sport,
  219. ih->daddr.byte1,
  220. ih->daddr.byte2,
  221. ih->daddr.byte3,
  222. ih->daddr.byte4,
  223. dport);
  224. }