udpdump.c 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  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. #ifdef _MSC_VER
  34. /*
  35. * we do not want the warnings about the old deprecated and unsecure CRT functions
  36. * since these examples can be compiled under *nix as well
  37. */
  38. #define _CRT_SECURE_NO_WARNINGS
  39. #endif
  40. #include <pcap.h>
  41. #include <time.h>
  42. #ifdef _WIN32
  43. #include <tchar.h>
  44. BOOL LoadNpcapDlls()
  45. {
  46. _TCHAR npcap_dir[512];
  47. UINT len;
  48. len = GetSystemDirectory(npcap_dir, 480);
  49. if (!len) {
  50. fprintf(stderr, "Error in GetSystemDirectory: %x", GetLastError());
  51. return FALSE;
  52. }
  53. _tcscat_s(npcap_dir, 512, _T("\\Npcap"));
  54. if (SetDllDirectory(npcap_dir) == 0) {
  55. fprintf(stderr, "Error in SetDllDirectory: %x", GetLastError());
  56. return FALSE;
  57. }
  58. return TRUE;
  59. }
  60. #endif
  61. /* 4 bytes IP address */
  62. typedef struct ip_address
  63. {
  64. u_char byte1;
  65. u_char byte2;
  66. u_char byte3;
  67. u_char byte4;
  68. }ip_address;
  69. /* IPv4 header */
  70. typedef struct ip_header
  71. {
  72. u_char ver_ihl; // Version (4 bits) + Internet header length (4 bits)
  73. u_char tos; // Type of service
  74. u_short tlen; // Total length
  75. u_short identification; // Identification
  76. u_short flags_fo; // Flags (3 bits) + Fragment offset (13 bits)
  77. u_char ttl; // Time to live
  78. u_char proto; // Protocol
  79. u_short crc; // Header checksum
  80. ip_address saddr; // Source address
  81. ip_address daddr; // Destination address
  82. u_int op_pad; // Option + Padding
  83. }ip_header;
  84. /* UDP header*/
  85. typedef struct udp_header
  86. {
  87. u_short sport; // Source port
  88. u_short dport; // Destination port
  89. u_short len; // Datagram length
  90. u_short crc; // Checksum
  91. }udp_header;
  92. /* prototype of the packet handler */
  93. void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data);
  94. int main()
  95. {
  96. pcap_if_t *alldevs;
  97. pcap_if_t *d;
  98. int inum;
  99. int i=0;
  100. pcap_t *adhandle;
  101. char errbuf[PCAP_ERRBUF_SIZE];
  102. u_int netmask;
  103. char packet_filter[] = "ip and udp";
  104. struct bpf_program fcode;
  105. #ifdef _WIN32
  106. /* Load Npcap and its functions. */
  107. if (!LoadNpcapDlls())
  108. {
  109. fprintf(stderr, "Couldn't load Npcap\n");
  110. exit(1);
  111. }
  112. #endif
  113. /* Retrieve the device list */
  114. if(pcap_findalldevs(&alldevs, errbuf) == -1)
  115. {
  116. fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf);
  117. exit(1);
  118. }
  119. /* Print the list */
  120. for(d=alldevs; d; d=d->next)
  121. {
  122. printf("%d. %s", ++i, d->name);
  123. if (d->description)
  124. printf(" (%s)\n", d->description);
  125. else
  126. printf(" (No description available)\n");
  127. }
  128. if(i==0)
  129. {
  130. printf("\nNo interfaces found! Make sure Npcap is installed.\n");
  131. return -1;
  132. }
  133. printf("Enter the interface number (1-%d):",i);
  134. scanf("%d", &inum);
  135. /* Check if the user specified a valid adapter */
  136. if(inum < 1 || inum > i)
  137. {
  138. printf("\nAdapter number out of range.\n");
  139. /* Free the device list */
  140. pcap_freealldevs(alldevs);
  141. return -1;
  142. }
  143. /* Jump to the selected adapter */
  144. for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++);
  145. /* Open the adapter */
  146. if ((adhandle= pcap_open_live(d->name, // name of the device
  147. 65536, // portion of the packet to capture.
  148. // 65536 grants that the whole packet will be captured on all the MACs.
  149. 1, // promiscuous mode (nonzero means promiscuous)
  150. 1000, // read timeout
  151. errbuf // error buffer
  152. )) == NULL)
  153. {
  154. fprintf(stderr,"\nUnable to open the adapter: %s\n", errbuf);
  155. /* Free the device list */
  156. pcap_freealldevs(alldevs);
  157. return -1;
  158. }
  159. /* Check the link layer. We support only Ethernet for simplicity. */
  160. if(pcap_datalink(adhandle) != DLT_EN10MB)
  161. {
  162. fprintf(stderr,"\nThis program works only on Ethernet networks.\n");
  163. /* Free the device list */
  164. pcap_freealldevs(alldevs);
  165. return -1;
  166. }
  167. if(d->addresses != NULL)
  168. /* Retrieve the mask of the first address of the interface */
  169. netmask=((struct sockaddr_in *)(d->addresses->netmask))->sin_addr.S_un.S_addr;
  170. else
  171. /* If the interface is without addresses we suppose to be in a C class network */
  172. netmask=0xffffff;
  173. //compile the filter
  174. if (pcap_compile(adhandle, &fcode, packet_filter, 1, netmask) <0 )
  175. {
  176. fprintf(stderr,"\nUnable to compile the packet filter. Check the syntax.\n");
  177. /* Free the device list */
  178. pcap_freealldevs(alldevs);
  179. return -1;
  180. }
  181. //set the filter
  182. if (pcap_setfilter(adhandle, &fcode)<0)
  183. {
  184. fprintf(stderr,"\nError setting the filter.\n");
  185. /* Free the device list */
  186. pcap_freealldevs(alldevs);
  187. return -1;
  188. }
  189. printf("\nlistening on %s...\n", d->description);
  190. /* At this point, we don't need any more the device list. Free it */
  191. pcap_freealldevs(alldevs);
  192. /* start the capture */
  193. pcap_loop(adhandle, 0, packet_handler, NULL);
  194. return 0;
  195. }
  196. /* Callback function invoked by libpcap for every incoming packet */
  197. void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data)
  198. {
  199. struct tm *ltime;
  200. char timestr[16];
  201. ip_header *ih;
  202. udp_header *uh;
  203. u_int ip_len;
  204. u_short sport,dport;
  205. time_t local_tv_sec;
  206. /*
  207. * unused parameter
  208. */
  209. (VOID)(param);
  210. /* convert the timestamp to readable format */
  211. local_tv_sec = header->ts.tv_sec;
  212. ltime=localtime(&local_tv_sec);
  213. strftime( timestr, sizeof timestr, "%H:%M:%S", ltime);
  214. /* print timestamp and length of the packet */
  215. printf("%s.%.6d len:%d ", timestr, header->ts.tv_usec, header->len);
  216. /* retireve the position of the ip header */
  217. ih = (ip_header *) (pkt_data +
  218. 14); //length of ethernet header
  219. /* retireve the position of the udp header */
  220. ip_len = (ih->ver_ihl & 0xf) * 4;
  221. uh = (udp_header *) ((u_char*)ih + ip_len);
  222. /* convert from network byte order to host byte order */
  223. sport = ntohs( uh->sport );
  224. dport = ntohs( uh->dport );
  225. /* print ip addresses and udp ports */
  226. printf("%d.%d.%d.%d.%d -> %d.%d.%d.%d.%d\n",
  227. ih->saddr.byte1,
  228. ih->saddr.byte2,
  229. ih->saddr.byte3,
  230. ih->saddr.byte4,
  231. sport,
  232. ih->daddr.byte1,
  233. ih->daddr.byte2,
  234. ih->daddr.byte3,
  235. ih->daddr.byte4,
  236. dport);
  237. }