ppp.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2002 by Call Direct Cellular Solutions Pty. Ltd. All rights reserved.
00003  *
00004  * Redistribution and use in source and binary forms, with or without
00005  * modification, are permitted provided that the following conditions
00006  * are met:
00007  *
00008  * 1. Redistributions of source code must retain the above copyright
00009  *    notice, this list of conditions and the following disclaimer.
00010  * 2. Redistributions in binary form must reproduce the above copyright
00011  *    notice, this list of conditions and the following disclaimer in the
00012  *    documentation and/or other materials provided with the distribution.
00013  * 3. Neither the name of the copyright holders nor the names of
00014  *    contributors may be used to endorse or promote products derived
00015  *    from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY CALL DIRECT CELLULAR SOLUTIONS AND CONTRIBUTORS
00018  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00019  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00020  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL CALL DIRECT
00021  * CELLULAR SOLUTIONS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00022  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00023  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
00024  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
00025  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00026  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
00027  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00028  * SUCH DAMAGE.
00029  *
00030  * For additional information see http://www.calldirect.com.au/
00031  * -
00032  * Copyright (C) 2001-2004 by egnite Software GmbH. All rights reserved.
00033  *
00034  * Redistribution and use in source and binary forms, with or without
00035  * modification, are permitted provided that the following conditions
00036  * are met:
00037  *
00038  * 1. Redistributions of source code must retain the above copyright
00039  *    notice, this list of conditions and the following disclaimer.
00040  * 2. Redistributions in binary form must reproduce the above copyright
00041  *    notice, this list of conditions and the following disclaimer in the
00042  *    documentation and/or other materials provided with the distribution.
00043  * 3. All advertising materials mentioning features or use of this
00044  *    software must display the following acknowledgement:
00045  *
00046  *    This product includes software developed by egnite Software GmbH
00047  *    and its contributors.
00048  *
00049  * THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH AND CONTRIBUTORS
00050  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00051  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00052  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL EGNITE
00053  * SOFTWARE GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00054  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00055  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
00056  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
00057  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00058  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
00059  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00060  * SUCH DAMAGE.
00061  *
00062  * For additional information see http://www.ethernut.de/
00063  *
00064  */
00065 
00066 /*
00067  * $Log: ppp.c,v $
00068  * Revision 1.10  2007/07/17 18:32:27  haraldkipp
00069  * Fixed bug #1369171, memory leak in NutPppClose(). Thanks to Sergey Danilov.
00070  *
00071  * Revision 1.9  2007/05/02 11:22:51  haraldkipp
00072  * Added multicast table entry.
00073  *
00074  * Revision 1.8  2006/03/29 01:23:52  olereinhardt
00075  *  Signednes of strings
00076  *
00077  * Revision 1.7  2005/04/30 16:42:41  chaac
00078  * Fixed bug in handling of NUTDEBUG. Added include for cfg/os.h. If NUTDEBUG
00079  * is defined in NutConf, it will make effect where it is used.
00080  *
00081  * Revision 1.6  2004/03/16 16:48:27  haraldkipp
00082  * Added Jan Dubiec's H8/300 port.
00083  *
00084  * Revision 1.5  2004/03/14 10:12:29  haraldkipp
00085  * Bugfix, failed to compile
00086  *
00087  * Revision 1.4  2004/03/08 11:15:32  haraldkipp
00088  * HDLC functions moved to async HDLC driver.
00089  *
00090  * Revision 1.3  2003/08/14 15:21:01  haraldkipp
00091  * Bugfix, allow HDLC flag to mark end _and_ begin
00092  *
00093  * Revision 1.2  2003/08/05 20:05:11  haraldkipp
00094  * DNS removed from interface
00095  *
00096  * Revision 1.1.1.1  2003/05/09 14:40:48  haraldkipp
00097  * Initial using 3.2.1
00098  *
00099  * Revision 1.2  2003/05/06 18:33:50  harald
00100  * PPP hack for simple UART support, functions reordered.
00101  *
00102  * Revision 1.1  2003/03/31 14:53:08  harald
00103  * Prepare release 3.1
00104  *
00105  */
00106 
00107 #include <cfg/os.h>
00108 #include <string.h>
00109 #include <io.h>
00110 #include <fcntl.h>
00111 
00112 #include <net/if_var.h>
00113 #include <net/ppp.h>
00114 
00115 #include <sys/heap.h>
00116 #include <sys/event.h>
00117 #include <sys/timer.h>
00118 #include <sys/thread.h>
00119 
00120 #include <dev/ppp.h>
00121 #include <netinet/ppp_fsm.h>
00122 #include <dev/ahdlc.h>
00123 
00124 #ifdef NUTDEBUG
00125 #include <net/netdebug.h>
00126 #endif
00127 
00132 
00133 static PPPDCB dcb_ppp;
00134 
00135 
00136 /*
00137  * Pass reads to the physical driver for now.
00138  */
00139 static int NutPppRead(NUTFILE * fp, void *buffer, int size)
00140 {
00141     return _read(((PPPDCB *) (fp->nf_dev->dev_dcb))->dcb_fd, buffer, size);
00142 }
00143 
00144 /*
00145  * Pass writes to the physical driver for now.
00146  */
00147 static int NutPppWrite(NUTFILE * fp, CONST void *buffer, int len)
00148 {
00149     return _write(((PPPDCB *) (fp->nf_dev->dev_dcb))->dcb_fd, buffer, len);
00150 }
00151 
00152 /*
00153  * Pass writes to the physical driver for now.
00154  */
00155 #ifdef __HARVARD_ARCH__
00156 static int NutPppWrite_P(NUTFILE * fp, PGM_P buffer, int len)
00157 {
00158     return _write_P(((PPPDCB *) (fp->nf_dev->dev_dcb))->dcb_fd, buffer, len);
00159 }
00160 #endif
00161 
00181 static int NutPppIOCtl(NUTDEVICE * dev, int req, void *conf)
00182 {
00183     int rc = 0;
00184 
00185     switch (req) {
00186     case LCP_OPEN:
00187         LcpOpen(dev);
00188         break;
00189 
00190     case LCP_CLOSE:
00191         LcpClose(dev);
00192         break;
00193 
00194     case LCP_LOWERUP:
00195         LcpLowerUp(dev);
00196         break;
00197 
00198     case LCP_LOWERDOWN:
00199         LcpLowerDown(dev);
00200         break;
00201 
00202     default:
00203         rc = _ioctl(((PPPDCB *) (dev->dev_dcb))->dcb_fd, req, conf);
00204         break;
00205     }
00206     return rc;
00207 }
00208 
00209 /*
00210  * \brief Enable the link layer to come up.
00211  *
00212  * The underlying hardware driver should have established a physical 
00213  * connection before calling this function.
00214  *
00215  * \param name Physical device name optionally followed by username 
00216  *             and password, each separated by a slash.
00217  *
00218  */
00219 static NUTFILE *NutPppOpen(NUTDEVICE * dev, CONST char *name, int mode, int acc)
00220 {
00221     NUTFILE *fp;
00222     u_char i;
00223     char *cp;
00224     char *sp;
00225     char pdn[9];
00226     PPPDCB *dcb = dev->dev_dcb;
00227 
00228     /* Clear our device control block. */
00229     memset(dcb, 0, sizeof(PPPDCB));
00230 
00231     /* Get the first part of the name, it specifies the physical device. */
00232     for (cp = (char *) name, i = 0; *cp && *cp != '/' && i < sizeof(pdn) - 1; i++) {
00233         pdn[i] = *cp++;
00234     }
00235     pdn[i] = 0;
00236 
00237     /* Open the pysical device. */
00238     if ((dcb->dcb_fd = _open(pdn, _O_RDWR | _O_BINARY)) == -1) {
00239         return NUTFILE_EOF;
00240     }
00241 
00242     /*
00243      * Allocate a file structure to return.
00244      */
00245     if ((fp = NutHeapAlloc(sizeof(NUTFILE))) == 0) {
00246         return NUTFILE_EOF;
00247     }
00248     fp->nf_next = 0;
00249     fp->nf_dev = dev;
00250     fp->nf_fcb = 0;
00251 
00252     /*
00253      * Extract user name and password and store it in our device control
00254      * block. It will be used later by the authentication layer.
00255      */
00256     if (*cp == '/') {
00257         for (sp = ++cp, i = 0; *sp && *sp != '/'; sp++, i++);
00258         if (i) {
00259             dcb->dcb_user = NutHeapAlloc(i + 1);
00260             for (sp = (char*)dcb->dcb_user; *cp && *cp != '/';)
00261                 *sp++ = *cp++;
00262             *sp = 0;
00263         }
00264         if (*cp == '/') {
00265             for (sp = ++cp, i = 0; *sp && *sp != '/'; sp++, i++);
00266             if (i) {
00267                 dcb->dcb_pass = NutHeapAlloc(i + 1);
00268                 for (sp = (char*)dcb->dcb_pass; *cp && *cp != '/';)
00269                     *sp++ = *cp++;
00270                 *sp = 0;
00271             }
00272         }
00273     }
00274 
00275     /* Enable all layers to come up. */
00276     IpcpOpen(dev);
00277 
00278     return fp;
00279 }
00280 
00281 
00282 /*
00283  * Start closing connection.
00284  */
00285 static int NutPppClose(NUTFILE * fp)
00286 {
00287     PPPDCB *dcb = fp->nf_dev->dev_dcb;
00288 
00289     IpcpClose(fp->nf_dev);
00290     _close(dcb->dcb_fd);
00291 
00292     if (dcb->dcb_user)
00293         NutHeapFree(dcb->dcb_user);
00294     if (dcb->dcb_pass)
00295         NutHeapFree(dcb->dcb_pass);
00296     NutHeapFree(fp);
00297 
00298     return 0;
00299 }
00300 
00311 static int NutPppInit(NUTDEVICE * dev)
00312 {
00313     return NutPppInitStateMachine(dev);
00314 }
00315 
00319 IFNET ifn_ppp = {
00320     IFT_PPP,                    
00321     {0, 0, 0, 0, 0, 0}
00322     ,                           
00323     0,                          
00324     0,                          
00325     0,                          
00326     PPP_MRU,                    
00327     0,                          
00328     0,                          
00329     0,                          
00330     NutPppInput,                
00331     0,                          
00332     NutPppOutput                
00333 };
00334 
00342 NUTDEVICE devPpp = {
00343     0,                          /* Pointer to next device, dev_next. */
00344     {'p', 'p', 'p', 0, 0, 0, 0, 0, 0}
00345     ,                           /* Unique device name, dev_name. */
00346     IFTYP_NET,                  /* Type of device, dev_type. */
00347     0,                          /* Base address, dev_base. */
00348     0,                          /* First interrupt number, dev_irq. */
00349     &ifn_ppp,                   /* Interface control block, dev_icb. */
00350     &dcb_ppp,                   /* Driver control block, dev_dcb. */
00351     NutPppInit,                 /* Driver initialization routine, dev_init(). */
00352     NutPppIOCtl,                /* Driver specific control function, dev_ioctl(). */
00353     NutPppRead,                 /* Read from device, dev_read. */
00354     NutPppWrite,                /* Write to device, dev_write. */
00355 #ifdef __HARVARD_ARCH__
00356     NutPppWrite_P,              /* Write data from program space to device, dev_write_P. */
00357 #endif
00358     NutPppOpen,                 /* Open a device or file, dev_open. */
00359     NutPppClose,                /* Close a device or file, dev_close. */
00360     0                           /* Request file size. */
00361 };
00362 

© 2000-2007 by egnite Software GmbH - visit http://www.ethernut.de/