1
0
This repository has been archived on 2024-07-22. You can view files and clone it, but cannot push or open issues or pull requests.
Files
2024-07-22 01:58:46 -03:00

137 lines
3.0 KiB
C

/* atmloop.c - get/set loopback mode of ATM interfaces */
/* Written 2000 by Werner Almesberger, EPFL ICA */
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/ioctl.h>
#include <atm.h>
#include <linux/atmdev.h>
static void usage(const char *name)
{
fprintf(stderr,"usage: %s -s [ -l level ] [ -r level ] [ itf ]\n",name);
fprintf(stderr,"%7s%s [ itf ]\n","",name);
fprintf(stderr,"%7s%s -q [ itf ]\n","",name);
fprintf(stderr,"%7s%s -V\n","",name);
fprintf(stderr," levels: aal = AAL PDU, atm = ATM cell,\n");
fprintf(stderr,"%10sphy = line (digital), analog = line (analog)\n","");
exit(1);
}
static int text2level(const char *name,const char *s)
{
if (!strcmp(s,"aal")) return __ATM_LM_AAL;
if (!strcmp(s,"atm")) return __ATM_LM_ATM;
if (!strcmp(s,"phy")) return __ATM_LM_PHY;
if (!strcmp(s,"analog")) return __ATM_LM_ANALOG;
usage(name);
return 0; /* uh ... */
}
static const char *level2text(int level)
{
switch (level) {
case __ATM_LM_AAL:
return "aal";
case __ATM_LM_ATM:
return "atm";
case __ATM_LM_PHY:
return "phy";
case __ATM_LM_ANALOG:
return "analog";
default:
return "???";
}
}
static void print_levels(int levels,int show_none)
{
int mask;
if (!levels) {
if (show_none) printf(" (none)");
return;
}
for (mask = 1; levels; mask += mask) {
if (!(mask & levels)) continue;
printf(" %s",level2text(__ATM_LM_XTLOC(mask)));
levels &= ~mask;
}
}
int main(int argc,char **argv)
{
int local = ATM_LM_NONE,remote = ATM_LM_NONE,mode;
int set = 0,query = 0;
struct atmif_sioc req;
int s,c;
req.number = 0;
while ((c = getopt(argc,argv,"l:qr:sV")) != EOF)
switch (c) {
case 'l':
if (local) usage(*argv);
local = text2level(*argv,optarg);
break;
case 'q':
query = 1;
break;
case 'r':
if (remote) usage(*argv);
remote = text2level(*argv,optarg);
break;
case 's':
set = 1;
break;
case 'V':
printf("%s\n",VERSION);
return 0;
default:
usage(*argv);
}
if (argc > optind+1) usage(*argv);
if (argc == optind+1) {
char *end;
req.number = strtoul(argv[optind],&end,0);
if (*end) usage(*argv);
}
mode = __ATM_LM_MKLOC(local) | __ATM_LM_MKRMT(remote);
if ((mode && !set) || (set && query)) usage(*argv);
s = socket(PF_ATMPVC,SOCK_DGRAM,0);
if (s < 0) {
perror("socket");
return 1;
}
if (set) {
req.arg = (void *) mode;
req.length = 0;
if (ioctl(s,ATM_SETLOOP,&req) < 0) {
perror("ioctl ATM_SETLOOP");
return 1;
}
return 0;
}
req.arg = &mode;
req.length = sizeof(mode);
if (ioctl(s,query ? ATM_QUERYLOOP : ATM_GETLOOP,&req) < 0) {
perror(query ? "ioctl ATM_QUERYLOOP" : "ioctl ATM_GETLOOP");
return 1;
}
printf("local: ");
print_levels(__ATM_LM_XTLOC(mode),query);
printf("\nremote:");
print_levels(__ATM_LM_XTRMT(mode),query);
printf("\n");
return 0;
}