/* SPDX-License-Identifier: GPL-2.0 */
/*
 * 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 <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, const char *dev)
{
	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"
		"  [ hdr HEX... ] [ excess ( CLASSID | clp ) ] [ clip ]\n");
}


static int atm_parse_class_opt(struct qdisc_util *qu, int argc, char **argv,
	struct nlmsghdr *n, const char *dev)
{
	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;

	(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 = addattr_nest(n, 1024, TCA_OPTIONS);
	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);
	addattr_nest_end(n, 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 = rta_getattr_u32(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,
};
