[Asterisk-cvs] zaptel sethdlc-new.c,NONE,1.1 Makefile,1.27,1.28 zaptel.c,1.46,1.47

markster at lists.digium.com markster at lists.digium.com
Fri Nov 21 03:04:33 CST 2003


Update of /usr/cvsroot/zaptel
In directory mongoose.digium.com:/tmp/cvs-serv27861

Modified Files:
	Makefile zaptel.c 
Added Files:
	sethdlc-new.c 
Log Message:
Fix for new kernels, add support for 2.4.22 and new sethdlc


--- NEW FILE: sethdlc-new.c ---
/*
 * sethdlc.c
 *
 * Copyright (C) 1999 - 2002 Krzysztof Halasa <khc at pm.waw.pl>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 */

#include <errno.h>
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <asm/types.h>
#include <linux/hdlc.h>
#include <netinet/in.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <linux/if.h>
#include <linux/sockios.h>

#if GENERIC_HDLC_VERSION != 4
#error Generic HDLC layer version mismatch, please get correct sethdlc.c
#endif

#if !defined(IF_PROTO_HDLC_ETH) || !defined(IF_PROTO_FR_ETH_PVC)
#warning "No kernel support for Ethernet over Frame Relay / HDLC, skipping it"
#endif


static struct ifreq req;	/* for ioctl */
static int argc;
static char **argv;
int sock;


static void error(const char *format, ...) __attribute__ ((noreturn));

static void error(const char *format, ...)
{
	va_list args;

	va_start(args, format);
	fprintf(stderr, "%s: ", req.ifr_name);
	vfprintf(stderr, format, args);
	va_end(args);
	exit(1);
}



typedef struct {
	const char *name;
	const unsigned int value;
} parsertab;



static int checkkey(const char* name)
{
	if (argc < 1)
		return -1;	/* no enough parameters */

	if (strcmp(name, argv[0]))
		return -1;
	argc--;
	argv++;
	return 0;
}



static int checktab(parsertab *tab, unsigned int *value)
{
	int i;

	if (argc < 1)
		return -1;	/* no enough parameters */
	
	for (i = 0; tab[i].name; i++)
		if (!strcmp(tab[i].name, argv[0])) {
			argc--;
			argv++;
			*value = tab[i].value;
			return 0;
		}

	return -1;		/* Not found */
}



static const char* tabstr(unsigned int value, parsertab *tab,
			  const char* unknown)
{
	int i;
	for (i = 0; tab[i].name; i++)
		if (tab[i].value == value)
			return tab[i].name;

	return unknown;		/* Not found */
}



static unsigned int match(const char* name, unsigned int *value,
			  unsigned int minimum, unsigned int maximum)
{
	char test;

	if (argc < 1)
		return -1;	/* no enough parameters */

	if (name) {
		if (strcmp(name, argv[0]))
			return -1;
		argc--;
		argv++;
	}

	if (argc < 1)
		error("Missing parameter\n");

	if (sscanf(argv[0], "%u%c", value, &test) != 1)
		error("Invalid parameter: %s\n", argv[0]);

	if ((*value > maximum) || (*value < minimum))
		error("Parameter out of range [%u - %u]: %u\n",
		      minimum, maximum, *value);

	argc--;
	argv++;
	return 0;
}


static parsertab ifaces[] = {{ "v35", IF_IFACE_V35 },
			     { "v24", IF_IFACE_V24 },
			     { "x21", IF_IFACE_X21 },
			     { "e1", IF_IFACE_E1 },
			     { "t1", IF_IFACE_T1 },
			     { NULL, 0 }};

static parsertab clocks[] = {{ "int", CLOCK_INT },
			     { "ext", CLOCK_EXT },
			     { "txint", CLOCK_TXINT },
			     { "txfromrx", CLOCK_TXFROMRX },
			     { NULL, 0 }};


