#include <sys/ioctl.h>
#include <sys/socket.h>

#include "atenl.h"

int atenl_eth_init(struct atenl *an)
{
	struct sockaddr_ll addr = {};
	struct ifreq ifr = {};
	int ret;
 
	if (!an->bridge_name) {
		perror("Bridge name not specified");
		goto out;
	}

	memcpy(ifr.ifr_name, an->bridge_name, strlen(an->bridge_name));
	ret = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_RACFG));
	if (ret < 0) {
		perror("socket");
		goto out;
	}
	an->sock_eth = ret;

	addr.sll_family = AF_PACKET;
	addr.sll_ifindex = if_nametoindex(an->bridge_name);

	ret = bind(an->sock_eth, (struct sockaddr *)&addr, sizeof(addr));
	if (ret < 0) {
		perror("bind");
		goto out;
	}

	ret = ioctl(an->sock_eth, SIOCGIFHWADDR, &ifr);
	if (ret < 0) {
		perror("ioctl(SIOCGIFHWADDR)");
		goto out;
	}

	memcpy(an->mac_addr, ifr.ifr_hwaddr.sa_data, ETH_ALEN);
	atenl_info("Open Ethernet socket success on %s, mac addr = " MACSTR "\n",
		   an->bridge_name, MAC2STR(an->mac_addr));

	ret = 0;
out:
	return ret;
}

int atenl_eth_recv(struct atenl *an, struct atenl_data *data)
{
	struct ethhdr *hdr;
	int len;

	len = recvfrom(an->sock_eth, data->buf, sizeof(data->buf), 0, NULL, NULL);

	if (len < ETH_HLEN + RACFG_HLEN) {
		atenl_err("packet len is too short: %d\n", len);
		return -EINVAL;
	}

	hdr = (struct ethhdr *)data->buf;
	if (hdr->h_proto != htons(ETH_P_RACFG)) {
		atenl_err("invalid protocol type\n");
		return -EINVAL;
	}

	if (!ether_addr_equal(an->mac_addr, hdr->h_dest) &&
	    !is_broadcast_ether_addr(hdr->h_dest)) {
		atenl_err("invalid dest MAC\n");
		return -EINVAL;
	}

	data->len = len;

	return 0;
}

int atenl_eth_send(struct atenl *an, struct atenl_data *data)
{
	struct ethhdr *ehdr = (struct ethhdr *)data->buf;
	struct sockaddr_ll addr = {};
	int ret, len = data->len;

	if (an->unicast)
		ether_addr_copy(ehdr->h_dest, ehdr->h_source);
	else
		eth_broadcast_addr(ehdr->h_dest);

	ether_addr_copy(ehdr->h_source, an->mac_addr);
	ehdr->h_proto = htons(ETH_P_RACFG);

	if (len < 60)
		len = 60;
	else if (len > 1514) {
		atenl_err("response ethernet length is too long\n");
		return -1;
	}

	atenl_dbg_print_data(data->buf, __func__, len);

	addr.sll_family = PF_PACKET;
	addr.sll_protocol = htons(ETH_P_RACFG);
	addr.sll_ifindex = if_nametoindex(an->bridge_name);
	addr.sll_pkttype = PACKET_BROADCAST;
	addr.sll_hatype = ARPHRD_ETHER;
	addr.sll_halen = ETH_ALEN;
	memset(addr.sll_addr, 0, 8);
	eth_broadcast_addr(addr.sll_addr);

	ret = sendto(an->sock_eth, data->buf, len, 0,
		     (struct sockaddr *)&addr, sizeof(addr));
	if (ret < 0) {
		perror("sendto");
		return ret;
	}
	
	return 0;
}
