/*
 * q_atm.c		ATM.
 *
 * Hacked 1998-2000 by Werner Almesberger, EPFL ICA
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <ctype.h>
#include <syslog.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <atm.h>
#include <linux/atmdev.h>
#include <linux/atmarp.h>

#include "utils.h"
#include "tc_util.h"


#define MAX_HDR_LEN 64


static int atm_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n)
{
	if (argc) {
		fprintf(stderr, "Usage: atm\n");
		return -1;
	}
	return 0;
}


static void explain(void)
{
	fprintf(stderr, "Usage: ... atm ( pvc ADDR | svc ADDR [ sap SAP ] ) [ qos QOS ] [ sndbuf BYTES ]\n");
	fprintf(stderr, "  [ hdr HEX... ] [ excess ( CLASSID | clp ) ] [ clip ]\n");
}


static int atm_parse_class_opt(struct qdisc_util *qu, int argc, char **argv,
   struct nlmsghdr *n)
{
	struct sockaddr_atmsvc addr;
	struct atm_qos qos;
	struct atm_sap sap;
	unsigned char hdr[MAX_HDR_LEN];
	__u32 excess = 0;
	struct rtattr *tail;
	int sndbuf = 0;
	int hdr_len = -1;
	int set_clip = 0;
	int s;

	memset(&addr, 0, sizeof(addr));
	(void) text2qos("aal5,ubr:sdu=9180,rx:none", &qos, 0);
	(void) text2sap("blli:l2=iso8802", &sap, 0);
	while (argc > 0) {
		if (!strcmp(*argv, "pvc")) {
			NEXT_ARG();
			if (text2atm(*argv, (struct sockaddr *) &addr,
			    sizeof(addr), T2A_PVC | T2A_NAME) < 0) {
				explain();
				return -1;
			}
		} else if (!strcmp(*argv,"svc")) {
			NEXT_ARG();
			if (text2atm(*argv, (struct sockaddr *) &addr,
			    sizeof(addr), T2A_SVC | T2A_NAME) < 0) {
				explain();
				return -1;
			}
		} else if (!strcmp(*argv,"qos")) {
			NEXT_ARG();
			if (text2qos(*argv, &qos, 0) < 0) {
				explain();
				return -1;
			}
		} else if (!strcmp(*argv,"sndbuf")) {
			char *end;

			NEXT_ARG();
			sndbuf = strtol(*argv, &end, 0);
			if (*end) {
				explain();
				return -1;
			}
		} else if (!strcmp(*argv,"sap")) {
			NEXT_ARG();
			if (addr.sas_family != AF_ATMSVC ||
			    text2sap(*argv, &sap, T2A_NAME) < 0) {
				explain();
				return -1;
			}
		} else if (!strcmp(*argv,"hdr")) {
			unsigned char *ptr;
			char *walk;

			NEXT_ARG();
			ptr = hdr;
			for (walk = *argv; *walk; walk++) {
				int tmp;

				if (ptr == hdr+MAX_HDR_LEN) {
					fprintf(stderr, "header is too long\n");
					return -1;
				}
				if (*walk == '.') continue;
				if (!isxdigit(walk[0]) || !walk[1] ||
				    !isxdigit(walk[1])) {
					explain();
					return -1;
				}
				sscanf(walk, "%2x", &tmp);
				*ptr++ = tmp;
				walk++;
			}
			hdr_len = ptr-hdr;
		} else if (!strcmp(*argv,"excess")) {
			NEXT_ARG();
			if (!strcmp(*argv, "clp")) excess = 0;
			else if (get_tc_classid(&excess, *argv)) {
					explain();
					return -1;
				}
		} else if (!strcmp(*argv,"clip")) {
			set_clip = 1;
		} else {
			explain();
			return 1;
		}
		argc--;
		argv++;
	}
	s = socket(addr.sas_family, SOCK_DGRAM, 0);
	if (s < 0) {
		perror("socket");
		return -1;
	}
	if (setsockopt(s, SOL_ATM, SO_ATMQOS, &qos, sizeof(qos)) < 0) {
		perror("SO_ATMQOS");
		return -1;
	}
	if (sndbuf)
	    if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf)) < 0) {
		perror("SO_SNDBUF");
	    return -1;
	}
	if (addr.sas_family == AF_ATMSVC && setsockopt(s, SOL_ATM, SO_ATMSAP,
	    &sap, sizeof(sap)) < 0) {
		perror("SO_ATMSAP");
		return -1;
	}
	if (connect(s, (struct sockaddr *) &addr, addr.sas_family == AF_ATMPVC ?
	    sizeof(struct sockaddr_atmpvc) : sizeof(addr)) < 0) {
		perror("connect");
		return -1;
	}
	if (set_clip)
		if (ioctl(s, ATMARP_MKIP, 0) < 0) {
			perror("ioctl ATMARP_MKIP");
			return -1;
		}
	tail = NLMSG_TAIL(n);
	addattr_l(n, 1024, TCA_OPTIONS, NULL, 0);
	addattr_l(n, 1024, TCA_ATM_FD, &s, sizeof(s));
	if (excess) addattr_l(n, 1024, TCA_ATM_EXCESS, &excess, sizeof(excess));
	if (hdr_len != -1) addattr_l(n, 1024, TCA_ATM_HDR, hdr, hdr_len);
	tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail;
	return 0;
}



static int atm_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
{
	struct rtattr *tb[TCA_ATM_MAX+1];
	char buffer[MAX_ATM_ADDR_LEN+1];

	if (opt == NULL)
		return 0;

	parse_rtattr_nested(tb, TCA_ATM_MAX, opt);
	if (tb[TCA_ATM_ADDR]) {
		if (RTA_PAYLOAD(tb[TCA_ATM_ADDR]) <
		    sizeof(struct sockaddr_atmpvc))
			fprintf(stderr, "ATM: address too short\n");
		else {
			if (atm2text(buffer, MAX_ATM_ADDR_LEN,
			    RTA_DATA(tb[TCA_ATM_ADDR]), A2T_PRETTY | A2T_NAME) <
			    0) fprintf(stderr, "atm2text error\n");
			fprintf(f, "pvc %s ", buffer);
		}
	}
	if (tb[TCA_ATM_HDR]) {
		int i;
		const __u8 *hdr = RTA_DATA(tb[TCA_ATM_HDR]);

		fprintf(f, "hdr");
		for (i = 0; i < RTA_PAYLOAD(tb[TCA_ATM_HDR]); i++)
			fprintf(f, "%c%02x", i ? '.' : ' ', hdr[i]);
		if (!i) fprintf(f, " .");
		fprintf(f, " ");
	}
	if (tb[TCA_ATM_EXCESS]) {
		__u32 excess;

		if (RTA_PAYLOAD(tb[TCA_ATM_EXCESS]) < sizeof(excess))
			fprintf(stderr, "ATM: excess class ID too short\n");
		else {
			excess = rta_getattr_u32(tb[TCA_ATM_EXCESS]);
			if (!excess) fprintf(f, "excess clp ");
			else {
				char buf[64];

				print_tc_classid(buf, sizeof(buf), excess);
				fprintf(f, "excess %s ", buf);
			}
		}
	}
	if (tb[TCA_ATM_STATE]) {
		static const char *map[] = { ATM_VS2TXT_MAP };
		int state;

		if (RTA_PAYLOAD(tb[TCA_ATM_STATE]) < sizeof(state))
			fprintf(stderr, "ATM: state field too short\n");
		else {
			state = *(int *) RTA_DATA(tb[TCA_ATM_STATE]);
			fprintf(f, "%s ", map[state]);
		}
	}
	return 0;
}


struct qdisc_util atm_qdisc_util = {
	.id		= "atm",
	.parse_qopt	= atm_parse_opt,
	.print_qopt	= atm_print_opt,
	.parse_copt	= atm_parse_class_opt,
	.print_copt	= atm_print_opt,
};