static parsertab protos[] = {{ "hdlc", IF_PROTO_HDLC},
			     { "cisco", IF_PROTO_CISCO},
			     { "fr", IF_PROTO_FR},
			     { "ppp", IF_PROTO_PPP},
			     { "x25", IF_PROTO_X25},
#ifdef IF_PROTO_HDLC_ETH
			     { "hdlc-eth", IF_PROTO_HDLC_ETH},
#endif
			     { NULL, 0 }};


static parsertab hdlc_enc[] = {{ "nrz", ENCODING_NRZ },
			       { "nrzi", ENCODING_NRZI },
			       { "fm-mark", ENCODING_FM_MARK },
			       { "fm-space", ENCODING_FM_SPACE },
			       { "manchester", ENCODING_MANCHESTER },
			       { NULL, 0 }};

static parsertab hdlc_par[] = {{ "no-parity", PARITY_NONE },
			       { "crc16", PARITY_CRC16_PR1 },
			       { "crc16-pr0", PARITY_CRC16_PR0 },
			       { "crc16-itu", PARITY_CRC16_PR1_CCITT },
			       { "crc16-itu-pr0", PARITY_CRC16_PR0_CCITT },
			       { "crc32-itu", PARITY_CRC32_PR1_CCITT },
			       { NULL, 0 }};

static parsertab lmi[] = {{ "none", LMI_NONE },
			  { "ansi", LMI_ANSI },
			  { "ccitt", LMI_CCITT },
			  { NULL, 0 }};


static void set_iface(void)
{
	int orig_argc = argc;
	te1_settings te1;

	memset(&te1, 0, sizeof(te1));
	req.ifr_settings.type = IF_IFACE_SYNC_SERIAL;

	while (argc > 0) {
		if (req.ifr_settings.type == IF_IFACE_SYNC_SERIAL)
			if (!checktab(ifaces, &req.ifr_settings.type))
				continue;

		if (!te1.clock_type)
			if (!checkkey("clock")) {
				if (!checktab(clocks, &te1.clock_type))
					continue;
				error("Invalid clock type\n");
			}

		if (!te1.clock_rate &&
		    (te1.clock_type == CLOCK_INT ||
		     te1.clock_type == CLOCK_TXINT))
			if (!match("rate", &te1.clock_rate, 1, 0xFFFFFFFF))
				continue;
		if (!te1.loopback) {
			if (!checkkey("loopback") ||
			    !checkkey("lb")) {
				te1.loopback = 1;
				continue;
			}
		}
		/* slotmap goes here */

		if (orig_argc == argc)
			return;	/* not an iface definition */
		error("Invalid parameter: %s\n", argv[0]);
	}

	if (!te1.clock_rate &&
	    (te1.clock_type == CLOCK_INT ||
	     te1.clock_type == CLOCK_TXINT))
		te1.clock_rate = 64000;

	/* FIXME stupid hack, will remove it later */
	req.ifr_settings.ifs_ifsu.te1 = &te1;
	if (req.ifr_settings.type == IF_IFACE_E1 ||
	    req.ifr_settings.type == IF_IFACE_T1)
		req.ifr_settings.size = sizeof(te1_settings);
	else
		req.ifr_settings.size = sizeof(sync_serial_settings);

	if (ioctl(sock, SIOCWANDEV, &req))
		error("Unable to set interface information: %s\n",
		      strerror(errno));

	exit(0);
}



