summaryrefslogblamecommitdiffstats
path: root/skripti/raw6.c
blob: c0fb1306098677011a252d742d161ddc148a8254 (plain) (tree)
























































































































































                                                                                                                                                                                                                          
#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;
}