1031 lines
42 KiB
C
1031 lines
42 KiB
C
/* $Id: isdnctrl.c,v 1.1 1997/02/17 00:09:21 fritz Exp $
|
|
* ISDN driver for Linux. (Control-Utility)
|
|
*
|
|
* Copyright 1994,95 by Fritz Elfert (fritz@wuemaus.franken.de)
|
|
* Copyright 1995 Thinking Objects Software GmbH Wuerzburg
|
|
*
|
|
* This file is part of Isdn4Linux.
|
|
*
|
|
* 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, or (at your option)
|
|
* any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
*
|
|
* $Log: isdnctrl.c,v $
|
|
* Revision 1.1 1997/02/17 00:09:21 fritz
|
|
* New CVS tree
|
|
*
|
|
* Revision 1.14 1996/06/06 22:08:46 fritz
|
|
* Bugfix: verbose and getconf checked wrong number of parameters.
|
|
* thanks to Andreas Jaeger <aj@arthur.pfalz.de>
|
|
*
|
|
* Revision 1.13 1996/04/30 12:48:35 fritz
|
|
* Added Michael's ippp-bind patch.
|
|
*
|
|
* Revision 1.12 1996/04/30 12:43:18 fritz
|
|
* Changed ioctl-names according to kernel-version
|
|
*
|
|
* Revision 1.11 1996/01/04 02:44:52 fritz
|
|
* Changed copying policy to GPL
|
|
* Added addslave, dial, sdelay and mapping.
|
|
*
|
|
* Revision 1.10 1995/12/18 18:03:19 fritz
|
|
* New License, minor cleanups.
|
|
*
|
|
* Revision 1.9 1995/10/29 21:38:51 fritz
|
|
* Changed all references to driver-numbers to new DriverId's
|
|
*
|
|
* Revision 1.8 1995/07/15 20:39:56 fritz
|
|
* Added support for cisco_h Encapsulation.
|
|
* Added suppurt for pre-binding an interface to a channel.
|
|
*
|
|
* Revision 1.7 1995/04/29 13:13:44 fritz
|
|
* Added new command verbose.
|
|
*
|
|
* Revision 1.6 1995/04/23 13:38:34 fritz
|
|
* Adapted addphone and delphone to support changes in isdn.c
|
|
*
|
|
* Revision 1.5 1995/03/25 23:35:35 fritz
|
|
* Added ihup-Feature.
|
|
*
|
|
* Revision 1.4 1995/03/15 12:44:15 fritz
|
|
* Added generic conversion-routines for keyword<->value conversion.
|
|
* Added display of phone-numbers in list-routine
|
|
* Corrected some typos
|
|
*
|
|
* Revision 1.3 1995/02/20 03:38:59 fritz
|
|
* Added getmax and rmax for performance-tests of tty-driver.
|
|
*
|
|
* Revision 1.2 1995/01/29 23:27:52 fritz
|
|
* Added keywords: list, l2_proto, l3_proto, huptimeout, chargehup and
|
|
* encap.
|
|
*
|
|
* Revision 1.1 1995/01/09 07:35:35 fritz
|
|
* Initial revision
|
|
*
|
|
*
|
|
*/
|
|
|
|
#undef ISDN_DEBUG_MODEM_SENDOPT
|
|
|
|
#include <stdio.h>
|
|
#include <sys/ioctl.h>
|
|
#include <sys/types.h>
|
|
#include <fcntl.h>
|
|
#include <unistd.h>
|
|
#include <string.h>
|
|
|
|
#include <linux/isdn.h>
|
|
#include <linux/isdnif.h>
|
|
|
|
char *l2protostr[] = {
|
|
"x75i", "x75ui", "x75bui", "hdlc", "\0"
|
|
};
|
|
|
|
int l2protoval[] = {
|
|
ISDN_PROTO_L2_X75I, ISDN_PROTO_L2_X75UI,
|
|
ISDN_PROTO_L2_X75BUI, ISDN_PROTO_L2_HDLC, -1
|
|
};
|
|
|
|
char *l3protostr[] = {
|
|
"trans", "\0"
|
|
};
|
|
|
|
int l3protoval[] = {
|
|
ISDN_PROTO_L3_TRANS, -1
|
|
};
|
|
|
|
char *pencapstr[] = {
|
|
"ethernet", "rawip", "ip", "cisco-h", "syncppp",
|
|
"uihdlc", "\0"
|
|
};
|
|
|
|
int pencapval[] = {
|
|
ISDN_NET_ENCAP_ETHER, ISDN_NET_ENCAP_RAWIP,
|
|
ISDN_NET_ENCAP_IPTYP, ISDN_NET_ENCAP_CISCOHDLC,
|
|
ISDN_NET_ENCAP_SYNCPPP, ISDN_NET_ENCAP_UIHDLC, -1
|
|
};
|
|
|
|
char *num2callb[] = {
|
|
"off", "in", "out"
|
|
};
|
|
|
|
char *cmd;
|
|
char nextlistif[10];
|
|
|
|
void usage(void)
|
|
{
|
|
fprintf(stderr, "usage: %s <command> <options>\n", cmd);
|
|
#if 0
|
|
fprintf(stderr, "\n");
|
|
fprintf(stderr, "where <command> is one of the following:\n");
|
|
fprintf(stderr, "\n");
|
|
fprintf(stderr, " addif [name] add net-interface\n");
|
|
fprintf(stderr, " delif name remove net-interface\n");
|
|
fprintf(stderr, " addphone name in|out num add phone-number to interface\n");
|
|
fprintf(stderr, " delphone name in|out num remove phone-number from interface\n");
|
|
fprintf(stderr, " eaz name [eaz|msn] get/set eaz for interface\n");
|
|
fprintf(stderr, " huptimeout name [seconds] get/set hangup-timeout for interface\n");
|
|
fprintf(stderr, " ihup name [on|off] get/set incoming-hangup for interface\n");
|
|
fprintf(stderr, " chargehup name [on|off] get/set charge-hangup for interface\n");
|
|
fprintf(stderr, " chargeint name [seconds] get/set charge-interval if not given by telco\n");
|
|
fprintf(stderr, " secure name [on|off] get/set secure-feature for interface\n");
|
|
fprintf(stderr, " callback name [in|outon|off]\n");
|
|
fprintf(stderr, " get/set active callback-feature for interface\n");
|
|
fprintf(stderr, " cbhup name [on|off] get/set reject-before-callback for interface\n");
|
|
fprintf(stderr, " cbdelay name [seconds] get/set delay before callback for interface\n");
|
|
fprintf(stderr, " dialmax name [num] get/set number of dial-atempts for interface\n");
|
|
fprintf(stderr, " encap name [encapname] get/set packet-encapsulation for interface\n");
|
|
fprintf(stderr, " l2_prot name [protocol] get/set layer-2-protocol for interface\n");
|
|
fprintf(stderr, " l3_prot name [protocol] get/set layer-3-protocol for interface\n");
|
|
fprintf(stderr, " bind name [drvId,channel [exclusive]]\n");
|
|
fprintf(stderr, " pre-bind interface to a channel\n");
|
|
fprintf(stderr, " unbind name delete pre-binding\n");
|
|
fprintf(stderr, " list name|all show current setup of interface(s)\n");
|
|
fprintf(stderr, " verbose num set verbose-level\n");
|
|
fprintf(stderr, " hangup name force hangup of interface\n");
|
|
fprintf(stderr, " busreject drvId on|off set bus-reject-mode\n");
|
|
fprintf(stderr, " mapping drvId [MSN,MSN...] set MSN<->EAZ-Mapping\n");
|
|
fprintf(stderr, " addslave name slavename add slave-interface\n");
|
|
fprintf(stderr, " sdelay mastername delay set slave-activation delay\n");
|
|
fprintf(stderr, " dial name force dialing of interface\n");
|
|
fprintf(stderr, " system on|off switch isdn-system on or off\n");
|
|
fprintf(stderr, " addlink name MPPP, increase number of links\n");
|
|
fprintf(stderr, " removelink name MPPP, decrease number of links\n");
|
|
fprintf(stderr, " pppbind name [devicenum] PPP, bind interface to ippp-device (exclusive)\n");
|
|
fprintf(stderr, " pppunbind name PPP, remove ippp-device binding\n");
|
|
#endif
|
|
exit(-2);
|
|
}
|
|
|
|
static int key2num(char *key, char **keytable, int *numtable)
|
|
{
|
|
int i = -1;
|
|
while (strlen(keytable[++i]))
|
|
if (!strcmp(keytable[i], key))
|
|
return numtable[i];
|
|
return -1;
|
|
}
|
|
|
|
static char *
|
|
num2key(int num, char **keytable, int *numtable)
|
|
{
|
|
int i = -1;
|
|
while (numtable[++i] >= 0)
|
|
if (numtable[i] == num)
|
|
return keytable[i];
|
|
return "???";
|
|
}
|
|
|
|
static void listbind(char *s, int e)
|
|
{
|
|
if (strlen(s)) {
|
|
char *p = strchr(s, ',');
|
|
int ch;
|
|
sscanf(p + 1, "%d", &ch);
|
|
*p = '\0';
|
|
printf("%s, Channel %d%s\n", s, ch, (e > 0) ? ", exclusive" : "");
|
|
} else
|
|
printf("Nothing\n");
|
|
}
|
|
|
|
static void listif(int isdnctrl, char *name, int errexit)
|
|
{
|
|
isdn_net_ioctl_cfg cfg;
|
|
union p {
|
|
isdn_net_ioctl_phone phone;
|
|
char n[1024];
|
|
} ph;
|
|
char nn[1024];
|
|
|
|
strcpy(cfg.name, name);
|
|
if (ioctl(isdnctrl, IIOCNETGCF, &cfg) < 0) {
|
|
if (errexit) {
|
|
perror(name);
|
|
exit(-1);
|
|
} else
|
|
return;
|
|
}
|
|
strcpy(ph.phone.name, name);
|
|
ph.phone.outgoing = 0;
|
|
if (ioctl(isdnctrl, IIOCNETGNM, &ph.phone) < 0) {
|
|
if (errexit) {
|
|
perror(name);
|
|
exit(-1);
|
|
} else
|
|
return;
|
|
}
|
|
strcpy(nn, ph.n);
|
|
strcpy(ph.phone.name, name);
|
|
ph.phone.outgoing = 1;
|
|
if (ioctl(isdnctrl, IIOCNETGNM, &ph.phone) < 0) {
|
|
if (errexit) {
|
|
perror(name);
|
|
exit(-1);
|
|
} else
|
|
return;
|
|
}
|
|
printf("\nCurrent setup of interface '%s':\n\n", cfg.name);
|
|
printf("EAZ/MSN: %s\n", cfg.eaz);
|
|
printf("Phone number(s):\n");
|
|
printf(" Outgoing: %s\n", ph.n);
|
|
printf(" Incoming: %s\n", nn);
|
|
printf("Secure: %s\n", cfg.secure ? "on" : "off");
|
|
printf("Callback: %s\n", num2callb[cfg.callback]);
|
|
if (cfg.callback == 2)
|
|
printf("Hangup after Dial %s\n", cfg.cbdelay ? "on" : "off");
|
|
else
|
|
printf("Reject before Callback: %s\n", cfg.cbhup ? "on" : "off");
|
|
printf("Callback-delay: %d\n", cfg.cbdelay / 5);
|
|
printf("Dialmax: %d\n", cfg.dialmax);
|
|
printf("Hangup-Timeout: %d\n", cfg.onhtime);
|
|
printf("Incoming-Hangup: %s\n", cfg.ihup ? "on" : "off");
|
|
printf("ChargeHangup: %s\n", cfg.chargehup ? "on" : "off");
|
|
printf("Charge-Units: %d\n", cfg.charge);
|
|
printf("Charge-Interval: %d\n", cfg.chargeint);
|
|
printf("Layer-2-Protocol: %s\n", num2key(cfg.l2_proto, l2protostr, l2protoval));
|
|
printf("Layer-3-Protocol: %s\n", num2key(cfg.l3_proto, l3protostr, l3protoval));
|
|
printf("Encapsulation: %s\n", num2key(cfg.p_encap, pencapstr, pencapval));
|
|
printf("Slave Interface: %s\n", strlen(cfg.slave) ? cfg.slave : "None");
|
|
printf("Slave delay: %d\n", cfg.slavedelay);
|
|
printf("Master Interface: %s\n", strlen(cfg.master) ? cfg.master : "None");
|
|
printf("Pre-Bound to: ");
|
|
listbind(cfg.drvid, cfg.exclusive);
|
|
if (cfg.slave && strlen(cfg.slave))
|
|
strcpy(nextlistif, cfg.slave);
|
|
else
|
|
nextlistif[0] = '\0';
|
|
}
|
|
|
|
static void get_setup(int isdnctrl, char *name)
|
|
{
|
|
isdn_net_ioctl_cfg cfg;
|
|
char buffer[0x1000];
|
|
char *p;
|
|
FILE *f;
|
|
|
|
if (ioctl(isdnctrl, IIOCGETSET, &buffer) < 0) {
|
|
perror("ioctl GET_SETUP");
|
|
exit(-1);
|
|
}
|
|
if (strcmp(name,"-"))
|
|
f = fopen(name, "w");
|
|
else
|
|
f = stdout;
|
|
if (!f) {
|
|
perror(name);
|
|
exit(-1);
|
|
}
|
|
p = buffer;
|
|
fprintf(f,"[isdnctrl]\n");
|
|
while (strlen(p)) {
|
|
if (strlen(cfg.master)) {
|
|
fprintf(f, " netslave=\"%s\"\n", p);
|
|
fprintf(f, " master=\"%s\"\n", p);
|
|
} else
|
|
fprintf(f, " netif=\"%s\"\n", p);
|
|
p += 10;
|
|
memcpy((char *) &cfg, p, sizeof(cfg));
|
|
fprintf(f, " eazmsn=\"%s\"\n", cfg.eaz);
|
|
fprintf(f, " secure=%d\n", cfg.secure);
|
|
fprintf(f, " callback=%d\n", cfg.callback);
|
|
fprintf(f, " huptimeout=%d\n", cfg.onhtime);
|
|
fprintf(f, " ihup=%d\n", cfg.ihup);
|
|
fprintf(f, " chargehup=%d\n", cfg.chargehup);
|
|
fprintf(f, " l2prot=%d\n", cfg.l2_proto);
|
|
fprintf(f, " l3prot=%d\n", cfg.l3_proto);
|
|
fprintf(f, " encap=%d\n", cfg.p_encap);
|
|
fprintf(f, " chargeint=%d\n", cfg.chargeint);
|
|
fprintf(f, " slavedelay=%d\n", cfg.slavedelay);
|
|
fprintf(f, " exclusive=%d\n", cfg.exclusive);
|
|
fprintf(f, " binddev=\"%s\"\n", cfg.drvid);
|
|
p += sizeof(cfg);
|
|
fprintf(f, " outphones=\"%s\"\n", p);
|
|
p += (strlen(p) + 1);
|
|
fprintf(f, " inphones=\"%s\"\n", p);
|
|
p += (strlen(p) + 1);
|
|
}
|
|
if (f != stdout)
|
|
fclose(f);
|
|
}
|
|
|
|
enum {
|
|
ADDIF, ADDSLAVE, DELIF, DIAL,
|
|
BIND, UNBIND, PPPBIND, PPPUNBIND,
|
|
BUSREJECT, MAPPING, SYSTEM, HANGUP,
|
|
ADDPHONE, DELPHONE, LIST, EAZ,
|
|
VERBOSE, GETCONF, HUPTIMEOUT, CBDELAY,
|
|
CHARGEINT, DIALMAX, SDELAY, CHARGEHUP,
|
|
CBHUP, IHUP, SECURE, CALLBACK,
|
|
L2_PROT, L3_PROT, ADDLINK, REMOVELINK,
|
|
ENCAP
|
|
};
|
|
|
|
typedef struct {
|
|
char *cmd;
|
|
char *argno;
|
|
} cmd_struct;
|
|
|
|
static cmd_struct cmds[] =
|
|
{
|
|
{"addif", "0"},
|
|
{"addslave", "1"},
|
|
{"delif", "0"},
|
|
{"dial", "0"},
|
|
{"bind", "12"},
|
|
{"unbind", "0"},
|
|
{"pppbind", "1"},
|
|
{"pppunbind", "0"},
|
|
{"busreject", "1"},
|
|
{"mapping", "0"},
|
|
{"system", "0"},
|
|
{"hangup", "0"},
|
|
{"addphone", "2"},
|
|
{"delphone", "2"},
|
|
{"list", "0"},
|
|
{"eaz", "01"},
|
|
{"verbose", "0"},
|
|
{"getconf", "0"},
|
|
{"huptimeout", "01"},
|
|
{"cbdelay", "01"},
|
|
{"chargeint", "01"},
|
|
{"dialmax", "01"},
|
|
{"sdelay", "01"},
|
|
{"chargehup", "01"},
|
|
{"cbhup", "01"},
|
|
{"ihup", "01"},
|
|
{"secure", "01"},
|
|
{"callback", "01"},
|
|
{"l2_prot", "01"},
|
|
{"l3_prot", "01"},
|
|
{"addlink", "0"},
|
|
{"removelink", "0"},
|
|
{"encap", "01"},
|
|
{NULL,}
|
|
};
|
|
|
|
int findcmd(char *str)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; cmds[i].cmd; i++)
|
|
if (!strcmp(cmds[i].cmd, str))
|
|
return i;
|
|
return -1;
|
|
}
|
|
|
|
void main(int argc, char **argv)
|
|
{
|
|
int fd;
|
|
int i,
|
|
n,
|
|
args,
|
|
cmdptr;
|
|
int result;
|
|
FILE *iflst;
|
|
char *p;
|
|
char s[255];
|
|
isdn_net_ioctl_phone phone;
|
|
isdn_net_ioctl_cfg cfg;
|
|
isdn_ioctl_struct iocts;
|
|
unsigned long j;
|
|
char nstring[255];
|
|
char *id;
|
|
char *arg1;
|
|
char *arg2;
|
|
|
|
cmd = argv[0];
|
|
if (argc < 3) {
|
|
usage();
|
|
return;
|
|
}
|
|
fd = open("/dev/isdnctrl", O_RDWR);
|
|
if (fd < 0) {
|
|
perror("/dev/isdnctrl");
|
|
exit(-1);
|
|
}
|
|
id = argv[2];
|
|
i = findcmd(argv[1]);
|
|
for (cmdptr = 2; cmdptr < argc;) {
|
|
if (i < 0) { /* Unknown command */
|
|
fprintf(stderr, "The given command \"%s\" is unknown.\n\n", argv[cmdptr]);
|
|
usage();
|
|
return;
|
|
}
|
|
if (i != GETCONF) {
|
|
if (strlen(id) > 8) {
|
|
fprintf(stderr, "Interface name must not exceed 8 characters!\n");
|
|
close(fd);
|
|
return;
|
|
}
|
|
}
|
|
args = 0;
|
|
for (n = 0; cmds[i].argno[n]; n++) {
|
|
args = cmds[i].argno[n] - '0';
|
|
if (!n && (args + cmdptr > argc - 1)) {
|
|
fprintf(stderr, "Too few arguments given for %s\n", cmds[i].cmd);
|
|
usage();
|
|
return;
|
|
}
|
|
if (n && ((cmdptr + args > argc - 1) || findcmd(argv[cmdptr + args]) >= 0)) {
|
|
args = cmds[i].argno[n - 1] - '0';
|
|
break;
|
|
}
|
|
}
|
|
arg1 = args ? argv[cmdptr + 1] : "";
|
|
arg2 = (args > 1) ? argv[cmdptr + 2] : "";
|
|
switch (i) {
|
|
case ADDIF:
|
|
strcpy(s, id);
|
|
if ((result = ioctl(fd, IIOCNETAIF, s)) < 0) {
|
|
perror("addif");
|
|
exit(-1);
|
|
}
|
|
printf("%s added\n", s);
|
|
break;
|
|
|
|
case ADDSLAVE:
|
|
if (strlen(arg1) > 8) {
|
|
fprintf(stderr, "slavename must not exceed 8 characters\n");
|
|
exit(-1);
|
|
}
|
|
sprintf(s, "%s,%s", id, arg1);
|
|
if ((result = ioctl(fd, IIOCNETASL, s)) < 0) {
|
|
perror("addslave");
|
|
exit(-1);
|
|
}
|
|
printf("%s added as slave to %s\n", s, id);
|
|
break;
|
|
|
|
case DELIF:
|
|
if ((result = ioctl(fd, IIOCNETDIF, id)) < 0) {
|
|
perror(id);
|
|
exit(-1);
|
|
}
|
|
printf("%s deleted\n", id);
|
|
break;
|
|
|
|
case DIAL:
|
|
if ((result = ioctl(fd, IIOCNETDIL, id)) < 0) {
|
|
perror(id);
|
|
exit(-1);
|
|
}
|
|
printf("Dialing of %s triggered\n", id);
|
|
break;
|
|
|
|
case BIND:
|
|
if (args == 2)
|
|
if (strncmp(arg2, "excl", 4))
|
|
usage();
|
|
strcpy(cfg.name, id);
|
|
if ((result = ioctl(fd, IIOCNETGCF, &cfg)) < 0) {
|
|
perror(id);
|
|
exit(-1);
|
|
}
|
|
sscanf(argv[3], "%s", cfg.drvid);
|
|
cfg.exclusive = (args == 2);
|
|
if ((result = ioctl(fd, IIOCNETSCF, &cfg)) < 0) {
|
|
sprintf(s, "%s or %s", id, arg2);
|
|
perror(s);
|
|
exit(-1);
|
|
}
|
|
printf("%s bound to ", id);
|
|
listbind(cfg.drvid, cfg.exclusive);
|
|
break;
|
|
|
|
case UNBIND:
|
|
strcpy(cfg.name, id);
|
|
if ((result = ioctl(fd, IIOCNETGCF, &cfg)) < 0) {
|
|
perror(id);
|
|
exit(-1);
|
|
}
|
|
if (!strlen(cfg.drvid)) {
|
|
printf("%s was not bound to anything\n", id);
|
|
exit(0);
|
|
}
|
|
cfg.drvid[0] = '\0';
|
|
cfg.exclusive = -1;
|
|
if ((result = ioctl(fd, IIOCNETSCF, &cfg)) < 0) {
|
|
perror(id);
|
|
exit(-1);
|
|
}
|
|
printf("%s unbound successfully\n", id);
|
|
break;
|
|
|
|
case PPPBIND:
|
|
strcpy(cfg.name, id);
|
|
if ((result = ioctl(fd, IIOCNETGCF, &cfg)) < 0) {
|
|
perror(id);
|
|
exit(-1);
|
|
}
|
|
sscanf(arg1, "%d", &cfg.pppbind);
|
|
if ((result = ioctl(fd, IIOCNETSCF, &cfg)) < 0) {
|
|
sprintf(s, "%s or %s", id, arg1);
|
|
perror(s);
|
|
exit(-1);
|
|
}
|
|
printf("%s bound to %s", id, arg1);
|
|
break;
|
|
|
|
case PPPUNBIND:
|
|
strcpy(cfg.name, id);
|
|
if ((result = ioctl(fd, IIOCNETGCF, &cfg)) < 0) {
|
|
perror(id);
|
|
exit(-1);
|
|
}
|
|
if (cfg.pppbind < 0) {
|
|
printf("%s was not bound to anything\n", id);
|
|
exit(0);
|
|
}
|
|
cfg.pppbind = -1;
|
|
if ((result = ioctl(fd, IIOCNETSCF, &cfg)) < 0) {
|
|
perror(id);
|
|
exit(-1);
|
|
}
|
|
printf("%s unbound successfully\n", id);
|
|
break;
|
|
|
|
case BUSREJECT:
|
|
strcpy(iocts.drvid, id);
|
|
if (strcmp(arg1, "on") && strcmp(arg1, "off")) {
|
|
fprintf(stderr, "Bus-Reject must be 'on' or 'off'\n");
|
|
exit(-1);
|
|
}
|
|
iocts.arg = strcmp(arg1, "off");
|
|
if ((result = ioctl(fd, IIOCSETBRJ, &iocts)) < 0) {
|
|
perror(id);
|
|
exit(-1);
|
|
}
|
|
break;
|
|
|
|
case MAPPING:
|
|
strcpy(iocts.drvid, id);
|
|
if (!args) {
|
|
iocts.arg = (unsigned long) &nstring;
|
|
if ((result = ioctl(fd, IIOCGETMAP, &iocts)) < 0) {
|
|
perror(id);
|
|
exit(-1);
|
|
}
|
|
printf("MSN/EAZ-mapping for %s:\n%s\n", id, nstring);
|
|
} else {
|
|
char buf[400];
|
|
strncpy(buf, arg1, sizeof(buf) - 1);
|
|
iocts.arg = (unsigned long) buf;
|
|
if ((result = ioctl(fd, IIOCSETMAP, &iocts)) < 0) {
|
|
perror(id);
|
|
exit(-1);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case SYSTEM:
|
|
if (strcmp(id, "on") && strcmp(id, "off")) {
|
|
fprintf(stderr, "System-Mode must be 'on' or 'off'\n");
|
|
exit(-1);
|
|
}
|
|
j = strcmp(id, "on");
|
|
if ((result = ioctl(fd, IIOCSETGST, j)) < 0) {
|
|
perror(id);
|
|
exit(-1);
|
|
}
|
|
break;
|
|
|
|
case HANGUP:
|
|
if ((result = ioctl(fd, IIOCNETHUP, id)) < 0) {
|
|
perror(id);
|
|
exit(-1);
|
|
}
|
|
if (result)
|
|
printf("%s not connected\n", id);
|
|
else
|
|
printf("%s hung up\n", id);
|
|
break;
|
|
|
|
case ADDPHONE:
|
|
if (strcmp(arg1, "in") && strcmp(arg1, "out")) {
|
|
fprintf(stderr, "Direction must be \"in\" or \"out\"\n");
|
|
exit(-1);
|
|
}
|
|
phone.outgoing = strcmp(arg1, "out") ? 0 : 1;
|
|
if (strlen(arg2) > 20) {
|
|
fprintf(stderr, "phone-number must not exceed 20 characters\n");
|
|
exit(-1);
|
|
}
|
|
strcpy(phone.name, id);
|
|
strcpy(phone.phone, arg2);
|
|
if ((result = ioctl(fd, IIOCNETANM, &phone)) < 0) {
|
|
perror(id);
|
|
exit(-1);
|
|
}
|
|
break;
|
|
|
|
case DELPHONE:
|
|
if (strcmp(arg1, "in") && strcmp(arg1, "out")) {
|
|
fprintf(stderr, "Direction must be \"in\" or \"out\"\n");
|
|
exit(-1);
|
|
}
|
|
phone.outgoing = strcmp(arg1, "out") ? 0 : 1;
|
|
if (strlen(arg2) > 20) {
|
|
fprintf(stderr, "phone-number must not exceed 20 characters\n");
|
|
exit(-1);
|
|
}
|
|
strcpy(phone.name, id);
|
|
strcpy(phone.phone, arg2);
|
|
if ((result = ioctl(fd, IIOCNETDNM, &phone)) < 0) {
|
|
perror(id);
|
|
exit(-1);
|
|
}
|
|
break;
|
|
|
|
case LIST:
|
|
if (!strcmp(id, "all")) {
|
|
char name[10];
|
|
if ((iflst = fopen("/proc/net/dev", "r")) == NULL) {
|
|
perror("/proc/net/dev");
|
|
exit(-1);
|
|
}
|
|
while (!feof(iflst)) {
|
|
fgets(s, sizeof(s), iflst);
|
|
if ((p = strchr(s, ':'))) {
|
|
*p = 0;
|
|
sscanf(s, "%s", name);
|
|
listif(fd, name, 0);
|
|
while (strlen(nextlistif))
|
|
listif(fd, nextlistif, 0);
|
|
}
|
|
}
|
|
fclose(iflst);
|
|
} else
|
|
listif(fd, id, 1);
|
|
break;
|
|
|
|
case EAZ:
|
|
strcpy(cfg.name, id);
|
|
if ((result = ioctl(fd, IIOCNETGCF, &cfg)) < 0) {
|
|
perror(id);
|
|
exit(-1);
|
|
}
|
|
if (args) {
|
|
i = -1;
|
|
strncpy(cfg.eaz, arg1, sizeof(cfg.eaz) - 1);
|
|
if ((result = ioctl(fd, IIOCNETSCF, &cfg)) < 0) {
|
|
perror(id);
|
|
exit(-1);
|
|
}
|
|
}
|
|
printf("EAZ/MSN for %s is %s\n", cfg.name, cfg.eaz);
|
|
break;
|
|
|
|
case VERBOSE:
|
|
i = -1;
|
|
sscanf(id, "%d", &i);
|
|
if (i < 0) {
|
|
fprintf(stderr, "Verbose-level must be >= 0\n");
|
|
exit(-1);
|
|
}
|
|
if ((result = ioctl(fd, IIOCSETVER, i)) < 0) {
|
|
perror("IIOCSETVER");
|
|
exit(-1);
|
|
}
|
|
printf("Verbose-level set to %d.\n", i);
|
|
break;
|
|
|
|
case GETCONF:
|
|
get_setup(fd, id);
|
|
printf("Configuration written to %s.\n", id);
|
|
break;
|
|
|
|
case HUPTIMEOUT:
|
|
strcpy(cfg.name, id);
|
|
if ((result = ioctl(fd, IIOCNETGCF, &cfg)) < 0) {
|
|
perror(id);
|
|
exit(-1);
|
|
}
|
|
if (args) {
|
|
i = -1;
|
|
sscanf(arg1, "%d", &i);
|
|
if (i < 0) {
|
|
fprintf(stderr, "Hangup-Timeout must be >= 0\n");
|
|
exit(-1);
|
|
}
|
|
cfg.onhtime = i;
|
|
if ((result = ioctl(fd, IIOCNETSCF, &cfg)) < 0) {
|
|
perror(id);
|
|
exit(-1);
|
|
}
|
|
}
|
|
printf("Hangup-Timeout for %s is %d sec.\n", cfg.name, cfg.onhtime);
|
|
break;
|
|
|
|
case CBDELAY:
|
|
strcpy(cfg.name, id);
|
|
if ((result = ioctl(fd, IIOCNETGCF, &cfg)) < 0) {
|
|
perror(id);
|
|
exit(-1);
|
|
}
|
|
if (args) {
|
|
i = -1;
|
|
sscanf(arg1, "%d", &i);
|
|
if (i < 0) {
|
|
fprintf(stderr, "Callback delay must be >= 0\n");
|
|
exit(-1);
|
|
}
|
|
cfg.cbdelay = i * 5;
|
|
if ((result = ioctl(fd, IIOCNETSCF, &cfg)) < 0) {
|
|
perror(id);
|
|
exit(-1);
|
|
}
|
|
}
|
|
printf("Callback delay for %s is %d sec.\n", cfg.name, cfg.cbdelay / 5);
|
|
break;
|
|
|
|
case CHARGEINT:
|
|
strcpy(cfg.name, id);
|
|
if ((result = ioctl(fd, IIOCNETGCF, &cfg)) < 0) {
|
|
perror(id);
|
|
exit(-1);
|
|
}
|
|
if (args) {
|
|
i = -1;
|
|
sscanf(arg1, "%d", &i);
|
|
if (i < 0) {
|
|
fprintf(stderr, "Charge interval must be >= 0\n");
|
|
exit(-1);
|
|
}
|
|
cfg.chargeint = i;
|
|
if ((result = ioctl(fd, IIOCNETSCF, &cfg)) < 0) {
|
|
perror(id);
|
|
exit(-1);
|
|
}
|
|
}
|
|
printf("Charge Interval for %s is %d sec.\n", cfg.name, cfg.chargeint);
|
|
break;
|
|
|
|
case DIALMAX:
|
|
strcpy(cfg.name, id);
|
|
if ((result = ioctl(fd, IIOCNETGCF, &cfg)) < 0) {
|
|
perror(id);
|
|
exit(-1);
|
|
}
|
|
if (args) {
|
|
i = -1;
|
|
sscanf(arg1, "%d", &i);
|
|
if (i < 1) {
|
|
fprintf(stderr, "Dialmax must be > 0\n");
|
|
exit(-1);
|
|
}
|
|
cfg.dialmax = i;
|
|
if ((result = ioctl(fd, IIOCNETSCF, &cfg)) < 0) {
|
|
perror(id);
|
|
exit(-1);
|
|
}
|
|
}
|
|
printf("Dialmax for %s is %d times.\n", cfg.name, cfg.dialmax);
|
|
break;
|
|
|
|
case SDELAY:
|
|
strcpy(cfg.name, id);
|
|
if ((result = ioctl(fd, IIOCNETGCF, &cfg)) < 0) {
|
|
perror(id);
|
|
exit(-1);
|
|
}
|
|
if (args) {
|
|
i = -1;
|
|
sscanf(arg1, "%d", &i);
|
|
if (i < 1) {
|
|
fprintf(stderr, "Slave-activation delay must be >= 1\n");
|
|
exit(-1);
|
|
}
|
|
cfg.slavedelay = i;
|
|
if ((result = ioctl(fd, IIOCNETSCF, &cfg)) < 0) {
|
|
perror(id);
|
|
exit(-1);
|
|
}
|
|
}
|
|
printf("Slave-activation delay for %s is %d sec.\n", cfg.name,
|
|
cfg.slavedelay);
|
|
break;
|
|
|
|
case CHARGEHUP:
|
|
strcpy(cfg.name, id);
|
|
if ((result = ioctl(fd, IIOCNETGCF, &cfg)) < 0) {
|
|
perror(id);
|
|
exit(-1);
|
|
}
|
|
if (args) {
|
|
i = -1;
|
|
if (strcmp(arg1, "on") && strcmp(arg1, "off")) {
|
|
fprintf(stderr, "Charge-Hangup must be 'on' or 'off'\n");
|
|
exit(-1);
|
|
}
|
|
cfg.chargehup = strcmp(arg1, "off");
|
|
if ((result = ioctl(fd, IIOCNETSCF, &cfg)) < 0) {
|
|
perror(id);
|
|
exit(-1);
|
|
}
|
|
}
|
|
printf("Charge-Hangup for %s is %s\n", cfg.name, cfg.chargehup ? "on" : "off");
|
|
break;
|
|
|
|
case CBHUP:
|
|
strcpy(cfg.name, id);
|
|
if ((result = ioctl(fd, IIOCNETGCF, &cfg)) < 0) {
|
|
perror(id);
|
|
exit(-1);
|
|
}
|
|
if (args) {
|
|
i = -1;
|
|
if (strcmp(arg1, "on") && strcmp(arg1, "off")) {
|
|
fprintf(stderr, "Callback-Hangup must be 'on' or 'off'\n");
|
|
exit(-1);
|
|
}
|
|
cfg.cbhup = strcmp(arg1, "off");
|
|
if ((result = ioctl(fd, IIOCNETSCF, &cfg)) < 0) {
|
|
perror(id);
|
|
exit(-1);
|
|
}
|
|
}
|
|
printf("Reject before Callback for %s is %s\n", cfg.name, cfg.cbhup ? "on" : "off");
|
|
break;
|
|
|
|
case IHUP:
|
|
strcpy(cfg.name, id);
|
|
if ((result = ioctl(fd, IIOCNETGCF, &cfg)) < 0) {
|
|
perror(id);
|
|
exit(-1);
|
|
}
|
|
if (args) {
|
|
i = -1;
|
|
if (strcmp(arg1, "on") && strcmp(arg1, "off")) {
|
|
fprintf(stderr, "Incoming-Hangup must be 'on' or 'off'\n");
|
|
exit(-1);
|
|
}
|
|
cfg.ihup = strcmp(arg1, "off");
|
|
if ((result = ioctl(fd, IIOCNETSCF, &cfg)) < 0) {
|
|
perror(id);
|
|
exit(-1);
|
|
}
|
|
}
|
|
printf("Incoming-Hangup for %s is %s\n", cfg.name, cfg.ihup ? "on" : "off");
|
|
break;
|
|
|
|
case SECURE:
|
|
strcpy(cfg.name, id);
|
|
if ((result = ioctl(fd, IIOCNETGCF, &cfg)) < 0) {
|
|
perror(id);
|
|
exit(-1);
|
|
}
|
|
if (args) {
|
|
i = -1;
|
|
if (strcmp(arg1, "on") && strcmp(arg1, "off")) {
|
|
fprintf(stderr, "Secure-parameter must be 'on' or 'off'\n");
|
|
exit(-1);
|
|
}
|
|
cfg.secure = strcmp(arg1, "off");
|
|
if ((result = ioctl(fd, IIOCNETSCF, &cfg)) < 0) {
|
|
perror(id);
|
|
exit(-1);
|
|
}
|
|
}
|
|
printf("Security for %s is %s\n", cfg.name, cfg.secure ? "on" : "off");
|
|
break;
|
|
|
|
case CALLBACK:
|
|
strcpy(cfg.name, id);
|
|
if ((result = ioctl(fd, IIOCNETGCF, &cfg)) < 0) {
|
|
perror(id);
|
|
exit(-1);
|
|
}
|
|
if (args) {
|
|
i = -1;
|
|
if (strcmp(arg1, "on") && strcmp(arg1, "off") &&
|
|
strcmp(arg1, "in") && strcmp(arg1, "out")) {
|
|
fprintf(stderr, "Callback-parameter must be 'on', 'in', 'out' or 'off'\n");
|
|
exit(-1);
|
|
}
|
|
cfg.callback = strcmp(arg1, "off") ? 1 : 0;
|
|
if (!strcmp(arg1, "out"))
|
|
cfg.callback = 2;
|
|
if ((result = ioctl(fd, IIOCNETSCF, &cfg)) < 0) {
|
|
perror(id);
|
|
exit(-1);
|
|
}
|
|
}
|
|
printf("Callback for %s is %s\n", cfg.name, num2callb[cfg.callback]);
|
|
break;
|
|
|
|
case L2_PROT:
|
|
strcpy(cfg.name, id);
|
|
if ((result = ioctl(fd, IIOCNETGCF, &cfg)) < 0) {
|
|
perror(id);
|
|
exit(-1);
|
|
}
|
|
if (args) {
|
|
i = key2num(arg1, l2protostr, l2protoval);
|
|
if (i < 0) {
|
|
fprintf(stderr, "Layer-2-Protocol must be one of the following:\n");
|
|
i = 0;
|
|
while (strlen(l2protostr[i]))
|
|
fprintf(stderr, "\t\"%s\"\n", l2protostr[i++]);
|
|
exit(-1);
|
|
}
|
|
cfg.l2_proto = i;
|
|
if ((result = ioctl(fd, IIOCNETSCF, &cfg)) < 0) {
|
|
perror(id);
|
|
exit(-1);
|
|
}
|
|
}
|
|
printf("Layer-2-Protocol for %s is %s\n", cfg.name,
|
|
num2key(cfg.l2_proto, l2protostr, l2protoval));
|
|
break;
|
|
|
|
case L3_PROT:
|
|
strcpy(cfg.name, id);
|
|
if ((result = ioctl(fd, IIOCNETGCF, &cfg)) < 0) {
|
|
perror(id);
|
|
exit(-1);
|
|
}
|
|
if (args) {
|
|
i = key2num(arg1, l3protostr, l3protoval);
|
|
if (i < 0) {
|
|
fprintf(stderr, "Layer-3-Protocol must be one of the following:\n");
|
|
i = 0;
|
|
while (strlen(l3protostr[i]))
|
|
fprintf(stderr, "\t\"%s\"\n", l3protostr[i++]);
|
|
exit(-1);
|
|
}
|
|
cfg.l3_proto = i;
|
|
if ((result = ioctl(fd, IIOCNETSCF, &cfg)) < 0) {
|
|
perror(id);
|
|
exit(-1);
|
|
}
|
|
}
|
|
printf("Layer-3-Protocol for %s is %s\n", cfg.name,
|
|
num2key(cfg.l3_proto, l3protostr, l3protoval));
|
|
break;
|
|
|
|
case ADDLINK:
|
|
if ((result = ioctl(fd, IIOCNETALN, id)) < 0) {
|
|
perror(id);
|
|
exit(-1);
|
|
}
|
|
if (result)
|
|
printf("Can't increase number of links: %d\n", result);
|
|
else
|
|
printf("Ok, added a new link. (dialing)\n");
|
|
break;
|
|
|
|
case REMOVELINK:
|
|
if ((result = ioctl(fd, IIOCNETDLN, id)) < 0) {
|
|
perror(id);
|
|
exit(-1);
|
|
}
|
|
if (result)
|
|
printf("Can't decrease number of links: %d\n", result);
|
|
else
|
|
printf("Ok, removed a link. (hangup)\n");
|
|
break;
|
|
|
|
case ENCAP:
|
|
strcpy(cfg.name, id);
|
|
if ((result = ioctl(fd, IIOCNETGCF, &cfg)) < 0) {
|
|
perror(id);
|
|
exit(-1);
|
|
}
|
|
if (args) {
|
|
i = key2num(arg1, pencapstr, pencapval);
|
|
if (i < 0) {
|
|
fprintf(stderr, "Encapsulation must be one of the following:\n");
|
|
i = 0;
|
|
while (strlen(pencapstr[i]))
|
|
fprintf(stderr, "\t\"%s\"\n", pencapstr[i++]);
|
|
exit(-1);
|
|
}
|
|
cfg.p_encap = i;
|
|
if ((result = ioctl(fd, IIOCNETSCF, &cfg)) < 0) {
|
|
perror(id);
|
|
exit(-1);
|
|
}
|
|
}
|
|
printf("Encapsulation for %s is %s\n", cfg.name,
|
|
num2key(cfg.p_encap, pencapstr, pencapval));
|
|
break;
|
|
}
|
|
cmdptr += args + 1;
|
|
if (cmdptr < argc) {
|
|
printf("args=%d nextcmd %s\n",args, argv[cmdptr]);
|
|
i = findcmd(argv[cmdptr]);
|
|
}
|
|
}
|
|
close(fd);
|
|
}
|