static void set_proto_fr(void)
{
	unsigned int lmi_type = 0;
	fr_proto fr;

	memset(&fr, 0, sizeof(fr));

	while (argc > 0) {
		if (!lmi_type)
			if (!checkkey("lmi")) {
				if (!checktab(lmi, &lmi_type))
					continue;
				error("Invalid LMI type: %s\n",
				      argv[0]);
			}

		if (lmi_type && lmi_type != LMI_NONE) {
			if (!fr.dce)
				if (!checkkey("dce")) {
					fr.dce = 1;
					continue;
				}

			if (!fr.t391)
				if (!match("t391", &fr.t391,
					   1, 1000))
					continue;
			if (!fr.t392)
				if (!match("t392", &fr.t392,
					   1, 1000))
					continue;
			if (!fr.n391)
				if (!match("n391", &fr.n391,
					   1, 1000))
					continue;
			if (!fr.n392)
				if (!match("n392", &fr.n392,
					   1, 1000))
					continue;
			if (!fr.n393)
				if (!match("n393", &fr.n393,
					   1, 1000))
					continue;
		}
		error("Invalid parameter: %s\n", argv[0]);
	}

	 /* polling verification timer*/
	if (!fr.t391) fr.t391 = 10;
	/* link integrity verification polling timer */
	if (!fr.t392) fr.t392 = 15;
	/* full status polling counter*/
	if (!fr.n391) fr.n391 = 6;
	/* error threshold */
	if (!fr.n392) fr.n392 = 3;
	/* monitored events count */
	if (!fr.n393) fr.n393 = 4;

	if (!lmi_type)
		fr.lmi = LMI_DEFAULT;
	else
		fr.lmi = lmi_type;

	req.ifr_settings.ifs_ifsu.fr = &fr;
	req.ifr_settings.size = sizeof(fr);

	if (ioctl(sock, SIOCWANDEV, &req))
		error("Unable to set FR protocol information: %s\n",
		      strerror(errno));
}



static void set_proto_hdlc(int eth)
{
	unsigned int enc = 0, par = 0;
	raw_hdlc_proto raw;

	memset(&raw, 0, sizeof(raw));

	while (argc > 0) {
		if (!enc)
			if (!checktab(hdlc_enc, &enc))
				continue;
		if (!par)
			if (!checktab(hdlc_par, &par))
				continue;

		error("Invalid parameter: %s\n", argv[0]);
	}

	if (!enc)
		raw.encoding = ENCODING_DEFAULT;
	else
		raw.encoding = enc;

	if (!par)
		raw.parity = ENCODING_DEFAULT;
	else
		raw.parity = par;

	req.ifr_settings.ifs_ifsu.raw_hdlc = &raw;
	req.ifr_settings.size = sizeof(raw);

	if (ioctl(sock, SIOCWANDEV, &req))
		error("Unable to set HDLC%s protocol information: %s\n",
		      eth ? "-ETH" : "", strerror(errno));
}



static void set_proto_cisco(void)
{
	cisco_proto cisco;
	memset(&cisco, 0, sizeof(cisco));

	while (argc > 0) {
		if (!cisco.interval)
			if (!match("interval", &cisco.interval,
				   1, 100))
				continue;
		if (!cisco.timeout)
			if (!match("timeout", &cisco.timeout,
				   1, 100))
				continue;

		error("Invalid parameter: %s\n",
		      argv[0]);
	}

	if (!cisco.interval)
		cisco.interval = 10;
	if (!cisco.timeout)
		cisco.timeout = 25;

	req.ifr_settings.ifs_ifsu.cisco = &cisco;
	req.ifr_settings.size = sizeof(cisco);

	if (ioctl(sock, SIOCWANDEV, &req))
		error("Unable to set Cisco HDLC protocol information: %s\n",
		      strerror(errno));
}



static void set_proto(void)
{
	if (checktab(protos, &req.ifr_settings.type))
		return;

	switch(req.ifr_settings.type) {
	case IF_PROTO_HDLC: set_proto_hdlc(0); break;
#ifdef IF_PROTO_HDLC_ETH
	case IF_PROTO_HDLC_ETH: set_proto_hdlc(1); break;
#endif
	case IF_PROTO_CISCO: set_proto_cisco(); break;
	case IF_PROTO_FR: set_proto_fr(); break;

	case IF_PROTO_PPP:
	case IF_PROTO_X25:
		req.ifr_settings.ifs_ifsu.sync = NULL; /* FIXME */
		req.ifr_settings.size = 0;

		if (!ioctl(sock, SIOCWANDEV, &req))
			break;

		error("Unable to set %s protocol information: %s\n",
		      req.ifr_settings.type == IF_PROTO_PPP
		      ? "PPP" : "X.25", strerror(errno));

	default: error("Unknown protocol %u\n", req.ifr_settings.type);
	}

	if (argc > 0)
		error("Unexpected parameter: %s\n", argv[0]);

	close(sock);
	exit(0);
}



