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.11  2008/08/11 06:59:42  haraldkipp
00069  * BSD types replaced by stdint types (feature request #1282721).
00070  *
00071  * Revision 1.10  2007/07/17 18:32:27  haraldkipp
00072  * Fixed bug #1369171, memory leak in NutPppClose(). Thanks to Sergey Danilov.
00073  *
00074  * Revision 1.9  2007/05/02 11:22:51  haraldkipp
00075  * Added multicast table entry.
00076  *
00077  * Revision 1.8  2006/03/29 01:23:52  olereinhardt
00078  *  Signednes of strings
00079  *
00080  * Revision 1.7  2005/04/30 16:42:41  chaac
00081  * Fixed bug in handling of NUTDEBUG. Added include for cfg/os.h. If NUTDEBUG
00082  * is defined in NutConf, it will make effect where it is used.
00083  *
00084  * Revision 1.6  2004/03/16 16:48:27  haraldkipp
00085  * Added Jan Dubiec's H8/300 port.
00086  *
00087  * Revision 1.5  2004/03/14 10:12:29  haraldkipp
00088  * Bugfix, failed to compile
00089  *
00090  * Revision 1.4  2004/03/08 11:15:32  haraldkipp
00091  * HDLC functions moved to async HDLC driver.
00092  *
00093  * Revision 1.3  2003/08/14 15:21:01  haraldkipp
00094  * Bugfix, allow HDLC flag to mark end _and_ begin
00095  *
00096  * Revision 1.2  2003/08/05 20:05:11  haraldkipp
00097  * DNS removed from interface
00098  *
00099  * Revision 1.1.1.1  2003/05/09 14:40:48  haraldkipp
00100  * Initial using 3.2.1
00101  *
00102  * Revision 1.2  2003/05/06 18:33:50  harald
00103  * PPP hack for simple UART support, functions reordered.
00104  *
00105  * Revision 1.1  2003/03/31 14:53:08  harald
00106  * Prepare release 3.1
00107  *
00108  */
00109 
00110 #include <cfg/os.h>
00111 #include <string.h>
00112 #include <io.h>
00113 #include <fcntl.h>
00114 
00115 #include <net/if_var.h>
00116 #include <net/ppp.h>
00117 
00118 #include <sys/heap.h>
00119 #include <sys/event.h>
00120 #include <sys/timer.h>
00121 #include <sys/thread.h>
00122 
00123 #include <dev/ppp.h>
00124 #include <netinet/ppp_fsm.h>
00125 #include <dev/ahdlc.h>
00126 
00127 #ifdef NUTDEBUG
00128 #include <net/netdebug.h>
00129 #endif
00130 
00135 
00136 static PPPDCB dcb_ppp;
00137 
00138 
00139 /*
00140  * Pass reads to the physical driver for now.
00141  */
00142 static int NutPppRead(NUTFILE * fp, void *buffer, int size)
00143 {
00144     return _read(((PPPDCB *) (fp->nf_dev->dev_dcb))->dcb_fd, buffer, size);
00145 }
00146 
00147 /*
00148  * Pass writes to the physical driver for now.
00149  */
00150 static int NutPppWrite(NUTFILE * fp, CONST void *buffer, int len)
00151 {
00152     return _write(((PPPDCB *) (fp->nf_dev->dev_dcb))->dcb_fd, buffer, len);
00153 }
00154 
00155 /*
00156  * Pass writes to the physical driver for now.
00157  */
00158 #ifdef __HARVARD_ARCH__
00159 static int NutPppWrite_P(NUTFILE * fp, PGM_P buffer, int len)
00160 {
00161     return _write_P(((PPPDCB *) (fp->nf_dev->dev_dcb))->dcb_fd, buffer, len);
00162 }
00163 #endif
00164 
00184 static int NutPppIOCtl(NUTDEVICE * dev, int req, void *conf)
00185 {
00186     int rc = 0;
00187 
00188     switch (req) {
00189     case LCP_OPEN:
00190         LcpOpen(dev);
00191         break;
00192 
00193     case LCP_CLOSE:
00194         LcpClose(dev);
00195         break;
00196 
00197     case LCP_LOWERUP:
00198         LcpLowerUp(dev);
00199         break;
00200 
00201     case LCP_LOWERDOWN:
00202         LcpLowerDown(dev);
00203         break;
00204 
00205     default:
00206         rc = _ioctl(((PPPDCB *) (dev->dev_dcb))->dcb_fd, req, conf);
00207         break;
00208     }
00209     return rc;
00210 }
00211 
00212 /*
00213  * \brief Enable the link layer to come up.
00214  *
00215  * The underlying hardware driver should have established a physical 
00216  * connection before calling this function.
00217  *
00218  * \param name Physical device name optionally followed by username 
00219  *             and password, each separated by a slash.
00220  *
00221  */
00222 static NUTFILE *NutPppOpen(NUTDEVICE * dev, CONST char *name, int mode, int acc)
00223 {
00224     NUTFILE *fp;
00225     uint8_t i;
00226     char *cp;
00227     char *sp;
00228     char pdn[9];
00229     PPPDCB *dcb = dev->dev_dcb;
00230 
00231     /* Clear our device control block. */
00232     memset(dcb, 0, sizeof(PPPDCB));
00233 
00234     /* Get the first part of the name, it specifies the physical device. */
00235     for (cp = (char *) name, i = 0; *cp && *cp != '/' && i < sizeof(pdn) - 1; i++) {
00236         pdn[i] = *cp++;
00237     }
00238     pdn[i] = 0;
00239 
00240     /* Open the pysical device. */
00241     if ((dcb->dcb_fd = _open(pdn, _O_RDWR | _O_BINARY)) == -1) {
00242         return NUTFILE_EOF;
00243     }
00244 
00245     /*
00246      * Allocate a file structure to return.
00247      */
00248     if ((fp = NutHeapAlloc(sizeof(NUTFILE))) == 0) {
00249         return NUTFILE_EOF;
00250     }
00251     fp->nf_next = 0;
00252     fp->nf_dev = dev;
00253     fp->nf_fcb = 0;
00254 
00255     /*
00256      * Extract user name and password and store it in our device control
00257      * block. It will be used later by the authentication layer.
00258      */
00259     if (*cp == '/') {
00260         for (sp = ++cp, i = 0; *sp && *sp != '/'; sp++, i++);
00261         if (i) {
00262             dcb->dcb_user = NutHeapAlloc(i + 1);
00263             for (sp = (char*)dcb->dcb_user; *cp && *cp != '/';)
00264                 *sp++ = *cp++;
00265             *sp = 0;
00266         }
00267         if (*cp == '/') {
00268             for (sp = ++cp, i = 0; *sp && *sp != '/'; sp++, i++);
00269             if (i) {
00270                 dcb->dcb_pass = NutHeapAlloc(i + 1);
00271                 for (sp = (char*)dcb->dcb_pass; *cp && *cp != '/';)
00272                     *sp++ = *cp++;
00273                 *sp = 0;
00274             }
00275         }
00276     }
00277 
00278     /* Enable all layers to come up. */
00279     IpcpOpen(dev);
00280 
00281     return fp;
00282 }
00283 
00284 
00285 /*
00286  * Start closing connection.
00287  */
00288 static int NutPppClose(NUTFILE * fp)
00289 {
00290     PPPDCB *dcb = fp->nf_dev->dev_dcb;
00291 
00292     IpcpClose(fp->nf_dev);
00293     _close(dcb->dcb_fd);
00294 
00295     if (dcb->dcb_user)
00296         NutHeapFree(dcb->dcb_user);
00297     if (dcb->dcb_pass)
00298         NutHeapFree(dcb->dcb_pass);
00299     NutHeapFree(fp);
00300 
00301     return 0;
00302 }
00303 
00314 static int NutPppInit(NUTDEVICE * dev)
00315 {
00316     return NutPppInitStateMachine(dev);
00317 }
00318 
00322 IFNET ifn_ppp = {
00323     IFT_PPP,                    
00324     {0, 0, 0, 0, 0, 0}
00325     ,                           
00326     0,                          
00327     0,                          
00328     0,                          
00329     PPP_MRU,                    
00330     0,                          
00331     0,                          
00332     0,                          
00333     NutPppInput,                
00334     0,                          
00335     NutPppOutput                
00336 };
00337 
00345 NUTDEVICE devPpp = {
00346     0,                          /* Pointer to next device, dev_next. */
00347     {'p', 'p', 'p', 0, 0, 0, 0, 0, 0}
00348     ,                           /* Unique device name, dev_name. */
00349     IFTYP_NET,                  /* Type of device, dev_type. */
00350     0,                          /* Base address, dev_base. */
00351     0,                          /* First interrupt number, dev_irq. */
00352     &ifn_ppp,                   /* Interface control block, dev_icb. */
00353     &dcb_ppp,                   /* Driver control block, dev_dcb. */
00354     NutPppInit,                 /* Driver initialization routine, dev_init(). */
00355     NutPppIOCtl,                /* Driver specific control function, dev_ioctl(). */
00356     NutPppRead,                 /* Read from device, dev_read. */
00357     NutPppWrite,                /* Write to device, dev_write. */
00358 #ifdef __HARVARD_ARCH__
00359     NutPppWrite_P,              /* Write data from program space to device, dev_write_P. */
00360 #endif
00361     NutPppOpen,                 /* Open a device or file, dev_open. */
00362     NutPppClose,                /* Close a device or file, dev_close. */
00363     0                           /* Request file size. */
00364 };
00365 

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