/* * A generic packet generator application. * * Copyright Richard Sharpe, 2019. * * You are welcome to use, modify, otherwise, this code. * * You will need libpcap installed. * * Create a Makefile with this: * * all: * cc -g -o pkt-gen pkt-gen.c -I . -lpcap * */ #include #include #include #include struct s1g_radiotap_hdr { uint16_t type; uint16_t len; uint16_t known; uint16_t data1; uint16_t data2; uint8_t ndp_type; uint8_t ndp_data[5]; } __attribute__((packed)); struct radiotap_hdr { uint8_t vers; uint8_t pad; uint16_t len; uint32_t presence_flags; uint32_t MAC_timestamp[2]; uint8_t flags; uint8_t data_rate; uint16_t pad2; struct s1g_radiotap_hdr s1g_hdr; } __attribute__((packed)); struct complete_pkt { struct radiotap_hdr radiotap; uint8_t pkt_data[26]; } __attribute__((packed)); uint8_t pkt_data[26] = { 0x1c, 0x0b, 0x00, 0x00, 0x02, 0x00, 0xeb, 0x4b, 0x02, 0x8b, 0x12, 0x52, 0xa7, 0x6b, 0x00, 0x62, 0x9c, 0x6b, 0x64, 0x4e, 0x35, 0xae, 0x05, 0x02, 0x00, 0x02 }; int main(int argc, char *argv[]) { int err = -1; pcap_t *pd = NULL; void *ctx = NULL; struct pcap_pkthdr hdr; struct timeval ts; pcap_dumper_t *dumper = NULL; struct complete_pkt pkt; if (argc < 2) { printf("Usage: %s \n", argv[0]); return 1; } pd = pcap_open_dead(DLT_IEEE802_11_RADIO, 65535); if (pd == NULL) { fprintf(stderr, "Unable to open pcap device: %s\n", strerror(errno)); return -1; } dumper = pcap_dump_open(pd, argv[1]); if (dumper == NULL) { fprintf(stderr, "Unable to create dump file %s: %s\n", argv[1], pcap_geterr(pd)); goto close_pd; } /* * Now create the comlete packet. */ pkt.radiotap.vers = 0; pkt.radiotap.pad = 0; pkt.radiotap.len = sizeof(struct radiotap_hdr); pkt.radiotap.presence_flags = 0x10000007; pkt.radiotap.MAC_timestamp[0] = 0x17860500; pkt.radiotap.MAC_timestamp[1] = 0x22ac9b1a; pkt.radiotap.flags = 0; pkt.radiotap.data_rate = 0x0c; pkt.radiotap.pad2 = 0xffff; pkt.radiotap.s1g_hdr.type = 32; pkt.radiotap.s1g_hdr.len = 12; pkt.radiotap.s1g_hdr.known = 0x0005; /* S1G PPDU forman and GU known */ pkt.radiotap.s1g_hdr.data1 = 0x0020; pkt.radiotap.s1g_hdr.data2 = 0x0; pkt.radiotap.s1g_hdr.ndp_type = 0; pkt.radiotap.s1g_hdr.ndp_data[0] = 0; pkt.radiotap.s1g_hdr.ndp_data[1] = 0; pkt.radiotap.s1g_hdr.ndp_data[2] = 0; pkt.radiotap.s1g_hdr.ndp_data[3] = 0; pkt.radiotap.s1g_hdr.ndp_data[4] = 0; memcpy(pkt.pkt_data, pkt_data, sizeof(pkt.pkt_data)); gettimeofday(&ts, NULL); hdr.ts = ts; hdr.caplen = sizeof(struct complete_pkt); hdr.len = sizeof(struct complete_pkt); pcap_dump((u_char *)dumper, &hdr, (u_char *)&pkt); /* Dump another with different values */ pkt.radiotap.s1g_hdr.known = 0x0035; pkt.radiotap.s1g_hdr.data1 = 0xB421; pcap_dump((u_char *)dumper, &hdr, (u_char *)&pkt); pkt.radiotap.s1g_hdr.known = 0x0180; pkt.radiotap.s1g_hdr.data1 = 0; pkt.radiotap.s1g_hdr.ndp_type = 0; pkt.radiotap.s1g_hdr.ndp_data[0] = 0xe2; pkt.radiotap.s1g_hdr.ndp_data[1] = 0xd9; pkt.radiotap.s1g_hdr.ndp_data[2] = 0x03; pkt.radiotap.s1g_hdr.ndp_data[3] = 0x00; pkt.radiotap.s1g_hdr.ndp_data[4] = 0x80; hdr.caplen = sizeof(struct radiotap_hdr); hdr.len = sizeof(struct radiotap_hdr); pcap_dump((u_char *)dumper, &hdr, (u_char *)&pkt); close_dumper: pcap_dump_close(dumper); close_pd: pcap_close(pd); return err; }