sendpack.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <pcap.h>
  4. #ifdef _WIN32
  5. #include <tchar.h>
  6. BOOL LoadNpcapDlls()
  7. {
  8. _TCHAR npcap_dir[512];
  9. UINT len;
  10. len = GetSystemDirectory(npcap_dir, 480);
  11. if (!len) {
  12. fprintf(stderr, "Error in GetSystemDirectory: %x", GetLastError());
  13. return FALSE;
  14. }
  15. _tcscat_s(npcap_dir, 512, _T("\\Npcap"));
  16. if (SetDllDirectory(npcap_dir) == 0) {
  17. fprintf(stderr, "Error in SetDllDirectory: %x", GetLastError());
  18. return FALSE;
  19. }
  20. return TRUE;
  21. }
  22. #endif
  23. /* case-insensitive string comparison that may mix up special characters and numbers */
  24. int close_enough(char *one, char *two)
  25. {
  26. while (*one && *two)
  27. {
  28. if ( *one != *two && !(
  29. (*one >= 'a' && *one - *two == 0x20) ||
  30. (*two >= 'a' && *two - *one == 0x20)
  31. ))
  32. {
  33. return 0;
  34. }
  35. one++;
  36. two++;
  37. }
  38. if (*one || *two)
  39. {
  40. return 0;
  41. }
  42. return 1;
  43. }
  44. #define ORIG_PACKET_LEN 64
  45. int main(int argc, char **argv)
  46. {
  47. pcap_t *fp;
  48. char errbuf[PCAP_ERRBUF_SIZE] = {0};
  49. u_char packet[ORIG_PACKET_LEN] =
  50. /* Ethernet frame header */
  51. "\xff\xff\xff\xff\xff\xff" /* dst mac */
  52. "\x02\x02\x02\x02\x02\x02" /* src mac */
  53. "\x08\x00" /* ethertype IPv4 */
  54. /* IPv4 packet header */
  55. "\x45\x00\x00\x00" /* IPv4, minimal header, length TBD */
  56. "\x12\x34\x00\x00" /* IPID 0x1234, no fragmentation */
  57. "\x10\x11\x00\x00" /* TTL 0x10, UDP, checksum (not required) */
  58. "\x00\x00\x00\x00" /* src IP (TBD) */
  59. "\xff\xff\xff\xff" /* dst IP (broadcast) */
  60. /* UDP header */
  61. "\x00\x07\x00\x07" /* src port 7, dst port 7 (echo) */
  62. "\x00\x00\x00\x00" /* length TBD, cksum 0 (unset) */
  63. ;
  64. u_char *sendme = packet;
  65. size_t packet_len = ORIG_PACKET_LEN;
  66. pcap_if_t *ifaces = NULL;
  67. pcap_if_t *dev = NULL;
  68. pcap_addr_t *addr = NULL;
  69. #ifdef _WIN32
  70. /* Load Npcap and its functions. */
  71. if (!LoadNpcapDlls())
  72. {
  73. fprintf(stderr, "Couldn't load Npcap\n");
  74. exit(1);
  75. }
  76. #endif
  77. /* Check the validity of the command line */
  78. if (argc != 2)
  79. {
  80. printf("usage: %s interface", argv[0]);
  81. return 1;
  82. }
  83. if (0 != pcap_init(PCAP_CHAR_ENC_LOCAL, errbuf)) {
  84. fprintf(stderr, "Failed to initialize pcap lib: %s\n", errbuf);
  85. return 2;
  86. }
  87. /* Find the IPv4 address of the device */
  88. if (0 != pcap_findalldevs(&ifaces, errbuf)) {
  89. fprintf(stderr, "Failed to get list of devices: %s\n", errbuf);
  90. return 2;
  91. }
  92. for (dev = ifaces; dev != NULL; dev = dev->next)
  93. {
  94. if (close_enough(dev->name, argv[1]))
  95. {
  96. break;
  97. }
  98. }
  99. if (dev == NULL) {
  100. fprintf(stderr, "Could not find %s in the list of devices\n", argv[1]);
  101. return 3;
  102. }
  103. for (addr = dev->addresses; addr != NULL; addr = addr->next)
  104. {
  105. if (addr->addr->sa_family == AF_INET)
  106. {
  107. break;
  108. }
  109. }
  110. if (addr == NULL) {
  111. fprintf(stderr, "Could not find IPv4 address for %s\n", argv[1]);
  112. return 3;
  113. }
  114. /* Fill in the length and source addr and calculate checksum */
  115. packet[14 + 2] = 0xff & ((ORIG_PACKET_LEN - 14) >> 8);
  116. packet[14 + 3] = 0xff & (ORIG_PACKET_LEN - 14);
  117. /* UDP length */
  118. packet[14 + 20 + 4] = 0xff & ((ORIG_PACKET_LEN - 14 - 20) >> 8);
  119. packet[14 + 20 + 5] = 0xff & (ORIG_PACKET_LEN - 14 - 20);
  120. *(u_long *)(packet + 14 + 12) = ((struct sockaddr_in *)(addr->addr))->sin_addr.S_un.S_addr;
  121. uint32_t cksum = 0;
  122. for (int i=14; i < 14 + 4 * (packet[14] & 0xf); i += 2)
  123. {
  124. cksum += *(uint16_t *)(packet + i);
  125. }
  126. while (cksum>>16)
  127. cksum = (cksum & 0xffff) + (cksum >> 16);
  128. cksum = ~cksum;
  129. *(uint16_t *)(packet + 14 + 10) = cksum;
  130. /* Open the adapter */
  131. if ((fp = pcap_open_live(argv[1], // name of the device
  132. 0, // portion of the packet to capture. 0 == no capture.
  133. 0, // non-promiscuous mode
  134. 1000, // read timeout
  135. errbuf // error buffer
  136. )) == NULL)
  137. {
  138. fprintf(stderr,"\nUnable to open the adapter. %s is not supported by Npcap\n", argv[1]);
  139. return 2;
  140. }
  141. switch(pcap_datalink(fp))
  142. {
  143. case DLT_NULL:
  144. /* Skip Ethernet header, retreat NULL header length */
  145. #define NULL_VS_ETH_DIFF (14 - 4)
  146. sendme = packet + NULL_VS_ETH_DIFF;
  147. packet_len -= NULL_VS_ETH_DIFF;
  148. // Pretend IPv4
  149. sendme[0] = 2;
  150. sendme[1] = 0;
  151. sendme[2] = 0;
  152. sendme[3] = 0;
  153. break;
  154. case DLT_EN10MB:
  155. /* Already set up */
  156. sendme = packet;
  157. break;
  158. default:
  159. fprintf(stderr, "\nError, unknown data-link type %u\n", pcap_datalink(fp));
  160. return 4;
  161. }
  162. /* Send down the packet */
  163. if (pcap_sendpacket(fp, // Adapter
  164. sendme, // buffer with the packet
  165. packet_len // size
  166. ) != 0)
  167. {
  168. fprintf(stderr,"\nError sending the packet: %s\n", pcap_geterr(fp));
  169. return 3;
  170. }
  171. pcap_close(fp);
  172. return 0;
  173. }