⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sethdlc-new.c

📁 This a SOFTWARE pbx DRIVER
💻 C
字号:
/* * sethdlc.c * * Copyright (C) 1999 - 2002 Krzysztof Halasa <khc@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"#endifstatic 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@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);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -