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