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