diff options
Diffstat (limited to 'skripti')
-rw-r--r-- | skripti/raw6.c | 153 |
1 files changed, 153 insertions, 0 deletions
diff --git a/skripti/raw6.c b/skripti/raw6.c new file mode 100644 index 0000000..c0fb130 --- /dev/null +++ b/skripti/raw6.c @@ -0,0 +1,153 @@ +#define _GNU_SOURCE +#include <sys/socket.h> +#include <netinet/in.h> +#include <netinet/ip6.h> +#include <netinet/udp.h> +#include <stdio.h> +#include <arpa/inet.h> +#include <string.h> +#include <signal.h> +#include <linux/if_packet.h> +#include <net/ethernet.h> +#include <net/if.h> +#include <stdlib.h> +#include <arpa/nameser.h> +#include <assert.h> +#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 <dst ipv6> <src ipv6> <if index> <router mac> <querydomain>\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; +} |