/*
 * Copyright (c) 2013 Qualcomm Atheros, Inc.
 *
 * All Rights Reserved.
 * Qualcomm Atheros Confidential and Proprietary.
 */

#include <netlink/genl/genl.h>
#include <netlink/genl/ctrl.h>
#include <errno.h>
#include <stdio.h>
#include <arpa/inet.h>

#include <fast-classifier.h>

static struct nl_sock *sock;
static struct nl_sock *sock_event;
static int family;
static int grp_id;

static struct nla_policy fast_classifier_genl_policy[FAST_CLASSIFIER_A_MAX + 1] = {
	[FAST_CLASSIFIER_A_TUPLE] = { .type = NLA_UNSPEC },
};

void dump_fc_tuple(struct fast_classifier_tuple *fc_msg) {
	char src_str[INET_ADDRSTRLEN];
	char dst_str[INET_ADDRSTRLEN];

	printf("TUPLE: %d, %s, %s, %d, %d"
			" SMAC=%02x:%02x:%02x:%02x:%02x:%02x",
			" DMAC=%02x:%02x:%02x:%02x:%02x:%02x\n",
				fc_msg->proto,
				inet_ntop(AF_INET, &(fc_msg->src_saddr),  src_str, INET_ADDRSTRLEN),
				inet_ntop(AF_INET, &(fc_msg->dst_saddr),  dst_str, INET_ADDRSTRLEN),
				fc_msg->sport, fc_msg->dport,
				fc_msg->smac[0], fc_msg->smac[1], fc_msg->smac[2],
				fc_msg->smac[3], fc_msg->smac[4], fc_msg->smac[5],
				fc_msg->dmac[0], fc_msg->dmac[1], fc_msg->dmac[2],
				fc_msg->dmac[3], fc_msg->dmac[4], fc_msg->dmac[5]);
}

static int parse_cb(struct nl_msg *msg, void *arg) {
	struct nlmsghdr *nlh = nlmsg_hdr(msg);
	struct genlmsghdr *gnlh = nlmsg_data(nlh);
	struct nlattr *attrs[FAST_CLASSIFIER_A_MAX];

	genlmsg_parse(nlh, 0, attrs, FAST_CLASSIFIER_A_MAX, fast_classifier_genl_policy);

	switch (gnlh->cmd) {
	case FAST_CLASSIFIER_C_OFFLOADED:
		printf("Got a offloaded message\n");
		dump_fc_tuple(nla_data(attrs[FAST_CLASSIFIER_A_TUPLE]));
		return NL_OK;
	case FAST_CLASSIFIER_C_DONE:
		printf("Got a done message\n");
		dump_fc_tuple(nla_data(attrs[FAST_CLASSIFIER_A_TUPLE]));
		return NL_OK;
	}

	return NL_SKIP;
}

int fast_classifier_init() {
	int err;

	sock = nl_socket_alloc();
	if (sock == NULL) {
		printf("Unable to allocation socket.\n");
		return -1;
	}
	genl_connect(sock);

	sock_event = nl_socket_alloc();
	if (sock_event == NULL) {
	        nl_close(sock);
		nl_socket_free(sock);
		printf("Unable to allocation socket.\n");
		return -1;
	}
	genl_connect(sock_event);

	family = genl_ctrl_resolve(sock, FAST_CLASSIFIER_GENL_NAME);
	if (family < 0) {
		nl_close(sock_event);
	        nl_close(sock);
		nl_socket_free(sock);
		nl_socket_free(sock_event);
		printf("Unable to resolve family\n");
		return -1;
	}

	grp_id = genl_ctrl_resolve_grp(sock, FAST_CLASSIFIER_GENL_NAME,
					FAST_CLASSIFIER_GENL_MCGRP);
	if (grp_id < 0) {
		printf("Unable to resolve mcast group\n");
		return -1;
	}

	err = nl_socket_add_membership(sock_event, grp_id);
	if (err < 0) {
		printf("Unable to add membership\n");
		return -1;
	}

	nl_socket_disable_seq_check(sock_event);
	nl_socket_modify_cb(sock_event, NL_CB_VALID, NL_CB_CUSTOM, parse_cb, NULL);

	return 0;
}

void fast_classifier_close() {
	nl_close(sock_event);
        nl_close(sock);
	nl_socket_free(sock_event);
        nl_socket_free(sock);
}

void fast_classifier_ipv4_offload(unsigned char proto, unsigned long src_saddr,
					 unsigned long dst_saddr, unsigned short sport,
					 unsigned short dport) {
	struct nl_msg *msg;
	int ret;
#ifdef DEBUG
	char src_str[INET_ADDRSTRLEN];
	char dst_str[INET_ADDRSTRLEN];
#endif
	struct fast_classifier_tuple fc_msg;

#ifdef DEBUG
	printf("DEBUG: would offload: %d, %s, %s, %d, %d\n", proto,
				inet_ntop(AF_INET, &src_saddr,  src_str, INET_ADDRSTRLEN),
				inet_ntop(AF_INET, &dst_saddr,  dst_str, INET_ADDRSTRLEN),
				sport, dport);
#endif

	fc_msg.proto = proto;
	fc_msg.src_saddr = src_saddr;
	fc_msg.dst_saddr = dst_saddr;
	fc_msg.sport = sport;
	fc_msg.dport = dport;
	fc_msg.smac[0] = 'a';
	fc_msg.smac[1] = 'b';
	fc_msg.smac[2] = 'c';
	fc_msg.smac[3] = 'd';
	fc_msg.smac[4] = 'e';
	fc_msg.smac[5] = 'f';
	fc_msg.dmac[0] = 'f';
	fc_msg.dmac[1] = 'e';
	fc_msg.dmac[2] = 'd';
	fc_msg.dmac[3] = 'c';
	fc_msg.dmac[4] = 'b';
	fc_msg.dmac[5] = 'a';

	if (fast_classifier_init() < 0) {
		printf("Unable to init generic netlink\n");
		exit(1);
	}

	msg = nlmsg_alloc();
	if (msg == NULL) {
		nl_socket_free(sock);
		printf("Unable to allocate message\n");
		return;
	}

        genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, family,
			FAST_CLASSIFIER_GENL_HDRSIZE, NLM_F_REQUEST,
			FAST_CLASSIFIER_C_OFFLOAD, FAST_CLASSIFIER_GENL_VERSION);
        nla_put(msg, 1, sizeof(fc_msg), &fc_msg);

        ret = nl_send_auto_complete(sock, msg);

        nlmsg_free(msg);
        if (ret < 0) {
                printf("nlmsg_free failed");
		nl_close(sock);
		nl_socket_free(sock);
                return;
        }

        ret = nl_wait_for_ack(sock);
        if (ret < 0) {
                printf("wait for ack failed");
		nl_close(sock);
		nl_socket_free(sock);
                return;
        }
}

void fast_classifier_listen_for_messages(void) {
	printf("waiting for netlink events\n");

	while (1) {
		nl_recvmsgs_default(sock_event);
	}
}
int main(int argc, char *argv[])
{
	if (fast_classifier_init() < 0) {
		printf("Unable to init generic netlink\n");
		exit(1);
	}

	fast_classifier_ipv4_offload('a', 0, 0, 0, 0);

	/* this never returns */
	fast_classifier_listen_for_messages();

	fast_classifier_close();

        return 0;
}