static void set_pvc(void)
{
	char *op = argv[0];
	parsertab ops[] = {{ "create", IF_PROTO_FR_ADD_PVC },
			   { "delete", IF_PROTO_FR_DEL_PVC },
			   { NULL, 0 }};
	fr_proto_pvc pvc;

	memset(&pvc, 0, sizeof(pvc));

	if (checktab(ops, &req.ifr_settings.type))
		return;

#ifdef IF_PROTO_FR_ETH_PVC
	if (!match("ether", &pvc.dlci, 0, 1023)) {
		if (req.ifr_settings.type == IF_PROTO_FR_ADD_PVC)
			req.ifr_settings.type = IF_PROTO_FR_ADD_ETH_PVC;
		else
			req.ifr_settings.type = IF_PROTO_FR_DEL_ETH_PVC;

	} else
#endif
		if (match(NULL, &pvc.dlci, 0, 1023))
			return;

	if (argc != 0)
		return;

	req.ifr_settings.ifs_ifsu.fr_pvc = &pvc;
	req.ifr_settings.size = sizeof(pvc);

	if (ioctl(sock, SIOCWANDEV, &req))
		error("Unable to %s PVC: %s\n", op, strerror(errno));
	exit(0);
}



static void private(void)
{
	if (argc < 1)
		return;

	if (!strcmp(argv[0], "private")) {
		if (argc != 1)
			return;
		if (ioctl(sock, SIOCDEVPRIVATE, &req))
			error("SIOCDEVPRIVATE: %s\n", strerror(errno));
		exit(0);
	}
}



