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