#define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "/root/projects/dnsfind/domain2name.c" int hex2int (char hex) { if (hex >= '0' && hex <= '9') return hex-'0'; if (hex >= 'a' && hex <= 'f') return 10+hex-'a'; if (hex >= 'A' && hex <= 'A') return 10+hex-'A'; return -1; } int mac_pton (const char * src, unsigned char * dst) { for (int i = 0; i < 6; i++) { if (hex2int(src[0]) == -1 || hex2int(src[1]) == -1) return 0; dst[i] = hex2int(src[0]) << 4 | hex2int(src[1]); src += 3; } return 1; } unsigned long checksum (void * data, int len) { // i cant into checksums im retarded unsigned sum = 0; for (int i = 0; i+1 < len; i += 2) sum += *((unsigned char *) data + i)*256+*((unsigned char *) data + i + 1); if (len % 2) sum += ((unsigned char *) data)[len-1]; return sum; } uint16_t checksum_final (unsigned long sum) { sum += sum >> 16; sum &= 0xffff; sum ^= 0xffff; if (sum == 0) sum = 0xffff; return htons(sum); } int main (int argc, char ** argv) { if (argc != 5) { fprintf(stderr, "%s \n", argv[0]); return 4; } int sock = socket(AF_PACKET, SOCK_DGRAM, htons(ETHERTYPE_IPV6)); if (sock == -1) { perror("socket(AF_PACKET, SOCK_DGRAM, htons(ETHERTYPE_IPV6)"); return 1; } HEADER dns = { .id = htons(0x1337), .qr = 0, // question .opcode = ns_o_query, .rd = 1, // recursion .qdcount = htons(1) }; unsigned char question[5] = ""; *((uint16_t *) (question+1)) = htons(ns_t_any); *((uint16_t *) (question+3)) = htons(ns_c_in); struct udphdr udp = { .source = htons(6969), .dest = htons(53), .len = htons(8+sizeof dns+sizeof question) }; struct ip6_hdr ip6 = { .ip6_ctlun.ip6_un1.ip6_un1_plen = udp.len, .ip6_ctlun.ip6_un1.ip6_un1_hlim = 255, .ip6_ctlun.ip6_un1.ip6_un1_nxt = IPPROTO_UDP }; ip6.ip6_ctlun.ip6_un2_vfc |= 0x60; switch (inet_pton(AF_INET6, argv[1], ip6.ip6_dst.s6_addr)) { case -1: perror("inet_pton(AF_INET6, argv[1])"); return 2; break; case 0: fprintf(stderr, "naslov %s ni veljaven\n", argv[1]); return 12; break; } switch (inet_pton(AF_INET6, argv[2], ip6.ip6_src.s6_addr)) { case -1: perror("inet_pton(AF_INET6, argv[2])"); return 9; break; case 0: fprintf(stderr, "naslov %s ni veljaven\n", argv[1]); return 11; break; } struct iovec msg[] = { { .iov_base = &ip6, .iov_len = sizeof ip6 }, { .iov_base = &udp, .iov_len = sizeof udp }, { .iov_base = &dns, .iov_len = sizeof dns }, { .iov_base = &question, .iov_len = sizeof question } }; unsigned long sum = ip6.ip6_ctlun.ip6_un1.ip6_un1_nxt + checksum(&ip6.ip6_ctlun.ip6_un1.ip6_un1_plen, sizeof(uint16_t)) + checksum(&ip6.ip6_src, sizeof ip6.ip6_src) + checksum(&ip6.ip6_dst, sizeof ip6.ip6_dst); for (size_t i = 1; i < sizeof msg/sizeof msg[0]; i++) sum += checksum(msg[i].iov_base, msg[i].iov_len); udp.check = checksum_final(sum); udp.check = 0; int ifindex = atoi(argv[3]); struct sockaddr_ll dst = { .sll_family = AF_PACKET, .sll_ifindex = ifindex, .sll_halen = 6, .sll_protocol = htons(ETHERTYPE_IPV6) }; if (!mac_pton(argv[4], dst.sll_addr)) { fprintf(stderr, "naslov %s ni veljaven\n", argv[4]); return 13; } struct mmsghdr mmsghdr = { .msg_hdr = { .msg_name = &dst, .msg_namelen = sizeof dst, .msg_iov = msg, .msg_iovlen = sizeof msg / sizeof msg[0] } }; /* if (sendmmsg(sock, &mmsghdr, 1, 0) == -1) { perror("sendmmsg(sock, &mmsghdr, 1, 0)"); return 3; } */ if (sendmsg(sock, &mmsghdr.msg_hdr, 0) == -1) { perror("sendmsg"); return 5; } return 0; }