static void show_port(void)
{
	const char *s;
	char buffer[128];
	const te1_settings *te1 = (void*)buffer;
	const raw_hdlc_proto *raw = (void*)buffer;
	const cisco_proto *cisco = (void*)buffer;
	const fr_proto *fr = (void*)buffer;
#ifdef IF_PROTO_FR_PVC
	const fr_proto_pvc_info *pvc = (void*)buffer;
#endif
	req.ifr_settings.ifs_ifsu.sync = (void*)buffer; /* FIXME */

	printf("%s: ", req.ifr_name);

	req.ifr_settings.size = sizeof(buffer);
	req.ifr_settings.type = IF_GET_IFACE;

	if (ioctl(sock, SIOCWANDEV, &req))
		if (errno != EINVAL) {
			printf("unable to get interface information: %s\n",
			       strerror(errno));
			close(sock);
			exit(1);
		}
	
	/* Get and print physical interface settings */
	if (req.ifr_settings.type == IF_IFACE_SYNC_SERIAL)
		s = "";		/* Unspecified serial interface */
	else
		s = tabstr(req.ifr_settings.type, ifaces, NULL);

	if (!s)
		printf("unknown interface 0x%x\n", req.ifr_settings.type);
	else {
		if (*s)
			printf("interface %s ", s);

		printf("clock %s", tabstr(te1->clock_type, clocks,
					  "type unknown"));
		if (te1->clock_type == CLOCK_INT ||
		    te1->clock_type == CLOCK_TXINT)
			printf(" rate %u", te1->clock_rate);

		if (te1->loopback)
			printf(" loopback");

		if (req.ifr_settings.type == IF_IFACE_E1 ||
		    req.ifr_settings.type == IF_IFACE_T1) {
			unsigned int u;
			printf(" slotmap ");
			for (u = te1->slot_map; u != 0; u /= 2)
				printf("%u", u % 2);
		}
		printf("\n");
	}

	/* Get and print protocol settings */
	do {
		printf("\t");
		req.ifr_settings.size = sizeof(buffer);
		req.ifr_settings.type = IF_GET_PROTO;

		if (ioctl(sock, SIOCWANDEV, &req)) {
			if (errno == EINVAL)
				printf("no protocol set\n");
			else
				printf("unable to get protocol information: "
				       "%s\n", strerror(errno));
			break;
		}

		switch(req.ifr_settings.type) {
		case IF_PROTO_FR:
			printf("protocol fr lmi %s",
			       tabstr(fr->lmi, lmi, "unknown"));
			if (fr->lmi == LMI_ANSI ||
			    fr->lmi == LMI_CCITT)
				printf("%s t391 %u t392 %u n391 %u n392 %u "
				       "n393 %u\n",
				       fr->dce ? " dce" : "",
				       fr->t391,
				       fr->t392,
				       fr->n391,
				       fr->n392,
				       fr->n393);
			else
				putchar('\n');
			break;

#ifdef IF_PROTO_FR_PVC
		case IF_PROTO_FR_PVC:
			printf("Frame-Relay PVC: DLCI %u, master device %s\n",
			       pvc->dlci, pvc->master);
			break;
#endif

#ifdef IF_PROTO_FR_ETH_PVC
		case IF_PROTO_FR_ETH_PVC:
			printf("Frame-Relay PVC (Ethernet emulation): DLCI %u,"
			       " master device %s\n", pvc->dlci, pvc->master);
			break;
#endif

		case IF_PROTO_HDLC:
			printf("protocol hdlc %s %s\n",
			       tabstr(raw->encoding, hdlc_enc, "unknown"),
			       tabstr(raw->parity, hdlc_par, "unknown"));
			break;

#ifdef IF_PROTO_HDLC_ETH
		case IF_PROTO_HDLC_ETH:
			printf("protocol hdlc-eth %s %s\n",
			       tabstr(raw->encoding, hdlc_enc, "unknown"),
			       tabstr(raw->parity, hdlc_par, "unknown"));
			break;
#endif

		case IF_PROTO_CISCO:
			printf("protocol cisco interval %u timeout %u\n",
			       cisco->interval,
			       cisco->timeout);
			break;

		case IF_PROTO_PPP:
			printf("protocol ppp\n");
			break;

		case IF_PROTO_X25:
			printf("protocol x25\n");
			break;

		default:
			printf("unknown protocol %u\n", req.ifr_settings.type);
		}
	}while(0);

	close(sock);
	exit(0);
}



static void usage(void)
{
	fprintf(stderr, "sethdlc version 1.15\n"
		"Copyright (C) 2000 - 2003 Krzysztof Halasa <khc at pm.waw.pl>\n"
		"\n"
		"Usage: sethdlc INTERFACE [PHYSICAL] [clock CLOCK] [LOOPBACK] "
		"[slotmap SLOTMAP]\n"
		"       sethdlc INTERFACE [PROTOCOL]\n"
		"       sethdlc INTERFACE create | delete"
#ifdef IF_PROTO_FR_ETH_PVC
		" [ether]"
#endif
		" DLCI\n"
		"       sethdlc INTERFACE private...\n"
		"\n"
		"PHYSICAL := v24 | v35 | x21 | e1 | t1\n"
		"CLOCK := int [rate RATE] | ext | txint [rate RATE] | txfromrx\n"
		"LOOPBACK := loopback | lb\n"
		"\n"
		"PROTOCOL := hdlc [ENCODING] [PARITY] |\n"
#ifdef IF_PROTO_HDLC_ETH
		"            hdlc-eth [ENCODING] [PARITY] |\n"
#endif
		"            cisco [interval val] [timeout val] |\n"
		"            fr [lmi LMI] |\n"
		"            ppp |\n"
		"            x25\n"
		"\n"
		"ENCODING := nrz | nrzi | fm-mark | fm-space | manchester\n"
		"PARITY := no-parity | crc16 | crc16-pr0 | crc16-itu | crc16-itu-pr0 | crc32-itu\n"
		"LMI := none | ansi [LMI_SPEC] | ccitt [LMI_SPEC]\n"
		"LMI_SPEC := [dce] [t391 val] [t392 val] [n391 val] [n392 val] [n393 val]\n");
	exit(0);
}



