#include #include #include #ifdef _WIN32 #include BOOL LoadNpcapDlls() { _TCHAR npcap_dir[512]; UINT len; len = GetSystemDirectory(npcap_dir, 480); if (!len) { fprintf(stderr, "Error in GetSystemDirectory: %x", GetLastError()); return FALSE; } _tcscat_s(npcap_dir, 512, _T("\\Npcap")); if (SetDllDirectory(npcap_dir) == 0) { fprintf(stderr, "Error in SetDllDirectory: %x", GetLastError()); return FALSE; } return TRUE; } #endif /* case-insensitive string comparison that may mix up special characters and numbers */ int close_enough(char *one, char *two) { while (*one && *two) { if ( *one != *two && !( (*one >= 'a' && *one - *two == 0x20) || (*two >= 'a' && *two - *one == 0x20) )) { return 0; } one++; two++; } if (*one || *two) { return 0; } return 1; } #define ORIG_PACKET_LEN 64 int main(int argc, char **argv) { pcap_t *fp; char errbuf[PCAP_ERRBUF_SIZE] = {0}; u_char packet[ORIG_PACKET_LEN] = /* Ethernet frame header */ "\xff\xff\xff\xff\xff\xff" /* dst mac */ "\x02\x02\x02\x02\x02\x02" /* src mac */ "\x08\x00" /* ethertype IPv4 */ /* IPv4 packet header */ "\x45\x00\x00\x00" /* IPv4, minimal header, length TBD */ "\x12\x34\x00\x00" /* IPID 0x1234, no fragmentation */ "\x10\x11\x00\x00" /* TTL 0x10, UDP, checksum (not required) */ "\x00\x00\x00\x00" /* src IP (TBD) */ "\xff\xff\xff\xff" /* dst IP (broadcast) */ /* UDP header */ "\x00\x07\x00\x07" /* src port 7, dst port 7 (echo) */ "\x00\x00\x00\x00" /* length TBD, cksum 0 (unset) */ ; u_char *sendme = packet; size_t packet_len = ORIG_PACKET_LEN; pcap_if_t *ifaces = NULL; pcap_if_t *dev = NULL; pcap_addr_t *addr = NULL; #ifdef _WIN32 /* Load Npcap and its functions. */ if (!LoadNpcapDlls()) { fprintf(stderr, "Couldn't load Npcap\n"); exit(1); } #endif /* Check the validity of the command line */ if (argc != 2) { printf("usage: %s interface", argv[0]); return 1; } if (0 != pcap_init(PCAP_CHAR_ENC_LOCAL, errbuf)) { fprintf(stderr, "Failed to initialize pcap lib: %s\n", errbuf); return 2; } /* Find the IPv4 address of the device */ if (0 != pcap_findalldevs(&ifaces, errbuf)) { fprintf(stderr, "Failed to get list of devices: %s\n", errbuf); return 2; } for (dev = ifaces; dev != NULL; dev = dev->next) { if (close_enough(dev->name, argv[1])) { break; } } if (dev == NULL) { fprintf(stderr, "Could not find %s in the list of devices\n", argv[1]); return 3; } for (addr = dev->addresses; addr != NULL; addr = addr->next) { if (addr->addr->sa_family == AF_INET) { break; } } if (addr == NULL) { fprintf(stderr, "Could not find IPv4 address for %s\n", argv[1]); return 3; } /* Fill in the length and source addr and calculate checksum */ packet[14 + 2] = 0xff & ((ORIG_PACKET_LEN - 14) >> 8); packet[14 + 3] = 0xff & (ORIG_PACKET_LEN - 14); /* UDP length */ packet[14 + 20 + 4] = 0xff & ((ORIG_PACKET_LEN - 14 - 20) >> 8); packet[14 + 20 + 5] = 0xff & (ORIG_PACKET_LEN - 14 - 20); *(u_long *)(packet + 14 + 12) = ((struct sockaddr_in *)(addr->addr))->sin_addr.S_un.S_addr; uint32_t cksum = 0; for (int i=14; i < 14 + 4 * (packet[14] & 0xf); i += 2) { cksum += *(uint16_t *)(packet + i); } while (cksum>>16) cksum = (cksum & 0xffff) + (cksum >> 16); cksum = ~cksum; *(uint16_t *)(packet + 14 + 10) = cksum; /* Open the adapter */ if ((fp = pcap_open_live(argv[1], // name of the device 0, // portion of the packet to capture. 0 == no capture. 0, // non-promiscuous mode 1000, // read timeout errbuf // error buffer )) == NULL) { fprintf(stderr,"\nUnable to open the adapter. %s is not supported by Npcap\n", argv[1]); return 2; } switch(pcap_datalink(fp)) { case DLT_NULL: /* Skip Ethernet header, retreat NULL header length */ #define NULL_VS_ETH_DIFF (14 - 4) sendme = packet + NULL_VS_ETH_DIFF; packet_len -= NULL_VS_ETH_DIFF; // Pretend IPv4 sendme[0] = 2; sendme[1] = 0; sendme[2] = 0; sendme[3] = 0; break; case DLT_EN10MB: /* Already set up */ sendme = packet; break; default: fprintf(stderr, "\nError, unknown data-link type %u\n", pcap_datalink(fp)); return 4; } /* Send down the packet */ if (pcap_sendpacket(fp, // Adapter sendme, // buffer with the packet packet_len // size ) != 0) { fprintf(stderr,"\nError sending the packet: %s\n", pcap_geterr(fp)); return 3; } pcap_close(fp); return 0; }