ppp.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376
  1. /*
  2. * Copyright (C) 2002 by Call Direct Cellular Solutions Pty. Ltd. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. *
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. * 3. Neither the name of the copyright holders nor the names of
  14. * contributors may be used to endorse or promote products derived
  15. * from this software without specific prior written permission.
  16. *
  17. * THIS SOFTWARE IS PROVIDED BY CALL DIRECT CELLULAR SOLUTIONS AND CONTRIBUTORS
  18. * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  19. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  20. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL CALL DIRECT
  21. * CELLULAR SOLUTIONS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  22. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  23. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  24. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  25. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  26. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
  27. * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  28. * SUCH DAMAGE.
  29. *
  30. * For additional information see http://www.calldirect.com.au/
  31. * -
  32. * Copyright (C) 2001-2004 by egnite Software GmbH. All rights reserved.
  33. *
  34. * Redistribution and use in source and binary forms, with or without
  35. * modification, are permitted provided that the following conditions
  36. * are met:
  37. *
  38. * 1. Redistributions of source code must retain the above copyright
  39. * notice, this list of conditions and the following disclaimer.
  40. * 2. Redistributions in binary form must reproduce the above copyright
  41. * notice, this list of conditions and the following disclaimer in the
  42. * documentation and/or other materials provided with the distribution.
  43. * 3. All advertising materials mentioning features or use of this
  44. * software must display the following acknowledgement:
  45. *
  46. * This product includes software developed by egnite Software GmbH
  47. * and its contributors.
  48. *
  49. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  50. * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  51. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  52. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  53. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  54. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  55. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  56. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  57. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  58. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
  59. * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  60. * SUCH DAMAGE.
  61. *
  62. * For additional information see http://www.ethernut.de/
  63. *
  64. */
  65. /*
  66. * $Log$
  67. * Revision 1.12 2008/08/28 11:12:15 haraldkipp
  68. * Added interface flags, which will be required to implement Ethernet ioctl
  69. * functions.
  70. *
  71. * Revision 1.11 2008/08/11 06:59:42 haraldkipp
  72. * BSD types replaced by stdint types (feature request #1282721).
  73. *
  74. * Revision 1.10 2007/07/17 18:32:27 haraldkipp
  75. * Fixed bug #1369171, memory leak in NutPppClose(). Thanks to Sergey Danilov.
  76. *
  77. * Revision 1.9 2007/05/02 11:22:51 haraldkipp
  78. * Added multicast table entry.
  79. *
  80. * Revision 1.8 2006/03/29 01:23:52 olereinhardt
  81. * Signednes of strings
  82. *
  83. * Revision 1.7 2005/04/30 16:42:41 chaac
  84. * Fixed bug in handling of NUTDEBUG. Added include for cfg/os.h. If NUTDEBUG
  85. * is defined in NutConf, it will make effect where it is used.
  86. *
  87. * Revision 1.6 2004/03/16 16:48:27 haraldkipp
  88. * Added Jan Dubiec's H8/300 port.
  89. *
  90. * Revision 1.5 2004/03/14 10:12:29 haraldkipp
  91. * Bugfix, failed to compile
  92. *
  93. * Revision 1.4 2004/03/08 11:15:32 haraldkipp
  94. * HDLC functions moved to async HDLC driver.
  95. *
  96. * Revision 1.3 2003/08/14 15:21:01 haraldkipp
  97. * Bugfix, allow HDLC flag to mark end _and_ begin
  98. *
  99. * Revision 1.2 2003/08/05 20:05:11 haraldkipp
  100. * DNS removed from interface
  101. *
  102. * Revision 1.1.1.1 2003/05/09 14:40:48 haraldkipp
  103. * Initial using 3.2.1
  104. *
  105. * Revision 1.2 2003/05/06 18:33:50 harald
  106. * PPP hack for simple UART support, functions reordered.
  107. *
  108. * Revision 1.1 2003/03/31 14:53:08 harald
  109. * Prepare release 3.1
  110. *
  111. */
  112. #include <cfg/os.h>
  113. #include <string.h>
  114. #include <io.h>
  115. #include <fcntl.h>
  116. #include <net/if_var.h>
  117. #include <net/ppp.h>
  118. #include <sys/heap.h>
  119. #include <sys/event.h>
  120. #include <sys/timer.h>
  121. #include <sys/thread.h>
  122. #include <dev/ppp.h>
  123. #include <netinet/ppp_fsm.h>
  124. #include <dev/ahdlc.h>
  125. #ifdef NUTDEBUG
  126. #include <net/netdebug.h>
  127. #endif
  128. /*!
  129. * \addtogroup xgPPP
  130. */
  131. /*@{*/
  132. static PPPDCB dcb_ppp;
  133. /*
  134. * Pass reads to the physical driver for now.
  135. */
  136. static int NutPppRead(NUTFILE * fp, void *buffer, int size)
  137. {
  138. return _read(((PPPDCB *) (fp->nf_dev->dev_dcb))->dcb_fd, buffer, size);
  139. }
  140. /*
  141. * Pass writes to the physical driver for now.
  142. */
  143. static int NutPppWrite(NUTFILE * fp, const void *buffer, int len)
  144. {
  145. return _write(((PPPDCB *) (fp->nf_dev->dev_dcb))->dcb_fd, buffer, len);
  146. }
  147. /*
  148. * Pass writes to the physical driver for now.
  149. */
  150. #ifdef __HARVARD_ARCH__
  151. static int NutPppWrite_P(NUTFILE * fp, PGM_P buffer, int len)
  152. {
  153. return _write_P(((PPPDCB *) (fp->nf_dev->dev_dcb))->dcb_fd, buffer, len);
  154. }
  155. #endif
  156. /*!
  157. * \brief Perform PPP control functions.
  158. *
  159. * \param dev Identifies the device that receives the device-control
  160. * function.
  161. * \param req Requested control function. May be set to one of the
  162. * following constants:
  163. * - LCP_OPEN
  164. * - LCP_CLOSE
  165. * - LCP_LOWERUP
  166. * - LCP_LOWERDOWN
  167. * Any other function will be passed to the physical driver.
  168. *
  169. * \param conf Points to a buffer that contains any data required for
  170. * the given control function or receives data from that
  171. * function.
  172. * \return 0 on success, -1 otherwise.
  173. *
  174. */
  175. static int NutPppIOCtl(NUTDEVICE * dev, int req, void *conf)
  176. {
  177. int rc = 0;
  178. switch (req) {
  179. case LCP_OPEN:
  180. LcpOpen(dev);
  181. break;
  182. case LCP_CLOSE:
  183. LcpClose(dev);
  184. break;
  185. case LCP_LOWERUP:
  186. LcpLowerUp(dev);
  187. break;
  188. case LCP_LOWERDOWN:
  189. LcpLowerDown(dev);
  190. break;
  191. default:
  192. rc = _ioctl(((PPPDCB *) (dev->dev_dcb))->dcb_fd, req, conf);
  193. break;
  194. }
  195. return rc;
  196. }
  197. /*
  198. * \brief Enable the link layer to come up.
  199. *
  200. * The underlying hardware driver should have established a physical
  201. * connection before calling this function.
  202. *
  203. * \param name Physical device name optionally followed by username
  204. * and password, each separated by a slash.
  205. *
  206. */
  207. static NUTFILE *NutPppOpen(NUTDEVICE * dev, const char *name, int mode, int acc)
  208. {
  209. NUTFILE *fp;
  210. uint8_t i;
  211. char *cp;
  212. char *sp;
  213. char pdn[9];
  214. PPPDCB *dcb = dev->dev_dcb;
  215. /* Clear our device control block. */
  216. memset(dcb, 0, sizeof(PPPDCB));
  217. /* Get the first part of the name, it specifies the physical device. */
  218. for (cp = (char *) name, i = 0; *cp && *cp != '/' && i < sizeof(pdn) - 1; i++) {
  219. pdn[i] = *cp++;
  220. }
  221. pdn[i] = 0;
  222. /* Open the pysical device. */
  223. if ((dcb->dcb_fd = _open(pdn, _O_RDWR | _O_BINARY)) == -1) {
  224. return NUTFILE_EOF;
  225. }
  226. /*
  227. * Allocate a file structure to return.
  228. */
  229. if ((fp = NutHeapAlloc(sizeof(NUTFILE))) == 0) {
  230. return NUTFILE_EOF;
  231. }
  232. fp->nf_dev = dev;
  233. fp->nf_fcb = NULL;
  234. /*
  235. * Extract user name and password and store it in our device control
  236. * block. It will be used later by the authentication layer.
  237. */
  238. if (*cp == '/') {
  239. for (sp = ++cp, i = 0; *sp && *sp != '/'; sp++, i++);
  240. if (i) {
  241. dcb->dcb_user = NutHeapAlloc(i + 1);
  242. for (sp = (char*)dcb->dcb_user; *cp && *cp != '/';)
  243. *sp++ = *cp++;
  244. *sp = 0;
  245. }
  246. if (*cp == '/') {
  247. for (sp = ++cp, i = 0; *sp && *sp != '/'; sp++, i++);
  248. if (i) {
  249. dcb->dcb_pass = NutHeapAlloc(i + 1);
  250. for (sp = (char*)dcb->dcb_pass; *cp && *cp != '/';)
  251. *sp++ = *cp++;
  252. *sp = 0;
  253. }
  254. }
  255. }
  256. /* Enable all layers to come up. */
  257. IpcpOpen(dev);
  258. return fp;
  259. }
  260. /*
  261. * Start closing connection.
  262. */
  263. static int NutPppClose(NUTFILE * fp)
  264. {
  265. PPPDCB *dcb = fp->nf_dev->dev_dcb;
  266. IpcpClose(fp->nf_dev);
  267. _close(dcb->dcb_fd);
  268. if (dcb->dcb_user)
  269. NutHeapFree(dcb->dcb_user);
  270. if (dcb->dcb_pass)
  271. NutHeapFree(dcb->dcb_pass);
  272. NutHeapFree(fp);
  273. return 0;
  274. }
  275. /*!
  276. * \brief Initialize the PPP device.
  277. *
  278. * This routine is called during device registration and initializes the
  279. * PPP state machine.
  280. *
  281. * \param dev Identifies the device to initialize.
  282. *
  283. * \return 0 on success, -1 otherwise.
  284. */
  285. static int NutPppInit(NUTDEVICE * dev)
  286. {
  287. return NutPppInitStateMachine(dev);
  288. }
  289. /*!
  290. * \brief Network interface information structure.
  291. */
  292. IFNET ifn_ppp = {
  293. IFT_PPP, /*!< \brief Interface type. */
  294. 0, /*!< \brief Interface flags, if_flags. */
  295. {0, 0, 0, 0, 0, 0}
  296. , /*!< \brief Hardware net address. */
  297. 0, /*!< \brief IP address. */
  298. 0, /*!< \brief Remote IP address for point to point. */
  299. 0, /*!< \brief IP network mask. */
  300. PPP_MRU, /*!< \brief Maximum size of a transmission unit. */
  301. 0, /*!< \brief Packet identifier. */
  302. 0, /*!< \brief Linked list of arp entries. */
  303. 0, /*!< \brief Linked list of multicast address entries, if_mcast. */
  304. NutPppInput, /*!< \brief Routine to pass received data to, if_recv(). */
  305. 0, /*!< \brief Dynamically attached driver output routine, if_send(). */
  306. NutPppOutput, /*!< \brief Media output routine, if_output(). */
  307. NULL /*!< \brief Interface specific control function, if_ioctl(). */
  308. #ifdef NUT_PERFMON
  309. , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  310. #endif
  311. };
  312. /*!
  313. * \brief Device information structure.
  314. *
  315. * This is a virtual device driver has no underlying hardware
  316. * and must not be registered. It will be initialized when the
  317. * application calls NutNetIfConfig().
  318. */
  319. NUTDEVICE devPpp = {
  320. 0, /* Pointer to next device, dev_next. */
  321. {'p', 'p', 'p', 0, 0, 0, 0, 0, 0}
  322. , /* Unique device name, dev_name. */
  323. IFTYP_NET, /* Type of device, dev_type. */
  324. 0, /* Base address, dev_base. */
  325. 0, /* First interrupt number, dev_irq. */
  326. &ifn_ppp, /* Interface control block, dev_icb. */
  327. &dcb_ppp, /* Driver control block, dev_dcb. */
  328. NutPppInit, /* Driver initialization routine, dev_init(). */
  329. NutPppIOCtl, /* Driver specific control function, dev_ioctl(). */
  330. NutPppRead, /* Read from device, dev_read. */
  331. NutPppWrite, /* Write to device, dev_write. */
  332. #ifdef __HARVARD_ARCH__
  333. NutPppWrite_P, /* Write data from program space to device, dev_write_P. */
  334. #endif
  335. NutPppOpen, /* Open a device or file, dev_open. */
  336. NutPppClose, /* Close a device or file, dev_close. */
  337. NULL, /* Request file size. */
  338. NULL, /* Select function, optional, not yet implemented */
  339. };
  340. /*@}*/