int main(int arg_c, char *arg_v[])
{
	argc = arg_c;
	argv = arg_v;

	if (argc <= 1)
		usage();
  
	sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
	if (sock < 0)
		error("Unable to create socket: %s\n", strerror(errno));
  
	strcpy(req.ifr_name, argv[1]); /* Device name */

	if (argc == 2)
		show_port();

	argc -= 2;
	argv += 2;

	set_iface();
	set_proto();
	set_pvc();
	private();

	close(sock);
	usage();
	exit(0);
}

Index: Makefile
===================================================================
RCS file: /usr/cvsroot/zaptel/Makefile,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -d -r1.27 -r1.28
--- Makefile	14 Nov 2003 00:25:28 -0000	1.27
+++ Makefile	21 Nov 2003 09:30:54 -0000	1.28
@@ -60,7 +60,7 @@
 #
 # Uncomment for Generic PPP support (i.e. ZapRAS)
 #
-KFLAGS+=-DCONFIG_ZAPATA_PPP
+#KFLAGS+=-DCONFIG_ZAPATA_PPP
 #
 # Uncomment to enable "watchdog" to monitor if interfaces
 # stop taking interrupts or otherwise misbehave
@@ -249,7 +249,11 @@
 install:  all devices
 	mkdir -p $(INSTALL_PREFIX)/sbin
 	install -m 755 ztcfg $(INSTALL_PREFIX)/sbin
-	if [ -f sethdlc ]; then install -m 755 sethdlc $(INSTALL_PREFIX)/sbin ; fi
+	if [ -f sethdlc-new ]; then \
+		install -m 755 sethdlc-new $(INSTALL_PREFIX)/sbin/sethdlc; \
+	elsif [ -f sethdlc ]; then \
+		install -m 755 sethdlc $(INSTALL_PREFIX)/sbin ; \
+	fi
 	if [ -f zttool ]; then install -m 755 zttool $(INSTALL_PREFIX)/sbin; fi
 	mkdir -p $(INSTALL_PREFIX)/lib/modules/`uname -r`/misc
 	for x in $(MODULES); do \
@@ -321,7 +325,7 @@
 clean:
 	rm -f torisatool makefw tor2fw.h
 	rm -f zttool
-	rm -f *.o ztcfg tzdriver sethdlc
+	rm -f *.o ztcfg tzdriver sethdlc sethdlc-new
 	rm -f $(TZOBJS) $(LIBTONEZONE) *.lo
 	rm -f gendigits tones.h
 	rm -f libtonezone*

Index: zaptel.c
===================================================================
RCS file: /usr/cvsroot/zaptel/zaptel.c,v
retrieving revision 1.46
retrieving revision 1.47
diff -u -d -r1.46 -r1.47
--- zaptel.c	20 Nov 2003 17:30:56 -0000	1.46
+++ zaptel.c	21 Nov 2003 09:30:54 -0000	1.47
@@ -5382,7 +5382,11 @@
 		{
 			skb->mac.raw = skb->data;
 			skb->dev = &ms->hdlcnetdev->netdev.netdev;
+#if 0
 			skb->protocol = hdlc_type_trans(skb, &ms->hdlcnetdev->netdev.netdev);
+#else
+			skb->protocol = htons (ETH_P_HDLC);
+#endif
 			netif_rx(skb);
 		}
 #else




More information about the svn-commits mailing list