/* vi: set sw=4 ts=4: */
/*
 * Copyright (C) 2011 Denys Vlasenko.
 *
 * Licensed under GPLv2, see file LICENSE in this source tree.
 */
#include "common.h"
#include "d6_common.h"
#include "dhcpd.h"
#include <netinet/in.h>
#include <netinet/if_ether.h>
#include <netpacket/packet.h>

#if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 2
void FAST_FUNC d6_dump_packet(struct d6_packet *packet)
{
	if (dhcp_verbose < 2)
		return;

	bb_info_msg(
		" xid %x"
		, packet->d6_xid32
	);
	//*bin2hex(buf, (void *) packet->chaddr, sizeof(packet->chaddr)) = '\0';
	//bb_error_msg(" chaddr %s", buf);
}
#endif

int FAST_FUNC d6_recv_kernel_packet(struct in6_addr *peer_ipv6
	UNUSED_PARAM
	, struct d6_packet *packet, int fd)
{
	int bytes;

	memset(packet, 0, sizeof(*packet));
	bytes = safe_read(fd, packet, sizeof(*packet));
	if (bytes < 0) {
		log1s("packet read error, ignoring");
		return bytes; /* returns -1 */
	}

	if (bytes < offsetof(struct d6_packet, d6_options)) {
		bb_simple_info_msg("packet with bad magic, ignoring");
		return -2;
	}
	log1("received %s", "a packet");
	d6_dump_packet(packet);

	return bytes;
}

/* Construct a ipv6+udp header for a packet, send packet */
int FAST_FUNC d6_send_raw_packet(
		struct d6_packet *d6_pkt, unsigned d6_pkt_size,
		struct in6_addr *src_ipv6, int source_port,
		struct in6_addr *dst_ipv6, int dest_port, const uint8_t *dest_arp,
		int ifindex)
{
	struct sockaddr_ll dest_sll;
	struct ip6_udp_d6_packet packet;
	int fd;
	int result = -1;
	const char *msg;

	fd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IPV6));
	if (fd < 0) {
		msg = "socket(%s)";
		goto ret_msg;
	}

	memset(&dest_sll, 0, sizeof(dest_sll));
	memset(&packet, 0, offsetof(struct ip6_udp_d6_packet, data));
	packet.data = *d6_pkt; /* struct copy */

	dest_sll.sll_family = AF_PACKET;
	dest_sll.sll_protocol = htons(ETH_P_IPV6);
	dest_sll.sll_ifindex = ifindex;
	/*dest_sll.sll_hatype = ARPHRD_???;*/
	/*dest_sll.sll_pkttype = PACKET_???;*/
	dest_sll.sll_halen = 6;
	memcpy(dest_sll.sll_addr, dest_arp, 6);

	if (bind(fd, (struct sockaddr *)&dest_sll, sizeof(dest_sll)) < 0) {
		msg = "bind(%s)";
		goto ret_close;
	}

	packet.ip6.ip6_vfc = (6 << 4); /* 4 bits version, top 4 bits of tclass */
	if (src_ipv6)
		packet.ip6.ip6_src = *src_ipv6; /* struct copy */
	packet.ip6.ip6_dst = *dst_ipv6; /* struct copy */
	packet.udp.source = htons(source_port);
	packet.udp.dest = htons(dest_port);
	/* size, excluding IP header: */
	packet.udp.len = htons(sizeof(struct udphdr) + d6_pkt_size);
	packet.ip6.ip6_plen = packet.udp.len;
	/*
	 * Someone was smoking weed (at least) while inventing UDP checksumming:
	 * UDP checksum skips first four bytes of IPv6 header.
	 * 'next header' field should be summed as if it is one more byte
	 * to the right, therefore we write its value (IPPROTO_UDP)
	 * into ip6_hlim, and its 'real' location remains zero-filled for now.
	 */
	packet.ip6.ip6_hlim = IPPROTO_UDP;
	packet.udp.check = inet_cksum(
				(uint16_t *)&packet + 2,
				offsetof(struct ip6_udp_d6_packet, data) - 4 + d6_pkt_size
	);
	/* fix 'hop limit' and 'next header' after UDP checksumming */
	packet.ip6.ip6_hlim = 1; /* observed Windows machines to use hlim=1 */
	packet.ip6.ip6_nxt = IPPROTO_UDP;

	d6_dump_packet(d6_pkt);
	result = sendto(fd, &packet, offsetof(struct ip6_udp_d6_packet, data) + d6_pkt_size,
			/*flags:*/ 0,
			(struct sockaddr *) &dest_sll, sizeof(dest_sll)
	);
	msg = "sendto";
 ret_close:
	close(fd);
	if (result < 0) {
 ret_msg:
		bb_perror_msg(msg, "PACKET");
	}
	return result;
}

/* Let the kernel do all the work for packet generation */
int FAST_FUNC d6_send_kernel_packet(
		struct d6_packet *d6_pkt, unsigned d6_pkt_size,
		struct in6_addr *src_ipv6, int source_port,
		struct in6_addr *dst_ipv6, int dest_port,
		int ifindex)
{
	struct sockaddr_in6 sa;
	int fd;
	int result = -1;
	const char *msg;

	fd = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP);
	if (fd < 0) {
		msg = "socket(%s)";
		goto ret_msg;
	}
	setsockopt_reuseaddr(fd);

	memset(&sa, 0, sizeof(sa));
	sa.sin6_family = AF_INET6;
	sa.sin6_port = htons(source_port);
	sa.sin6_addr = *src_ipv6; /* struct copy */
	if (bind(fd, (struct sockaddr *)&sa, sizeof(sa)) == -1) {
		msg = "bind(%s)";
		goto ret_close;
	}

	memset(&sa, 0, sizeof(sa));
	sa.sin6_family = AF_INET6;
	sa.sin6_port = htons(dest_port);
	sa.sin6_addr = *dst_ipv6; /* struct copy */
	sa.sin6_scope_id = ifindex;
	if (connect(fd, (struct sockaddr *)&sa, sizeof(sa)) == -1) {
		msg = "connect";
		goto ret_close;
	}

	d6_dump_packet(d6_pkt);
	result = safe_write(fd, d6_pkt, d6_pkt_size);
	msg = "write";
 ret_close:
	close(fd);
	if (result < 0) {
 ret_msg:
		bb_perror_msg(msg, "UDP");
	}
	return result;
}
