CVS: linux-atm/src/br2684 Makefile.am,NONE,1.1.2.1 br2684ctl.8,NONE,1.1.2.1 br2684ctl.c,NONE,1.1.2.1
From: chas w. <ch...@us...> - 2003-07-19 22:03:30
|
Update of /cvsroot/linux-atm/linux-atm/src/br2684 In directory sc8-pr-cvs1:/tmp/cvs-serv9154/src/br2684 Added Files: Tag: V2_5_0 Makefile.am br2684ctl.8 br2684ctl.c Log Message: add br2684ctl --- NEW FILE: Makefile.am --- sbin_PROGRAMS = br2684ctl LDADD = $(top_builddir)/src/lib/libatm.la br2684ctl_SOURCES = br2684ctl.c man_MANS = br2684ctl.8 EXTRA_DIST = $(man_MANS) USAGE.br2684 --- NEW FILE: br2684ctl.8 --- .\" .TH br2684ctl 1 "7 Jul 2003" .SH NAME br2684ctl \- RFC1483/2684 Bridge Daemon .SH SYNOPSIS .B br2684ctl [ .BI \-b ] [[ .BI \-c\ n ] [ .BI \-e\ 0|1 ] [ .BI \-s\ sndbuf ] [ .BI \-a\ [itf].vpi.vci ]] ... .SH PARAMETERS .TP 15 .BI \-a\ [itf].vpi.vci ATM PVC number, VPI and VCI. (Required) .BI \-b Puts the process in the background. .TP 15 .BI \-c\ n br2684 interface number such as 0, 1, ... (Required) .TP 15 .BI \-e\ 0|1 Encapsulation method: 0=LLC, 1=VC mux (the default is 0 or LLC) .TP 15 .TP 15 .BI \-s\ sndbuf Send buffer size. Default is 8192. .SH DESCRIPTION br2684ctl handles RFC1483/2684 bridged PDUs. This is most often used in ADSL scenarios where .I usually the subscribers' ethernet traffic is encapsulated in ATM AAL5 (by bridging ADSL modems) according to RFC2684. The subscriber-side ADSL modem can be external with an ethernet connector or an internal ADSL card in a PC. RFC1483 has been obsoleted by RFC2684. For example it is possible to set up your Linux box to handle several ATM PVC's with bridged-1483 (sometimes referred as SNAP) encapsulation. The Linux network stack might provide DHCP, IP masquerading, IP firewall services or bridge the Ethernet frames just like it had several ethernet interfaces. In fact it can have several (logical) ethernet interfaces, where ATM is just used as a carrier. .SH USAGE br2684ctl creates a new network interface named nas[n] which is bound to an specific ATM PVC. It requires two mandatory arguments: -c, the interface number, and -a, the ATM PVC. It should be noted that the order of the command arguments matter; -c should be followed by -a. You can create as many interfaces as necessary in one go, just make a long command line ;) For example, following command will create a nas0 interface which uses the ATM PVC with VPI=0 and VCI=401. You need to configure the PVC connection 0.401 on the ATM switch manually. % br2684ctl -c 0 -a 0.401 The command will only create a new interface nas0. Next step is to assign an IP address and netmask to the interface nas0 using the ifconfig command. Using ifconfig, you can also assign a Ethernet MAC address to the interface nas0, if necessary. % ifconfig nas0 192.168.2.1 netmask 255.255.255.0 .SH NOTES This man page is based on a tutorial by by Joonbum Byun <jb...@me...> .SH SEE ALSO .BR qos (7) --- NEW FILE: br2684ctl.c --- #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <errno.h> #include <sys/ioctl.h> #include <string.h> #include <syslog.h> #include <atm.h> #include <linux/atmdev.h> #include <linux/atmbr2684.h> /* Written by Marcell GAL <ce...@sc...> to make use of the */ /* ioctls defined in the br2684... kernel patch */ /* Compile with cc -o br2684ctl br2684ctl.c -latm */ /* Modified feb 2001 by Stephen Aaskov (sa...@la...) - Added daemonization code - Added syslog TODO: Delete interfaces after exit? */ #define LOG_NAME "RFC1483/2684 bridge" #define LOG_OPTION LOG_PERROR #define LOG_FACILITY LOG_LOCAL0 int lastsock, lastitf; void fatal(const char *str, int i) { syslog (LOG_ERR,"Fatal: %s",str); exit(-2); }; void exitFunc(void) { syslog (LOG_PID,"Daemon terminated\n"); } int create_br(char *nstr) { int num, err; if(lastsock<0) { lastsock = socket(PF_ATMPVC, SOCK_DGRAM, ATM_AAL5); } if (lastsock<0) { syslog(LOG_ERR, "socket creation failed: %s",strerror(errno)); } else { /* create the device with ioctl: */ num=atoi(nstr); if( num>=0 && num<1234567890){ struct atm_newif_br2684 ni; ni.backend_num = ATM_BACKEND_BR2684; ni.media = BR2684_MEDIA_ETHERNET; ni.mtu = 1500; sprintf(ni.ifname, "nas%d", num); err=ioctl (lastsock, ATM_NEWBACKENDIF, &ni); if (err == 0) syslog(LOG_INFO, "Interface \"%s\" created sucessfully\n",ni.ifname); else syslog(LOG_INFO, "Interface \"%s\" could not be created, reason: %s\n", ni.ifname, strerror(errno)); lastitf=num; /* even if we didn't create, because existed, assign_vcc wil want to know it! */ } else { syslog(LOG_ERR,"err: strange interface number %d", num ); } } return 0; } int assign_vcc(char *astr, int encap, int bufsize) { int err; struct atm_qos qos; struct sockaddr_atmpvc addr; int fd; struct atm_backend_br2684 be; memset(&addr, 0, sizeof(addr)); err=text2atm(astr,(struct sockaddr *)(&addr), sizeof(addr), T2A_PVC); if (err!=0) syslog(LOG_ERR,"Could not parse ATM parameters (error=%d)\n",err); #if 0 addr.sap_family = AF_ATMPVC; addr.sap_addr.itf = itf; addr.sap_addr.vpi = 0; addr.sap_addr.vci = vci; #endif syslog(LOG_INFO,"Communicating over ATM %d.%d.%d, encapsulation: %s\n", addr.sap_addr.itf, addr.sap_addr.vpi, addr.sap_addr.vci, encap?"VC mux":"LLC"); if ((fd = socket(PF_ATMPVC, SOCK_DGRAM, ATM_AAL5)) < 0) syslog(LOG_ERR,"failed to create socket %d, reason: %s", errno,strerror(errno)); memset(&qos, 0, sizeof(qos)); qos.aal = ATM_AAL5; qos.txtp.traffic_class = ATM_UBR; qos.txtp.max_sdu = 1524; qos.txtp.pcr = ATM_MAX_PCR; qos.rxtp = qos.txtp; if ( (err=setsockopt(fd,SOL_SOCKET,SO_SNDBUF, &bufsize ,sizeof(bufsize))) ) syslog(LOG_ERR,"setsockopt SO_SNDBUF: (%d) %s\n",err, strerror(err)); if (setsockopt(fd, SOL_ATM, SO_ATMQOS, &qos, sizeof(qos)) < 0) syslog(LOG_ERR,"setsockopt SO_ATMQOS %d", errno); err = connect(fd, (struct sockaddr*)&addr, sizeof(struct sockaddr_atmpvc)); if (err < 0) fatal("failed to connect on socket", err); /* attach the vcc to device: */ be.backend_num = ATM_BACKEND_BR2684; be.ifspec.method = BR2684_FIND_BYIFNAME; sprintf(be.ifspec.spec.ifname, "nas%d", lastitf); be.fcs_in = BR2684_FCSIN_NO; be.fcs_out = BR2684_FCSOUT_NO; be.fcs_auto = 0; be.encaps = encap ? BR2684_ENCAPS_VC : BR2684_ENCAPS_LLC; be.has_vpiid = 0; be.send_padding = 0; be.min_size = 0; err=ioctl (fd, ATM_SETBACKEND, &be); if (err == 0) syslog (LOG_INFO,"Interface configured"); else { syslog (LOG_ERR,"Could not configure interface:%s",strerror(errno)); exit(2); } return fd ; } void usage(char *s) { printf("usage: %s [-b] [[-c number] [-e 0|1] [-s sndbuf] [-a [itf.]vpi.vci]*]*\n", s); exit(1); } int main (int argc, char **argv) { int c, background=0, encap=0, sndbuf=8192; lastsock=-1; lastitf=0; openlog (LOG_NAME,LOG_OPTION,LOG_FACILITY); if (argc>1) while ((c = getopt(argc, argv,"a:bc:e:s:?h")) !=EOF) switch (c) { case 'a': assign_vcc(optarg, encap, sndbuf); break; case 'b': background=1; break; case 'c': create_br(optarg); break; case 'e': encap=(atoi(optarg)); if(encap<0){ syslog (LOG_ERR, "invalid encapsulation: %s:\n",optarg); encap=0; } break; case 's': sndbuf=(atoi(optarg)); if(sndbuf<0){ syslog(LOG_ERR, "Invalid sndbuf: %s, using size of 8192 instead\n",optarg); sndbuf=8192; } break; case '?': case 'h': default: usage(argv[0]); } else usage(argv[0]); if (argc != optind) usage(argv[0]); if(lastsock>=0) close(lastsock); if (background) { pid_t pid; pid=fork(); if (pid < 0) { fprintf(stderr,"Error detaching\n"); exit(2); } else if (pid) exit(0); // This is the parent // Become a process group and session group leader if (setsid()<0) { fprintf (stderr,"Could not set process group\n"); exit(2); } // Fork again to let process group leader exit pid = fork(); if (pid < 0) { fprintf(stderr,"Error detaching during second fork\n"); exit(2); } else if (pid) exit(0); // This is the parent // Now we're ready for buisness chdir("/"); // Don't keep directories in use close(0); close(1); close(2); // Close stdin, -out and -error /* Note that this implementation does not keep an open stdout/err. If we need them they can be opened now */ } syslog (LOG_INFO, "RFC 1483/2684 bridge daemon started\n"); atexit (exitFunc); while (1) sleep(30); /* to keep the sockets... */ return 0; } |