From e5a4835f5ea1ca74b0ccdc2c44d3e1657c6d3f05 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Wed, 11 Mar 2015 07:53:04 -0600 Subject: [PATCH] Add a PPP daemon. From Max Neklyudov --- netutils/Kconfig | 1 + netutils/Make.defs | 4 + netutils/pppd/.gitignore | 6 + netutils/pppd/Kconfig | 23 ++ netutils/pppd/Makefile | 111 ++++++++ netutils/pppd/ahdlc.c | 451 ++++++++++++++++++++++++++++++ netutils/pppd/ahdlc.h | 84 ++++++ netutils/pppd/chat.c | 136 +++++++++ netutils/pppd/chat.h | 46 +++ netutils/pppd/ipcp.c | 513 ++++++++++++++++++++++++++++++++++ netutils/pppd/ipcp.h | 117 ++++++++ netutils/pppd/lcp.c | 589 +++++++++++++++++++++++++++++++++++++++ netutils/pppd/lcp.h | 133 +++++++++ netutils/pppd/ntpv3.h | 207 ++++++++++++++ netutils/pppd/pap.c | 188 +++++++++++++ netutils/pppd/pap.h | 113 ++++++++ netutils/pppd/ppp.c | 456 ++++++++++++++++++++++++++++++ netutils/pppd/ppp.h | 233 ++++++++++++++++ netutils/pppd/ppp_arch.h | 59 ++++ netutils/pppd/ppp_conf.h | 36 +++ netutils/pppd/pppd.c | 435 +++++++++++++++++++++++++++++ 21 files changed, 3941 insertions(+) create mode 100644 netutils/pppd/.gitignore create mode 100644 netutils/pppd/Kconfig create mode 100644 netutils/pppd/Makefile create mode 100644 netutils/pppd/ahdlc.c create mode 100644 netutils/pppd/ahdlc.h create mode 100644 netutils/pppd/chat.c create mode 100644 netutils/pppd/chat.h create mode 100644 netutils/pppd/ipcp.c create mode 100644 netutils/pppd/ipcp.h create mode 100644 netutils/pppd/lcp.c create mode 100644 netutils/pppd/lcp.h create mode 100644 netutils/pppd/ntpv3.h create mode 100644 netutils/pppd/pap.c create mode 100644 netutils/pppd/pap.h create mode 100644 netutils/pppd/ppp.c create mode 100644 netutils/pppd/ppp.h create mode 100644 netutils/pppd/ppp_arch.h create mode 100644 netutils/pppd/ppp_conf.h create mode 100644 netutils/pppd/pppd.c diff --git a/netutils/Kconfig b/netutils/Kconfig index 33702e5a2..114fe044d 100644 --- a/netutils/Kconfig +++ b/netutils/Kconfig @@ -22,3 +22,4 @@ source "$APPSDIR/netutils/webserver/Kconfig" source "$APPSDIR/netutils/ntpclient/Kconfig" source "$APPSDIR/netutils/discover/Kconfig" source "$APPSDIR/netutils/xmlrpc/Kconfig" +source "$APPSDIR/netutils/pppd/Kconfig" diff --git a/netutils/Make.defs b/netutils/Make.defs index 41ed1dff9..07998a91c 100644 --- a/netutils/Make.defs +++ b/netutils/Make.defs @@ -62,6 +62,10 @@ ifeq ($(CONFIG_NETUTILS_NTPCLIENT),y) CONFIGURED_APPS += netutils/ntpclient endif +ifeq ($(CONFIG_NETUTILS_PPPD),y) +CONFIGURED_APPS += netutils/pppd +endif + ifeq ($(CONFIG_NETUTILS_DNSCLIENT),y) CONFIGURED_APPS += netutils/dnsclient endif diff --git a/netutils/pppd/.gitignore b/netutils/pppd/.gitignore new file mode 100644 index 000000000..f21c854d1 --- /dev/null +++ b/netutils/pppd/.gitignore @@ -0,0 +1,6 @@ +/.built +/.depend +/Make.dep +/*.src +/*.obj +/*.lst diff --git a/netutils/pppd/Kconfig b/netutils/pppd/Kconfig new file mode 100644 index 000000000..3d5f92644 --- /dev/null +++ b/netutils/pppd/Kconfig @@ -0,0 +1,23 @@ +# +# For a description of the syntax of this configuration file, +# see misc/tools/kconfig-language.txt. +# + +config NETUTILS_PPPD + bool "PPP daemon" + default n + select NET_TUN + ---help--- + Enable support for the PPP daemon. + +if NETUTILS_PPPD + +config NETUTILS_PPPD_STACKSIZE + int "PPP daemon stack stack size" + default 2048 + +config NETUTILS_PPPD_SERVERPRIO + int "NTP daemon priority" + default 100 + +endif # NETUTILS_PPPD diff --git a/netutils/pppd/Makefile b/netutils/pppd/Makefile new file mode 100644 index 000000000..3dafdcc40 --- /dev/null +++ b/netutils/pppd/Makefile @@ -0,0 +1,111 @@ +############################################################################ +# apps/netutils/pppd/Makefile +# +# Copyright (C) 2015 Max Nekludov. All rights reserved. +# Author: Max Nekludov +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +-include $(TOPDIR)/.config +-include $(TOPDIR)/Make.defs +include $(APPDIR)/Make.defs + +APPNAME = pppd +PRIORITY = SCHED_PRIORITY_DEFAULT +STACKSIZE = $(CONFIG_NETUTILS_PPPD_STACKSIZE) + +ASRCS = +CSRCS = + +CSRCS += pppd.c chat.c ppp.c ahdlc.c lcp.c pap.c ipcp.c + +AOBJS = $(ASRCS:.S=$(OBJEXT)) +COBJS = $(CSRCS:.c=$(OBJEXT)) + +SRCS = $(ASRCS) $(CSRCS) +OBJS = $(AOBJS) $(COBJS) + +ifeq ($(CONFIG_WINDOWS_NATIVE),y) + BIN = ..\..\libapps$(LIBEXT) +else +ifeq ($(WINTOOL),y) + BIN = ..\\..\\libapps$(LIBEXT) +else + BIN = ../../libapps$(LIBEXT) +endif +endif + +ROOTDEPPATH = --dep-path . + +# Common build + +VPATH = + +all: .built +.PHONY: context depend clean distclean + +$(AOBJS): %$(OBJEXT): %.S + $(call ASSEMBLE, $<, $@) + +$(COBJS): %$(OBJEXT): %.c + $(call COMPILE, $<, $@) + +.built: $(OBJS) + $(call ARCHIVE, $(BIN), $(OBJS)) + $(Q) touch .built + +install: + +# Register application + +ifeq ($(CONFIG_NSH_BUILTIN_APPS),y) +$(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat: $(DEPCONFIG) Makefile + $(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main) + +context: $(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat +else +context: +endif + +.depend: Makefile $(SRCS) + $(Q) $(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep + $(Q) touch $@ + +depend: .depend + +clean: + $(call DELFILE, .built) + $(call CLEAN) + +distclean: clean + $(call DELFILE, Make.dep) + $(call DELFILE, .depend) + +-include Make.dep diff --git a/netutils/pppd/ahdlc.c b/netutils/pppd/ahdlc.c new file mode 100644 index 000000000..43c911893 --- /dev/null +++ b/netutils/pppd/ahdlc.c @@ -0,0 +1,451 @@ +/* www.mycal.com + *--------------------------------------------------------------------------- + * ahdlc.c - Ahdlc receive and transmit processor for PPP engine. + * + *--------------------------------------------------------------------------- + * Version + * 0.1 Original Version Jan 11, 1998 + * + *--------------------------------------------------------------------------- + * + * Copyright (C) 1998, Mycal Labs www.mycal.com + * + *--------------------------------------------------------------------------- + */ +/* + * Copyright (c) 2003, Mike Johnson, Mycal Labs, www.mycal.net + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Mike Johnson/Mycal Labs + * www.mycal.net. + * 4. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the Mycal Modified uIP TCP/IP stack. + * + * $Id: ahdlc.c,v 1.1 2007/05/26 07:14:39 oliverschmidt Exp $ + * + */ + +/* */ +/* include files */ +/* */ + +#include "ppp_conf.h" +#include "ppp.h" + +#if PPP_DEBUG +# define DEBUG1(x) debug_printf x +# define PACKET_TX_DEBUG 1 +#else +# define DEBUG1(x) +# undef PACKET_TX_DEBUG +#endif + +/*--------------------------------------------------------------------------- + * ahdlc flags bit defins, for ahdlc_flags variable + ---------------------------------------------------------------------------*/ + +/* Escaped mode bit */ + +#define AHDLC_ESCAPED 0x1 + +/* Frame is ready bit */ + +#define AHDLC_RX_READY 0x2 +#define AHDLC_RX_ASYNC_MAP 0x4 +#define AHDLC_TX_ASYNC_MAP 0x8 +#define AHDLC_PFC 0x10 +#define AHDLC_ACFC 0x20 + +/*---------------------------------------------------------------------------*/ +/* Simple and fast CRC16 routine for embedded processors. + * Just slightly slower than the table lookup method but consumes + * almost no space. Much faster and smaller than the loop and + * shift method that is widely used in the embedded space. + * Can be optimized even more in .ASM + * + * data = (crcvalue ^ inputchar) & 0xff; + * data = (data ^ (data << 4)) & 0xff; + * crc = (crc >> 8) ^ ((data << 8) ^ (data <<3) ^ (data >> 4)) + */ +/*---------------------------------------------------------------------------*/ + +static u16_t crcadd(u16_t crcvalue, u8_t c) +{ + u16_t b; + + b = (crcvalue ^ c) & 0xFF; + b = (b ^ (b << 4)) & 0xFF; + b = (b << 8) ^ (b << 3) ^ (b >> 4); + + return ((crcvalue >> 8) ^ b); +} + +/*---------------------------------------------------------------------------*/ +/* ahdlc_init(buffer, buffersize) - this initializes the ahdlc engine to + * allow for rx frames. + */ +/*---------------------------------------------------------------------------*/ + +void ahdlc_init(struct ppp_context_s *ctx) +{ + ctx->ahdlc_flags = 0 | AHDLC_RX_ASYNC_MAP; + ctx->ahdlc_rx_count = 0; + ctx->ahdlc_tx_offline = 0; + +#ifdef PPP_STATISTICS + ctx->ahdlc_rx_tobig_error = 0; +#endif +} + +/*---------------------------------------------------------------------------*/ +/* ahdlc_rx_ready() - resets the ahdlc engine to the beginning of frame + * state. + */ +/*---------------------------------------------------------------------------*/ + +void ahdlc_rx_ready(struct ppp_context_s *ctx) +{ + ctx->ahdlc_rx_count = 0; + ctx->ahdlc_rx_crc = 0xffff; + ctx->ahdlc_flags |= AHDLC_RX_READY; +} + +/*---------------------------------------------------------------------------*/ +/* ahdlc receive function - This routine processes incoming bytes and tries + * to build a PPP frame. + * + * Two possible reasons that ahdlc_rx will not process characters: + * o Buffer is locked - in this case ahdlc_rx returns 1, char + * sending routing should retry. + */ +/*---------------------------------------------------------------------------*/ + +u8_t ahdlc_rx(struct ppp_context_s *ctx, u8_t c) +{ + //static u16_t protocol; + + /* Check to see if PPP packet is useable, we should have hardware + flow control set, but if host ignores it and sends us a char when + the PPP Receive packet is in use, discard the character. */ + + if (ctx->ahdlc_flags & AHDLC_RX_READY) + { + /* Check to see if character is less than 0x20 hex we really + should set AHDLC_RX_ASYNC_MAP on by default and only turn it + off when it is negotiated off to handle some buggy stacks. */ + + if ((c < 0x20) && ((ctx->ahdlc_flags & AHDLC_RX_ASYNC_MAP) == 0)) + { + /* Discard character */ + + DEBUG1(("Discard because char is < 0x20 hex and asysnc map is 0\n")); + return 0; + } + + /* Are we in escaped mode? */ + + if (ctx->ahdlc_flags & AHDLC_ESCAPED) + { + /* Set escaped to FALSE */ + + ctx->ahdlc_flags &= ~AHDLC_ESCAPED; + + /* If value is 0x7e then silently discard and reset receive packet */ + + if (c == 0x7e) + { + ahdlc_rx_ready(ctx); + return 0; + } + + /* Incoming char = itself xor 20 */ + + c = c ^ 0x20; + } + else if (c == 0x7e) + { + /* Handle frame end */ + + if (ctx->ahdlc_rx_crc == CRC_GOOD_VALUE) + { + DEBUG1(("\nReceiving packet with good crc value, len %d\n", + ctx->ahdlc_rx_count)); + + /* we hae a good packet, turn off CTS until we are done with + this packet */ + /*CTS_OFF();*/ + +#if PPP_STATISTICS + /* Update statistics */ + + ++ctx->ppp_rx_frame_count; +#endif + + /* Femove CRC bytes from packet */ + + ctx->ahdlc_rx_count -= 2; + + /* Lock PPP buffer */ + + ctx->ahdlc_flags &= ~AHDLC_RX_READY; + + /*upcall routine must fully process frame before return + * as returning signifies that buffer belongs to AHDLC again. + */ + + if ((c & 0x1) && (ctx->ahdlc_flags & PPP_PFC)) + { + /* Send up packet */ + + ppp_upcall(ctx, (u16_t)ctx->ahdlc_rx_buffer[0], + (u8_t *)&ctx->ahdlc_rx_buffer[1], + (u16_t)(ctx->ahdlc_rx_count - 1)); + } + else + { + /* Send up packet */ + + ppp_upcall(ctx, (u16_t)(ctx->ahdlc_rx_buffer[0] << 8 | ctx->ahdlc_rx_buffer[1]), + (u8_t *)&ctx->ahdlc_rx_buffer[2], (u16_t)(ctx->ahdlc_rx_count - 2)); + } + + ctx->ahdlc_tx_offline = 0; /* The remote side is alive */ + ahdlc_rx_ready(ctx); + return 0; + } + else if (ctx->ahdlc_rx_count > 3) + { + DEBUG1(("\nReceiving packet with bad crc value, was 0x%04x len %d\n", + ctx->ahdlc_rx_crc, ctx->ahdlc_rx_count)); +#ifdef PPP_STATISTICS + ++ctx->ahdlc_crc_error; +#endif + /* Shouldn't we dump the packet and not pass it up? */ + + /*ppp_upcall((u16_t)ahdlc_rx_buffer[0], + (u8_t *)&ahdlc_rx_buffer[0], (u16_t)(ahdlc_rx_count+2)); + dump_ppp_packet(&ahdlc_rx_buffer[0],ahdlc_rx_count);*/ + } + + ahdlc_rx_ready(ctx); + return 0; + } + else if (c == 0x7d) + { + /* Handle escaped chars*/ + + ctx->ahdlc_flags |= PPP_ESCAPED; + return 0; + } + + /* Rry to store char if not too big */ + + if (ctx->ahdlc_rx_count >= PPP_RX_BUFFER_SIZE) + { +#ifdef PPP_STATISTICS + ++ctx->ahdlc_rx_tobig_error; +#endif + ahdlc_rx_ready(ctx); + } + else + { + /* Add CRC in */ + + ctx->ahdlc_rx_crc = crcadd(ctx->ahdlc_rx_crc, c); + + /* Do auto ACFC, if packet len is zero discard 0xff and 0x03 */ + + if (ctx->ahdlc_rx_count == 0) + { + if ((c == 0xff) || (c == 0x03)) + { + return 0; + } + } + + /* Store char */ + + ctx->ahdlc_rx_buffer[ctx->ahdlc_rx_count++] = c; + } + } + else + { + /* we are busy and didn't process the character. */ + DEBUG1(("Busy/not active\n")); + return 1; + } + + return 0; +} + +/*---------------------------------------------------------------------------*/ +/* ahdlc_tx_char(char) - write a character to the serial device, + * escape if necessary. + * + * Relies on local global vars : ahdlc_tx_crc, ahdlc_flags. + * Modifies local global vars : ahdlc_tx_crc. + */ +/*---------------------------------------------------------------------------*/ + +void ahdlc_tx_char(struct ppp_context_s *ctx, u16_t protocol, u8_t c) +{ + /* Add in crc */ + + ctx->ahdlc_tx_crc = crcadd(ctx->ahdlc_tx_crc, c); + + /* See if we need to escape char, we always escape 0x7d and 0x7e, in the case + * of char < 0x20 we only support async map of default or none, so escape if + * ASYNC map is not set. We may want to modify this to support a bitmap set + * ASYNC map. + */ + + if ((c == 0x7d) || (c == 0x7e) || ((c < 0x20) && ((protocol == LCP) || + (ctx->ahdlc_flags & PPP_TX_ASYNC_MAP) == 0))) + { + /* Send escape char and xor byte by 0x20 */ + + ppp_arch_putchar(ctx, 0x7d); + c ^= 0x20; + } + + ppp_arch_putchar(ctx, c); +} + +/*---------------------------------------------------------------------------*/ +/* ahdlc_tx(protocol,buffer,len) - Transmit a PPP frame. + * Buffer contains protocol data, ahdlc_tx addes address, control and + * protocol data. + * + * Relies on local global vars : ahdlc_tx_crc, ahdlc_flags. + * Modifies local global vars : ahdlc_tx_crc. + */ +/*---------------------------------------------------------------------------*/ + +u8_t ahdlc_tx(struct ppp_context_s *ctx, u16_t protocol, u8_t *header, + u8_t *buffer, u16_t headerlen, u16_t datalen) +{ + u16_t i; + u8_t c; + + DEBUG1(("\nAHDLC_TX - transmit frame, protocol 0x%04x, length %d offline %d\n", + protocol, datalen + headerlen, ctx->ahdlc_tx_offline)); + + if (AHDLC_TX_OFFLINE && (ctx->ahdlc_tx_offline++ > AHDLC_TX_OFFLINE)) + { + ctx->ahdlc_tx_offline = 0; + DEBUG1(("\nAHDLC_TX to many outstanding TX packets => ppp_reconnect()\n")); + ppp_reconnect(ctx); + return 0; + } + +#if PACKET_TX_DEBUG + DEBUG1(("\n")); + for(i = 0; i < headerlen; ++i) + { + DEBUG1(("0x%02x ", header[i])); + } + + for(i = 0; i < datalen; ++i) + { + DEBUG1(("0x%02x ", buffer[i])); + } + + DEBUG1(("\n\n")); +#endif + + /* Check to see that physical layer is up, we can assume is some + cases */ + + /* Write leading 0x7e */ + + ppp_arch_putchar(ctx, 0x7e); + + /* Set initial CRC value */ + + ctx->ahdlc_tx_crc = 0xffff; + + /* send HDLC control and address if not disabled or of LCP frame type */ + + /*if ((0==(ahdlc_flags & PPP_ACFC)) || ((0xc0==buffer[0]) && (0x21==buffer[1]))) */ + if ((0 == (ctx->ahdlc_flags & PPP_ACFC)) || (protocol == LCP)) + { + ahdlc_tx_char(ctx, protocol, 0xff); + ahdlc_tx_char(ctx, protocol, 0x03); + } + + /* Write Protocol */ + + ahdlc_tx_char(ctx, protocol,(u8_t)(protocol >> 8)); + ahdlc_tx_char(ctx, protocol,(u8_t)(protocol & 0xff)); + + /* Write header if it exists */ + + for(i = 0; i < headerlen; ++i) + { + /* Get next byte from buffer */ + + c = header[i]; + + /* Write it...*/ + + ahdlc_tx_char(ctx, protocol, c); + } + + /* Write frame bytes */ + + for(i = 0; i < datalen; ++i) + { + /* Get next byte from buffer */ + + c = buffer[i]; + + /* Write it...*/ + + ahdlc_tx_char(ctx, protocol, c); + } + + /* Send crc, lsb then msb */ + + i = ctx->ahdlc_tx_crc ^ 0xffff; + ahdlc_tx_char(ctx, protocol, (u8_t)(i & 0xff)); + ahdlc_tx_char(ctx, protocol, (u8_t)((i >> 8) & 0xff)); + + /* Write trailing 0x7e, probably not needed but it doesn't hurt */ + + ppp_arch_putchar(ctx, 0x7e); + +#if PPP_STATISTICS + /* Update statistics */ + + ++ctx->ppp_tx_frame_count; +#endif +O + return 0; +} + +/*---------------------------------------------------------------------------*/ diff --git a/netutils/pppd/ahdlc.h b/netutils/pppd/ahdlc.h new file mode 100644 index 000000000..84fbc442c --- /dev/null +++ b/netutils/pppd/ahdlc.h @@ -0,0 +1,84 @@ +/*--------------------------------------------------------------------------- + ahdlc.h - ahdlc header file +--------------------------------------------------------------------------- + Version + 0.1 Original Version Jan 11, 1998 + (c)1998 Mycal Labs, All Rights Reserved + ---------------------------------------------------------------------------*/ +/* + * Copyright (c) 2003, Mike Johnson, Mycal Labs, www.mycal.net + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Mike Johnson/Mycal Labs + * www.mycal.net. + * 4. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the Mycal Modified uIP TCP/IP stack. + * + * $Id: ahdlc.h,v 1.1 2007/05/26 07:14:39 oliverschmidt Exp $ + * + */ + +#ifndef __APPS_NETUTILS_PPPD_AHDLC_H +#define __APPS_NETUTILS_PPPD_AHDLC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "ppp_conf.h" +#include "ppp_arch.h" + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +struct ppp_context_s; + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +void ahdlc_init(struct ppp_context_s *ctx); + +void ahdlc_rx_ready(struct ppp_context_s *ctx); + +u8_t ahdlc_rx(struct ppp_context_s *ctx, u8_t); +u8_t ahdlc_tx(struct ppp_context_s *ctx, u16_t protocol, u8_t *header, + u8_t *buffer, u16_t headerlen, u16_t datalen); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __APPS_NETUTILS_PPPD_AHDLC_H */ diff --git a/netutils/pppd/chat.c b/netutils/pppd/chat.c new file mode 100644 index 000000000..9042437dc --- /dev/null +++ b/netutils/pppd/chat.c @@ -0,0 +1,136 @@ +#include "ppp_conf.h" +#include "ppp_arch.h" +#include "chat.h" + +#include + +#define CHAT_MAX_SKIP 8 +#define CHAT_ECHO_TIMEOUT 500 + +static int chat_read_byte(int fd, char* c, int timeout) +{ + int ret; + struct pollfd fds; + + fds.fd = fd; + fds.events = POLLIN; + fds.revents = 0; + + ret = poll(&fds, 1, timeout); + if (ret <= 0) + { + return -1; + } + + ret = read(fd, c, 1); + if (ret != 1) + { + return -1; + } + + printf("chat: char = %c (0x%02X)\n", *c, *c); + + return 0; +} + +static void chat_flush(int fd) +{ + char tmp; + while (chat_read_byte(fd, &tmp, 0) == 0); +} + +static int chat_check_response(int fd, const char* response, int timeout) +{ + char c; + int ret; + int skip = CHAT_MAX_SKIP; + + while (*response) + { + ret = chat_read_byte(fd, &c, timeout); + if (ret < 0) + { + return ret; + } + + if (skip > 0 && (c == '\r' || c == '\n')) + { + --skip; + continue; + } + + if (c == *response) + { + ++response; + } + else + { + return -1; + } + } + + return 0; +} + +int ppp_chat(int fd, struct chat_script_s *script, int echo) +{ + int ret; + size_t len; + struct chat_line_s *line = script->lines; + const char* request = line->request; + const char* response = line->response; + + while (request) + { + chat_flush(fd); + + printf("chat: send '%s`\n", request); + len = strlen(request); + ret = write(fd, request, len); + if (ret < 0) + { + return ret; + } + else if ((size_t)ret != len) + { + return -1; + } + + ret = write(fd, "\r\n", 2); + if (ret != 2) + { + return -1; + } + + /* Check echo if enabled */ + + if (echo) + { + ret = chat_check_response(fd, request, CHAT_ECHO_TIMEOUT); + if (ret < 0) + { + printf("chat: invalid echo\n"); + return ret; + } + } + + if (response) + { + printf("chat: wait for '%s`\n", response); + ret = chat_check_response(fd, response, script->timeout * 1000); + if (ret < 0) + { + printf("chat: bad response\n"); + return ret; + } + + printf("chat: got it!\n"); + } + + ++line; + request = line->request; + response = line->response; + } + + return 0; +} \ No newline at end of file diff --git a/netutils/pppd/chat.h b/netutils/pppd/chat.h new file mode 100644 index 000000000..7d1cb8df8 --- /dev/null +++ b/netutils/pppd/chat.h @@ -0,0 +1,46 @@ +#ifndef __APPS_NETUTILS_PPPD_CHAT_H +#define __APPS_NETUTILS_PPPD_CHAT_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +struct chat_line_s +{ + const char *request; + const char *response; +}; + +struct chat_script_s +{ + time_t timeout; + struct chat_line_s lines[]; +}; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +int ppp_chat(int fd, struct chat_script_s *script, int echo); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __APPS_NETUTILS_PPPD_CHAT_H */ \ No newline at end of file diff --git a/netutils/pppd/ipcp.c b/netutils/pppd/ipcp.c new file mode 100644 index 000000000..b1aa6a691 --- /dev/null +++ b/netutils/pppd/ipcp.c @@ -0,0 +1,513 @@ +/* + *--------------------------------------------------------------------------- + * ipcp.c - PPP IPCP (intrnet protocol) Processor/Handler + * + *--------------------------------------------------------------------------- + * + * Version + * 0.1 Original Version Jun 3, 2000 + * + *--------------------------------------------------------------------------- + * + * Copyright (C) 2000, Mycal Labs www.mycal.com + * + *--------------------------------------------------------------------------- + */ +/* + * Copyright (c) 2003, Mike Johnson, Mycal Labs, www.mycal.net + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Mike Johnson/Mycal Labs + * www.mycal.net. + * 4. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the Mycal Modified uIP TCP/IP stack. + * + * $Id: ipcp.c,v 1.2 2010/10/19 18:29:03 adamdunkels Exp $ + * + */ + +/* */ +/* include files */ +/* */ + +#include "ppp_conf.h" +#include "ppp_arch.h" +#include "ipcp.h" +#include "ppp.h" +#include "ahdlc.h" + +#if PPP_DEBUG +# define DEBUG1(x) debug_printf x +#else +# define DEBUG1(x) +#endif + +/* In the future add compression protocol and name servers (possibly for servers + * only) + */ + +static const u8_t ipcplist[] = +{ + 0x3, + 0 +}; + +/*---------------------------------------------------------------------------*/ + +#if 0 +void +printip(uip_ipaddr_t ip2) +{ + char *ip = (u8_t*)ip2; + DEBUG1((" %d.%d.%d.%d ",ip[0],ip[1],ip[2],ip[3])); +} +#else +# define printip(x) +#endif + +/*---------------------------------------------------------------------------*/ + +void ipcp_init(struct ppp_context_s *ctx) +{ + DEBUG1(("ipcp init\n")); + + ctx->ipcp_state = 0; + ctx->ipcp_retry = 0; + ctx->ipcp_prev_seconds = 0; + + memset(&ctx->local_ip, 0, sizeof(struct in_addr)); +#ifdef IPCP_GET_PEER_IP + memset(&ctx->peer_ip, 0, sizeof(struct in_addr)); +#endif +#ifdef IPCP_GET_PRI_DNS + memset(&ctx->pri_dns_addr, 0, sizeof(struct in_addr)); +#endif +#ifdef IPCP_GET_SEC_DNS + memset(&ctx->sec_dns_addr, 0, sizeof(struct in_addr)); +#endif +} + +/*---------------------------------------------------------------------------*/ +/* IPCP RX protocol Handler */ + +void ipcp_rx(struct ppp_context_s *ctx, u8_t *buffer, u16_t count) +{ + u8_t *bptr = buffer; + //IPCPPKT *pkt=(IPCPPKT *)buffer; + u16_t len; + + DEBUG1(("IPCP len %d\n",count)); + + switch (*bptr++) + { + case CONF_REQ: + /* Parse request and see if we can ACK it */ + + ++bptr; + len = (*bptr++ << 8); + len |= *bptr++; + /* len-=2; */ + + DEBUG1(("check lcplist\n")); + if (scan_packet(ctx, IPCP, ipcplist, buffer, bptr, (u16_t)(len - 4))) + { + DEBUG1(("option was bad\n")); + } + else + { + DEBUG1(("IPCP options are good\n")); + + /* Parse out the results */ + /* lets try to implement what peer wants */ + /* Reject any protocol not */ + /* Error? if we we need to send a config Reject ++++ this is good for a subroutine*/ + /* All we should get is the peer IP address */ + + if (IPCP_IPADDRESS == *bptr++) + { + /* Dump length */ + + ++bptr; +#ifdef IPCP_GET_PEER_IP + ((u8_t*)&ctx->peer_ip)[0] = *bptr++; + ((u8_t*)&ctx->peer_ip)[1] = *bptr++; + ((u8_t*)&ctx->peer_ip)[2] = *bptr++; + ((u8_t*)&ctx->peer_ip)[3] = *bptr++; + + DEBUG1(("Peer IP ")); + /* printip(peer_ip_addr); */ + DEBUG1(("\n")); + + netlib_set_dripv4addr((char*)ctx->ifname, &ctx->peer_ip); +#else + bptr += 4; +#endif + } + else + { + DEBUG1(("HMMMM this shouldn't happen IPCP1\n")); + } + +#if 0 + if (error) + { + /* Write the config NAK packet we've built above, take on the header */ + + bptr = buffer; + *bptr++ = CONF_NAK; /* Write Conf_rej */ + *bptr++; + /*tptr++;*/ /* skip over ID */ + + /* Write new length */ + + *bptr++ = 0; + *bptr = tptr - buffer; + + /* Write the reject frame */ + + DEBUG1(("Writing NAK frame \n")); + ahdlc_tx(IPCP, buffer, (u16_t)(tptr - buffer)); + DEBUG1(("- End NAK Write frame\n")); + } + else + { + } +#endif + /* If we get here then we are OK, lets send an ACK and tell the rest + * of our modules our negotiated config. + */ + + ctx->ipcp_state |= IPCP_RX_UP; + DEBUG1(("Send IPCP ACK!\n")); + bptr = buffer; + *bptr++ = CONF_ACK; /* Write Conf_ACK */ + bptr++; /* Skip ID (send same one) */ + + /* Set stuff */ + + /* ppp_flags |= tflag; */ + DEBUG1(("SET- stuff -- are we up? c=%d dif=%d \n", count, (u16_t)(bptr - buffer))); + + /* Write the ACK frame */ + + DEBUG1(("Writing ACK frame \n")); + + /* Send packet ahdlc_txz(procol,header,data,headerlen,datalen); */ + + ahdlc_tx(ctx, IPCP, 0, buffer, 0, count /*bptr-buffer*/); + DEBUG1(("- End ACK Write frame\n")); + } + break; + + case CONF_ACK: /* config Ack */ + DEBUG1(("CONF ACK\n")); + /* Parse out the results + * + * Dump the ID and get the length. + */ + + /* Dump the ID */ + + bptr++; + + /* Get the length */ + + len = (*bptr++ << 8); + len |= *bptr++; + +#if 0 + /* Parse ACK and set data */ + + while (bptr < buffer + len) + { + switch (*bptr++) + { + case IPCP_IPADDRESS: + /* Dump length */ + + bptr++; + ((u8_t*)ipaddr)[0] = *bptr++; + ((u8_t*)ipaddr)[1] = *bptr++; + ((u8_t*)ipaddr)[2] = *bptr++; + ((u8_t*)ipaddr)[3] = *bptr++; + break; + + case IPCP_PRIMARY_DNS: + bptr++; + ((u8_t*)pri_dns_addr)[0] = *bptr++; + ((u8_t*)pri_dns_addr)[1] = *bptr++; + ((u8_t*)pri_dns_addr)[2] = *bptr++; + ((u8_t*)pri_dns_addr)[3] = *bptr++; + break; + + case IPCP_SECONDARY_DNS: + bptr++; + ((u8_t*)sec_dns_addr)[0] = *bptr++; + ((u8_t*)sec_dns_addr)[1] = *bptr++; + ((u8_t*)sec_dns_addr)[2] = *bptr++; + ((u8_t*)sec_dns_addr)[3] = *bptr++; + break; + + default: + DEBUG1(("IPCP CONFIG_ACK problem1\n")); + } + } +#endif + + ctx->ipcp_state |= IPCP_TX_UP; + /*ppp_ipcp_state &= ~IPCP_RX_UP;*/ + + DEBUG1(("were up! \n")); + //printip(pppif.ipaddr); +#ifdef IPCP_GET_PRI_DNS + printip(pri_dns_addr); +#endif +#ifdef IPCP_GET_SEC_DNS + printip(sec_dns_addr); +#endif + DEBUG1(("\n")); + break; + + case CONF_NAK: /* Config Nack */ + DEBUG1(("CONF NAK\n")); + + /* Dump the ID */ + + bptr++; + + /* Get the length */ + + len = (*bptr++ << 8); + len |= *bptr++; + + /* Parse ACK and set data */ + + while (bptr < buffer + len) + { + switch (*bptr++) + { + case IPCP_IPADDRESS: + /* dump length */ + bptr++; + + ((u8_t*)&ctx->local_ip)[0] = (char)*bptr++; + ((u8_t*)&ctx->local_ip)[1] = (char)*bptr++; + ((u8_t*)&ctx->local_ip)[2] = (char)*bptr++; + ((u8_t*)&ctx->local_ip)[3] = (char)*bptr++; + + netlib_ifup((char*)ctx->ifname); + netlib_set_ipv4addr((char*)ctx->ifname, &ctx->local_ip); + //DEBUG1(("My PPP-ipno: (%d.%d.%d.%d)\n", ((u8_t*)pppif.ipaddr)[0], ((u8_t*)pppif.ipaddr)[1], ((u8_t*)pppif.ipaddr)[2], ((u8_t*)pppif.ipaddr)[3])); + break; + +#ifdef IPCP_GET_PRI_DNS + case IPCP_PRIMARY_DNS: + bptr++; + ((u8_t*)&ctx->pri_dns_addr)[0] = *bptr++; + ((u8_t*)&ctx->pri_dns_addr)[1] = *bptr++; + ((u8_t*)&ctx->pri_dns_addr)[2] = *bptr++; + ((u8_t*)&ctx->pri_dns_addr)[3] = *bptr++; + break; +#endif + +#ifdef IPCP_GET_SEC_DNS + case IPCP_SECONDARY_DNS: + bptr++; + ((u8_t*)&ctx->sec_dns_addr)[0] = *bptr++; + ((u8_t*)&ctx->sec_dns_addr)[1] = *bptr++; + ((u8_t*)&ctx->sec_dns_addr)[2] = *bptr++; + ((u8_t*)&ctx->sec_dns_addr)[3] = *bptr++; + break; +#endif + + default: + DEBUG1(("IPCP CONFIG_ACK problem 2\n")); + } + } + + ctx->ppp_id++; + + printip(pppif.ipaddr); +#ifdef IPCP_GET_PRI_DNS + printip(pri_dns_addr); +#endif +#ifdef IPCP_GET_PRI_DNS + printip(sec_dns_addr); +#endif + DEBUG1(("\n")); + break; + + case CONF_REJ: /* Config Reject */ + DEBUG1(("CONF REJ\n")); + + /* Remove the offending options*/ + + ctx->ppp_id++; + + /* Dump the ID */ + + bptr++; + + /* Get the length */ + + len = (*bptr++ << 8); + len |= *bptr++; + + /* Parse ACK and set data */ + + while (bptr < buffer + len) + { + switch (*bptr++) + { + case IPCP_IPADDRESS: + ctx->ipcp_state |= IPCP_IP_BIT; + bptr += 5; + break; + +#ifdef IPCP_GET_PRI_DNS + case IPCP_PRIMARY_DNS: + ctx->ipcp_state |= IPCP_PRI_DNS_BIT; + bptr += 5; + break; +#endif + +#ifdef IPCP_GET_PRI_DNS + case IPCP_SECONDARY_DNS: + ctx->ipcp_state |= IPCP_SEC_DNS_BIT; + bptr += 5; + break; +#endif + + default: + DEBUG1(("IPCP this shoudln't happen 3\n")); + } + } + break; + + default: + DEBUG1(("-Unknown 4\n")); + } +} + +/*---------------------------------------------------------------------------*/ + +void ipcp_task(struct ppp_context_s *ctx, u8_t *buffer) +{ + u8_t *bptr; + u16_t t; + IPCPPKT *pkt; + + /* IPCP tx not up and hasn't timed out then lets see if we need to + send a request */ + + if (!(ctx->ipcp_state & IPCP_TX_UP) && !(ctx->ipcp_state & IPCP_TX_TIMEOUT)) + { + /* Check if we have a request pending */ + + if ((ppp_arch_clock_seconds() - ctx->ipcp_prev_seconds) > IPCP_TIMEOUT) + { + ctx->ipcp_prev_seconds = ppp_arch_clock_seconds(); + + /* No pending request, lets build one */ + + pkt=(IPCPPKT *)buffer; + + /* Configure-Request only here, write id */ + + pkt->code = CONF_REQ; + pkt->id = ctx->ppp_id; + + bptr = pkt->data; + + /* Write options, we want IP address, and DNS addresses if set. */ + /* Write zeros for IP address the first time */ + + *bptr++ = IPCP_IPADDRESS; + *bptr++ = 0x6; + *bptr++ = (u8_t)((u8_t*)&ctx->local_ip)[0]; + *bptr++ = (u8_t)((u8_t*)&ctx->local_ip)[1]; + *bptr++ = (u8_t)((u8_t*)&ctx->local_ip)[2]; + *bptr++ = (u8_t)((u8_t*)&ctx->local_ip)[3]; + +#ifdef IPCP_GET_PRI_DNS + if (!(ppp_ipcp_state & IPCP_PRI_DNS_BIT)) + { + /* Write zeros for IP address the first time */ + + *bptr++ = IPCP_PRIMARY_DNS; + *bptr++ = 0x6; + *bptr++ = ((u8_t*)&ctx->pri_dns_addr)[0]; + *bptr++ = ((u8_t*)&ctx->pri_dns_addr)[1]; + *bptr++ = ((u8_t*)&ctx->pri_dns_addr)[2]; + *bptr++ = ((u8_t*)&ctx->pri_dns_addr)[3]; + } +#endif + +#ifdef IPCP_GET_SEC_DNS + if (!(ppp_ipcp_state & IPCP_SEC_DNS_BIT)) + { + /* Write zeros for IP address the first time */ + + *bptr++ = IPCP_SECONDARY_DNS; + *bptr++ = 0x6; + *bptr++ = ((u8_t*)&ctx->sec_dns_addr)[0]; + *bptr++ = ((u8_t*)&ctx->sec_dns_addr)[1]; + *bptr++ = ((u8_t*)&ctx->sec_dns_addr)[2]; + *bptr++ = ((u8_t*)&ctx->sec_dns_addr)[3]; + } +#endif + + /* Write length */ + + t = bptr - buffer; + + /* length here - code and ID + */ + + pkt->len = htons(t); + + DEBUG1(("\n**Sending IPCP Request packet\n")); + + /* Send packet ahdlc_txz(procol,header,data,headerlen,datalen); */ + + ahdlc_tx(ctx, IPCP, 0, buffer, 0, t); + + /* Inc retry */ + + ctx->ipcp_retry++; + + /* Have we timed out? (combine the timers?) */ + + if (ctx->ipcp_retry > IPCP_RETRY_COUNT) + { + ctx->ipcp_state &= IPCP_TX_TIMEOUT; + } + } + } +} + +/*---------------------------------------------------------------------------*/ diff --git a/netutils/pppd/ipcp.h b/netutils/pppd/ipcp.h new file mode 100644 index 000000000..ee58f1cf7 --- /dev/null +++ b/netutils/pppd/ipcp.h @@ -0,0 +1,117 @@ +/* www.mycal.com + --------------------------------------------------------------------------- + IPCP.h - Internet Protocol Control Protocol header file + --------------------------------------------------------------------------- + Version + 0.1 Original Version June 3, 2000 + (c)2000 Mycal Labs, All Rights Reserved + --------------------------------------------------------------------------- +*/ +/* + * Copyright (c) 2003, Mike Johnson, Mycal Labs, www.mycal.net + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Mike Johnson/Mycal Labs + * www.mycal.net. + * 4. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the Mycal Modified uIP TCP/IP stack. + * + * $Id: ipcp.h,v 1.1 2007/05/26 07:14:39 oliverschmidt Exp $ + * + */ + +#ifndef __APPS_NETUTILS_PPPD_IPCP_H +#define __APPS_NETUTILS_PPPD_IPCP_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "ppp_arch.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Config options (move to pppconfig) + #define IPCP_RETRY_COUNT 5 + #define IPCP_TIMEOUT 5 +*/ + +/* IPCP Option Types */ + +#define IPCP_IPADDRESS 0x03 +#define IPCP_PRIMARY_DNS 0x81 +#define IPCP_SECONDARY_DNS 0x83 + +/* IPCP state machine flags */ + +#define IPCP_TX_UP 0x01 +#define IPCP_RX_UP 0x02 +#define IPCP_IP_BIT 0x04 +#define IPCP_TX_TIMEOUT 0x08 +#define IPCP_PRI_DNS_BIT 0x08 +#define IPCP_SEC_DNS_BIT 0x10 + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +struct ppp_context_s; + +typedef struct _ipcp +{ + u8_t code; + u8_t id; + u16_t len; + u8_t data[0]; +} IPCPPKT; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +void ipcp_init(struct ppp_context_s *ctx); +void ipcp_task(struct ppp_context_s *ctx, u8_t *buffer); +void ipcp_rx(struct ppp_context_s *ctx, u8_t *, u16_t); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __APPS_NETUTILS_PPPD_IPCP_H */ diff --git a/netutils/pppd/lcp.c b/netutils/pppd/lcp.c new file mode 100644 index 000000000..2a58c0218 --- /dev/null +++ b/netutils/pppd/lcp.c @@ -0,0 +1,589 @@ +/* www.mycal.com + *--------------------------------------------------------------------------- + *lcp.c - Link Configuration Protocol Handler. - - + *--------------------------------------------------------------------------- + *Version - 0.1 Original Version June 3, 2000 - + * + *--------------------------------------------------------------------------- + *- Copyright (C) 2000, Mycal Labs www.mycal.com - - + *--------------------------------------------------------------------------- + */ +/* + * Copyright (c) 2003, Mike Johnson, Mycal Labs, www.mycal.net + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Mike Johnson/Mycal Labs + * www.mycal.net. + * 4. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the Mycal Modified uIP TCP/IP stack. + * + * $Id: lcp.c,v 1.2 2010/10/19 18:29:03 adamdunkels Exp $ + * + */ + +/* include files */ + +#include "ppp_conf.h" +#include "ppp_arch.h" +#include "ppp.h" +#include "ahdlc.h" +#include "lcp.h" + +#if PPP_DEBUG +# define DEBUG1(x) debug_printf x +# define DEBUG2(x) debug_printf x +#else +# define DEBUG1(x) +# define DEBUG2(x) +#endif + +/* We need this when we neg our direction. + u8_t lcp_tx_options; */ + +/* Define the supported parameters for this module here. */ + +static const u8_t lcplist[] = +{ + LPC_MAGICNUMBER, + LPC_PFC, + LPC_ACFC, + LPC_AUTH, + LPC_ACCM, + LPC_MRU, + 0 +}; + +/*---------------------------------------------------------------------------*/ +/* lcp_init() - Initialize the LCP engine to startup values */ +/*---------------------------------------------------------------------------*/ + +void lcp_init(struct ppp_context_s *ctx) +{ + ctx->lcp_state = 0; + ctx->lcp_retry = 0; +} + +/*---------------------------------------------------------------------------*/ +/* lcp_rx() - Receive an LCP packet and process it. + * This routine receives a LCP packet in buffer of length count. + * Process it here, support for CONF_REQ, CONF_ACK, CONF_NACK, CONF_REJ or + * TERM_REQ. + */ +/*---------------------------------------------------------------------------*/ + +void lcp_rx(struct ppp_context_s *ctx, u8_t *buffer, u16_t count) +{ + u8_t *bptr = buffer, *tptr; + u8_t error = 0; + u8_t id; + u16_t len, j; + + switch (*bptr++) + { + case CONF_REQ: /* config request */ + /* Parse request and see if we can ACK it */ + + id = *bptr++; + len = (*bptr++ << 8); + len |= *bptr++; + /*len -= 2;*/ + + /* In case of new peer connection */ + + ipcp_init(ctx); + ctx->lcp_state &= ~LCP_TX_UP; + + DEBUG1(("received [LCP Config Request id %u\n", id)); + if (scan_packet(ctx, (u16_t)LCP, lcplist, buffer, bptr, (u16_t)(len-4))) + { + /* Must do the -4 here, !scan packet */ + + DEBUG1((" options were rejected\n")); + } + else + { + /* Lets try to implement what peer wants */ + + tptr = bptr = buffer; + bptr += 4; /* skip code, id, len */ + error = 0; + + /* First scan for unknown values */ + + while(bptr < (buffer + len)) + { + switch (*bptr++) + { + case LPC_MRU: /* mru */ + j = *bptr++; + j -= 2; + + if (j == 2) + { + ctx->ppp_tx_mru = ((int)*bptr++) << 8; + ctx->ppp_tx_mru |= *bptr++; + DEBUG1((" ", ctx->ppp_tx_mru)); + } + else + { + DEBUG1((" ")); + } + break; + + case LPC_ACCM: + bptr++; /* skip length */ + j = *bptr++; + j += *bptr++; + j += *bptr++; + j += *bptr++; + + if (j==0) + { + // ok + DEBUG1(("",j)); + //ahdlc_flags |= PPP_TX_ASYNC_MAP; + } + else if (j!=0) + { + // ok + DEBUG1((", assume 0xffffffff",j)); + } + else + { + /* Fail. We only support default or all zeros */ + + DEBUG1(("We only support default or all zeros for ACCM ")); + error = 1; + *tptr++ = LPC_ACCM; + *tptr++ = 0x6; + *tptr++ = 0; + *tptr++ = 0; + *tptr++ = 0; + *tptr++ = 0; + } + break; + + case LPC_AUTH: + bptr++; + if ((*bptr++ == 0xc0) && (*bptr++ == 0x23)) + { + /* Negotiate PAP */ + + if (strlen((char*)ctx->pap_username) > 0) + { + DEBUG1((" ")); + ctx->lcp_state |= LCP_RX_AUTH; + } + else + { + DEBUG1((" ")); + + *tptr++ = CONF_REJ; + tptr++; // Keep ID + *tptr++ = 0; + *tptr++ = 8; + *tptr++ = LPC_AUTH; + *tptr++ = 0x4; + *tptr++ = 0xc0; + *tptr++ = 0x23; + ahdlc_tx(ctx, LCP, 0, buffer, 0, (u16_t)(tptr-buffer)); + return; + } + } + else + { + /* We only support PAP */ + + DEBUG1(("")); + error = 1; + *tptr++ = LPC_AUTH; + *tptr++ = 0x4; + *tptr++ = 0xc0; + *tptr++ = 0x23; + } + break; + + case LPC_MAGICNUMBER: + DEBUG1((" ")); + + /* Compare incoming number to our number (not implemented) */ + + bptr++; /* For now just dump */ + bptr++; + bptr++; + bptr++; + bptr++; + break; + + case LPC_PFC: + bptr++; + DEBUG1((" ")); + /*tflag|=PPP_PFC;*/ + break; + + case LPC_ACFC: + bptr++; + DEBUG1((" ")); + /*tflag|=PPP_ACFC;*/ + break; + } + } + + /* Error? if we we need to send a config Reject ++++ this is good + * for a subroutine. + */ + + if (error) + { + /* Write the config NAK packet we've built above, take on the + * header + */ + + bptr = buffer; + *bptr++ = CONF_NAK; /* Write Conf_rej */ + bptr++;/*tptr++;*/ /* skip over ID */ + + /* Write new length */ + + *bptr++ = 0; + *bptr = tptr - buffer; + + /* Write the reject frame */ + + DEBUG1(("\nWriting NAK frame \n")); + // Send packet ahdlc_txz(procol,header,data,headerlen,datalen); + ahdlc_tx(ctx, LCP, 0, buffer, 0, (u16_t)(tptr-buffer)); + DEBUG1(("- end NAK Write frame\n")); + } + else + { + /* If we get here then we are OK, lets send an ACK and tell the rest + * of our modules our negotiated config. + */ + + DEBUG1(("\nSend ACK!\n")); + bptr = buffer; + *bptr++ = CONF_ACK; /* Write Conf_ACK */ + bptr++; /* Skip ID (send same one) */ + + /* Set stuff */ + + /*ppp_flags|=tflag;*/ + /* DEBUG2("SET- stuff -- are we up? c=%d dif=%d \n", count, (u16_t)(bptr-buffer)); */ + + /* Write the ACK frame */ + + DEBUG2(("Writing ACK frame \n")); + + /* Send packet ahdlc_txz(procol,header,data,headerlen,datalen); */ + + ahdlc_tx(ctx, LCP, 0, buffer, 0, count /*bptr-buffer*/); + DEBUG2(("- end ACK Write frame\n")); + ctx->lcp_state |= LCP_RX_UP; + } + } + break; + + case CONF_ACK: /* config Ack Anytime we do an ack reset the timer to force send. */ + DEBUG1(("LCP-ACK - ")); + + /* Check that ID matches one sent */ + + if (*bptr++ == ctx->ppp_id) + { + /* Change state to PPP up. */ + + DEBUG1((">>>>>>>> good ACK id up! %d\n", ctx->ppp_id)); + + /* Copy negotiated values over */ + + ctx->lcp_state |= LCP_TX_UP; + } + else + { + DEBUG1(("*************++++++++++ bad id %d\n", ctx->ppp_id)); + } + break; + + case CONF_NAK: /* Config Nack */ + DEBUG1(("LCP-CONF NAK\n")); + ctx->ppp_id++; + break; + + case CONF_REJ: /* Config Reject */ + DEBUG1(("LCP-CONF REJ\n")); + ctx->ppp_id++; + break; + + case TERM_REQ: /* Terminate Request */ + DEBUG1(("LCP-TERM-REQ -")); + bptr = buffer; + *bptr++ = TERM_ACK; /* Write TERM_ACK */ + + /* Write the reject frame */ + + DEBUG1(("Writing TERM_ACK frame \n")); + + /* Send packet ahdlc_txz(procol,header,data,headerlen,datalen); */ + + ahdlc_tx(ctx, LCP, 0, buffer, 0, count); + + ctx->lcp_state &= ~LCP_TX_UP; + ctx->lcp_state |= LCP_TERM_PEER; + break; + + case TERM_ACK: + DEBUG1(("LCP-TERM ACK\n")); + break; + + case ECHO_REQ: + if ((ctx->lcp_state & LCP_TX_UP) && (ctx->lcp_state & LCP_RX_UP)) + { + bptr = buffer; + *bptr++ = ECHO_REP; /* Write ECHO-REPLY */ + + bptr += 3; /* Skip id and length */ + + *bptr++ = 0; /* Zero Magic */ + *bptr++ = 0; + *bptr++ = 0; + *bptr++ = 0; + + /* Write the echo reply frame */ + + DEBUG1(("\nWriting ECHO-REPLY frame \n")); + // Send packet ahdlc_txz(procol,header,data,headerlen,datalen); + ahdlc_tx(ctx, LCP, 0, buffer, 0, count); + DEBUG1(("- end ECHO-REPLY Write frame\n")); + } + break; + + case ECHO_REP: + DEBUG1(("LCP-ECHO REPLY\n")); + if ((ctx->lcp_state & LCP_TX_UP) && (ctx->lcp_state & LCP_RX_UP)) + { + ctx->ppp_id++; + } + break; + + default: + DEBUG1(("LCP unknown packet: %02x", *(bptr-1))); + break; + } +} + +/*---------------------------------------------------------------------------*/ + +void lcp_disconnect(struct ppp_context_s *ctx, u8_t id) +{ + u8_t buffer[4]; + u8_t *bptr = buffer; + + *bptr++ = TERM_REQ; + *bptr++ = id; + *bptr++ = 0; + *bptr++ = 4; + + ahdlc_tx(ctx, LCP, 0, buffer, 0, bptr - buffer); +} + +/*---------------------------------------------------------------------------*/ + +void lcp_echo_request(struct ppp_context_s *ctx, u8_t *buffer) +{ + u8_t *bptr; + u16_t t; + LCPPKT *pkt; + + if ((ctx->lcp_state & LCP_TX_UP) && (ctx->lcp_state & LCP_RX_UP)) + { + if ((ppp_arch_clock_seconds() - ctx->lcp_prev_seconds) > LCP_ECHO_INTERVAL) + { + ctx->lcp_prev_seconds = ppp_arch_clock_seconds(); + + pkt = (LCPPKT *)buffer; + + /* Configure-Request only here, write id */ + + pkt->code = ECHO_REQ; + pkt->id = ctx->ppp_id; + + bptr = pkt->data; + + *bptr++ = 0; + *bptr++ = 0; + *bptr++ = 0; + *bptr++ = 0; + + /* Write length */ + + t = bptr - buffer; + pkt->len = htons(t); /* length here - code and ID + */ + + DEBUG1((" len %d\n",t)); + + /* Send packet */ + /* Send packet ahdlc_txz(procol,header,data,headerlen,datalen); */ + + DEBUG1(("\nWriting ECHO-REQUEST frame \n")); + ahdlc_tx(ctx, LCP, 0, buffer, 0, t); + DEBUG1(("- end ECHO-REQUEST Write frame\n")); + } + } +} + +/*---------------------------------------------------------------------------*/ +/* lcp_task(buffer) - This routine see if a lcp request needs to be sent + * out. It uses the passed buffer to form the packet. This formed LCP + * request is what we negotiate for sending options on the link. + * + * Currently we negotiate : Magic Number Only, but this will change. + */ +/*---------------------------------------------------------------------------*/ + +void lcp_task(struct ppp_context_s *ctx, u8_t *buffer) +{ + u8_t *bptr; + u16_t t; + LCPPKT *pkt; + + /* lcp tx not up and hasn't timed out then lets see if we need to send a + * request + */ + + if (!(ctx->lcp_state & LCP_TX_UP) && !(ctx->lcp_state & LCP_TX_TIMEOUT)) + { + /* Check if we have a request pending */ + + if ((ppp_arch_clock_seconds() - ctx->lcp_prev_seconds) > LCP_TIMEOUT) + { + ctx->lcp_prev_seconds = ppp_arch_clock_seconds(); + + DEBUG1(("\nSending LCP request packet - ")); + + /* No pending request, lets build one */ + + pkt = (LCPPKT *)buffer; + + /* Configure-Request only here, write id */ + + pkt->code = CONF_REQ; + pkt->id = ctx->ppp_id; + + bptr = pkt->data; + + /* Write options */ + + *bptr++ = LPC_ACCM; + *bptr++ = 0x6; + *bptr++ = 0xff; + *bptr++ = 0xff; + *bptr++ = 0xff; + *bptr++ = 0xff; + +#if 0 + /* Write magic number */ + + DEBUG1(("LPC_MAGICNUMBER -")); + *bptr++ = LPC_MAGICNUMBER; + *bptr++ = 0x6; + + /* + *bptr++ = random_rand() & 0xff; + *bptr++ = random_rand() & 0xff; + *bptr++ = random_rand() & 0xff; + *bptr++ = random_rand() & 0xff; + */ + + *bptr++ = 0x11; + *bptr++ = 0x11; + *bptr++ = 0x11; + *bptr++ = 0x11; +#endif + +#if 0 + /* Authentication protocol */ + + if ((lcp_tx_options & LCP_OPT_AUTH) && 0) + { + /* If turned on, we only negotiate PAP */ + + *bptr++ = LPC_AUTH; + *bptr++ = 0x4; + *bptr++ = 0xc0; + *bptr++ = 0x23; + } + + /* PFC */ + + if ((lcp_tx_options & LCP_OPT_PFC) && 0) + { + /* If turned on, we only negotiate PAP */ + + *bptr++ = LPC_PFC; + *bptr++ = 0x2; + } + + /* ACFC */ + + if ((lcp_tx_options & LCP_OPT_ACFC) && 0) + { + /* If turned on, we only negotiate PAP */ + + *bptr++ = LPC_ACFC; + *bptr++ = 0x2; + } +#endif + + /* Write length */ + + t = bptr - buffer; + pkt->len = htons(t); /* length here - code and ID + */ + + DEBUG1((" len %d\n",t)); + + /* Send packet */ + /* Send packet ahdlc_txz(procol,header,data,headerlen,datalen); */ + + ahdlc_tx(ctx, LCP, 0, buffer, 0, t); + + /* Inc retry */ + + ctx->lcp_retry++; + + /* Have we timed out? */ + + if (ctx->lcp_retry > LCP_RETRY_COUNT) + { + ctx->lcp_state &= LCP_TX_TIMEOUT; + } + } + } +} + +/*---------------------------------------------------------------------------*/ diff --git a/netutils/pppd/lcp.h b/netutils/pppd/lcp.h new file mode 100644 index 000000000..2565e43a7 --- /dev/null +++ b/netutils/pppd/lcp.h @@ -0,0 +1,133 @@ +/* www.mycal.com + --------------------------------------------------------------------------- + LCP.h - LCP header file + --------------------------------------------------------------------------- + Version - + 0.1 Original Version June 3, 2000 + (c)2000 Mycal Labs, All Rights Reserved + --------------------------------------------------------------------------- +*/ +/* + * Copyright (c) 2003, Mike Johnson, Mycal Labs, www.mycal.net + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Mike Johnson/Mycal Labs + * www.mycal.net. + * 4. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the Mycal Modified uIP TCP/IP stack. + * + * $Id: lcp.h,v 1.1 2007/05/26 07:14:39 oliverschmidt Exp $ + * + */ + +#ifndef __APPS_NETUTILS_PPPD_LCP_H +#define __APPS_NETUTILS_PPPD_LCP_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "ppp_arch.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* LCP Option Types */ + +#define LPC_VENDERX 0x0 +#define LPC_MRU 0x1 +#define LPC_ACCM 0x2 +#define LPC_AUTH 0x3 +#define LPC_QUALITY 0x4 +#define LPC_MAGICNUMBER 0x5 +#define LPC_PFC 0x7 +#define LPC_ACFC 0x8 + +/* LCP Negotiated options flag equates */ + +#define LCP_OPT_ACCM 0x1 +#define LCP_OPT_AUTH 0x2 +#define LCP_OPT_PFC 0x4 +#define LCP_OPT_ACFC 0x4 + +/* LCP state machine flags */ + +#define LCP_TX_UP 0x1 +#define LCP_RX_UP 0x2 + +#define LCP_RX_AUTH 0x10 + +/* LCP request for auth */ + +#define LCP_TERM_PEER 0x20 + +/* LCP Terminated by peer */ + +#define LCP_RX_TIMEOUT 0x40 +#define LCP_TX_TIMEOUT 0x80 + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +struct ppp_context_s; + +typedef struct _lcppkt +{ + u8_t code; + u8_t id; + u16_t len; + u8_t data[0]; +} LCPPKT; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +void lcp_init(struct ppp_context_s *ctx); +void lcp_rx(struct ppp_context_s *ctx, u8_t *, u16_t); +void lcp_task(struct ppp_context_s *ctx, u8_t *buffer); +void lcp_disconnect(struct ppp_context_s *ctx, u8_t id); +void lcp_echo_request(struct ppp_context_s *ctx, u8_t *buffer); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __APPS_NETUTILS_PPPD_LCP_H */ diff --git a/netutils/pppd/ntpv3.h b/netutils/pppd/ntpv3.h new file mode 100644 index 000000000..563b7226f --- /dev/null +++ b/netutils/pppd/ntpv3.h @@ -0,0 +1,207 @@ +/**************************************************************************** + * apps/netutils/pppd/ntpv3.h + * + * Copyright (C) 2014-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __APPS_NETUTILS_NTPCLIENT_NTPV3_H +#define __APPS_NETUTILS_NTPCLIENT_NTPV3_H 1 + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* The NTP version is described in RFC 1305 (NTP version 3), Appendix A: + * + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |LI | VN |Mode | Stratum | Poll | Precision | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Root Delay | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Root Dispersion | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Reference Identifier | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | + * | Reference Timestamp (64) | + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | + * | Originate Timestamp (64) | + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | + * | Receive Timestamp (64) | + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | + * | Transmit Timestamp (64) | + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Key Identifier (optional) (32) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | + * | | + * | Message Digest (optional) (128) | + * | | + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +#define NTP_DATAGRAM_MINSIZE (12 * sizeof(uint32_t)) +#define NTP_DATAGRAM_MAXSIZE (17 * sizeof(uint32_t)) + +/* Leap Indicator (LI): 2-bit code warning of impending leap-second to be + * inserted at the end of the last day of the current month. Bits are coded + * as follows: + * + * 00 no warning + * 01 last minute has 61 seconds + * 10 last minute has 59 seconds + * 11 alarm condition (clock not synchronized) + * + * Version Number (VN): This is a three-bit integer indicating the NTP + * version number. In this case, three (3). + * + * Mode: This is a three-bit integer indicating the mode, with values + * defined as follows: + * + * 0 reserved + * 1 symmetric active + * 2 symmetric passive + * 3 client + * 4 server + * 5 broadcast + * 6 reserved for NTP control message (see Appendix B) + * 7 reserved for private use + * + * Stratum: This is a eight-bit integer indicating the stratum level of the + * local clock, with values defined as follows: + * + * 0 unspecified + * 1 primary reference (e.g., radio clock) + * 2-255 secondary reference (via NTP) + * + * Poll Interval: This is an eight-bit signed integer indicating the maximum + * interval between successive messages, in seconds to the nearest power of + * two. + * + * Precision: This is an eight-bit signed integer indicating the precision + * of the local clock, in seconds to the nearest power of two. + * + * Root Delay: This is a 32-bit signed fixed-point number indicating the + * total roundtrip delay to the primary reference source, in seconds with + * fraction point between bits 15 and 16. Note that this variable can take + * on both positive and negative values, depending on clock precision and + * skew. + * + * Root Dispersion: This is a 32-bit signed fixed-point number indicating + * the maximum error relative to the primary reference source, in seconds + * with fraction point between bits 15 and 16. Only positive values greater + * than zero are possible. + * + * Reference Clock Identifier: This is a 32-bit code identifying the + * particular reference clock. In the case of stratum 0 (unspecified) or + * stratum 1 (primary reference), this is a four-octet, left-justified, + * zero-padded ASCII string. + * + * While not enumerated as part of the NTP specification, the following are + * suggested ASCII identifiers: + * + * Stratum Code Meaning + * 0 DCN DCN routing protocol + * 0 NIST NIST public modem + * 0 TSP TSP time protocol + * 0 DTS Digital Time Service + * 1 ATOM Atomic clock (calibrated) + * 1 VLF VLF radio (OMEGA, etc.) + * 1 callsign Generic radio + * 1 LORC LORAN-C radionavigation + * 1 GOES GOES UHF environment satellite + * 1 GPS GPS UHF satellite positioning + * + * In the case of stratum 2 and greater (secondary reference) this is the + * four-octet Internet address of the primary reference host. + * + * Reference Timestamp: This is the local time at which the local clock was + * last set or corrected, in 64-bit timestamp format. + * + * Originate Timestamp: This is the local time at which the request departed + * the client host for the service host, in 64-bit timestamp format. + * + * Receive Timestamp: This is the local time at which the request arrived at + * the service host, in 64-bit timestamp format. + * + * Transmit Timestamp: This is the local time at which the reply departed + * the service host for the client host, in 64-bit timestamp format. + * + * Authenticator (optional): When the NTP authentication mechanism is + * implemented, this contains the authenticator information defined in + * Appendix C. + */ + +#define MKLVM(l,v,m) ((uint8_t)(l) << 6 | (uint8_t)(v) << 3 | (uint8_t)(m)) +#define GETLI(lvm) ((uint8_t)(lvm) >> 6) +#define GETVN(lvm) ((uint8_t)(lvm) >> 3) & 7) +#define GETMODE(lvm) ((uint8_t)(lvm) & 7) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +struct ntp_datagram_s +{ + uint8_t lvm; /* LI | VN | Mode */ + uint8_t stratum; /* Stratum */ + uint8_t poll; /* Poll interval */ + uint8_t precision; /* Precision */ + uint8_t rootdelay[4]; /* Root Delay */ + uint8_t rootdispersion[4]; /* Root dispersion */ + uint8_t refid[4]; /* Reference Clock Identifier */ + uint8_t reftimestamp[8]; /* Rererence Timestamp */ + uint8_t origtimestamp[8]; /* Originate Timestamp */ + uint8_t recvtimestamp[8]; /* Receive Timestamp */ + uint8_t xmittimestamp[8]; /* Transmit Timestamp */ + uint8_t keyid[4]; /* Authenticator data */ + uint8_t digest1[4]; + uint8_t digest2[4]; + uint8_t digest3[4]; + uint8_t digest4[4]; +}; + +#endif /* __APPS_NETUTILS_NTPCLIENT_NTPV3_H */ diff --git a/netutils/pppd/pap.c b/netutils/pppd/pap.c new file mode 100644 index 000000000..982fe83c0 --- /dev/null +++ b/netutils/pppd/pap.c @@ -0,0 +1,188 @@ +/* www.mycal.net + *--------------------------------------------------------------------------- + *pap.c - PAP processor for the PPP module - - + *--------------------------------------------------------------------------- + *Version - 0.1 Original Version Jun 3, 2000 - - + *--------------------------------------------------------------------------- + *- Copyright (C) 2000, Mycal Labs www.mycal.com - - + *--------------------------------------------------------------------------- +*/ +/* + * Copyright (c) 2003, Mike Johnson, Mycal Labs, www.mycal.net + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Mike Johnson/Mycal Labs + * www.mycal.net. + * 4. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the Mycal Modified uIP TCP/IP stack. + * + * $Id: pap.c,v 1.2 2010/10/19 18:29:03 adamdunkels Exp $ + * + */ + +/* */ +/* include files */ +/* */ + +#include "ppp_conf.h" +#include "ppp_arch.h" +#include "ppp.h" +#include "pap.h" +#include "lcp.h" + +#if PPP_DEBUG +# define DEBUG1(x) debug_printf x +#else +# define DEBUG1(x) +#endif + +/*---------------------------------------------------------------------------*/ + +void pap_init(struct ppp_context_s *ctx) +{ + ctx->pap_retry = 0; + ctx->pap_state = 0; + ctx->pap_prev_seconds = 0; +} + +/*---------------------------------------------------------------------------*/ +/* pap_rx() - PAP RX protocol Handler */ +/*---------------------------------------------------------------------------*/ + +void pap_rx(struct ppp_context_s *ctx, u8_t *buffer, u16_t count) +{ + u8_t *bptr=buffer; + u8_t len; + + switch (*bptr++) + { + case CONF_REQ: + DEBUG1(("CONF REQ - only for server, no support\n")); + break; + + case CONF_ACK: /* config Ack */ + DEBUG1(("CONF ACK - PAP good - ")); + + /* Display message if debug */ + + len = *bptr++; + *(bptr + len) = 0; + DEBUG1((" %s \n",bptr)); + ctx->pap_state |= PAP_TX_UP; + break; + + case CONF_NAK: + DEBUG1(("CONF NAK - Failed Auth - ")); + ctx->pap_state |= PAP_TX_AUTH_FAIL; + + /* Display message if debug */ + + len = *bptr++; + *(bptr + len)=0; + DEBUG1((" %s \n",bptr)); + break; + } +} +/*---------------------------------------------------------------------------*/ +/* pap_task() - This task needs to be called every so often during the PAP + * negotiation phase. This task sends PAP REQ packets. + */ +/*---------------------------------------------------------------------------*/ + +void pap_task(struct ppp_context_s *ctx, u8_t *buffer) +{ + u8_t *bptr; + u16_t t; + PAPPKT *pkt; + + /* If LCP is up and PAP negotiated, try to bring up PAP */ + + if (!(ctx->pap_state & PAP_TX_UP) && !(ctx->pap_state & PAP_TX_TIMEOUT)) + { + /* Do we need to send a PAP auth packet? + Check if we have a request pending*/ + + if ((ppp_arch_clock_seconds() - ctx->pap_prev_seconds) > PAP_TIMEOUT) + { + ctx->pap_prev_seconds = ppp_arch_clock_seconds(); + + /* We need to send a PAP authentication request */ + + DEBUG1(("\nSending PAP Request packet - ")); + + /* Build a PAP request packet */ + + pkt = (PAPPKT *)buffer; + + /* Configure-Request only here, write id */ + + pkt->code = CONF_REQ; + pkt->id = ctx->ppp_id; + bptr = pkt->data; + + /* Write options */ + + t = strlen((char*)ctx->pap_username); + + /* Write peer length */ + + *bptr++ = (u8_t)t; + bptr = memcpy(bptr, ctx->pap_username, t); + + t = strlen((char*)ctx->pap_password); + *bptr++ = (u8_t)t; + bptr = memcpy(bptr, ctx->pap_password, t); + + /* Write length */ + + t = bptr - buffer; + + /* length here - code and ID + */ + + pkt->len = htons(t); + + DEBUG1((" Len %d\n",t)); + + /* Send packet */ + + ahdlc_tx(ctx, PAP, buffer, 0, t, 0); + + ctx->pap_retry++; + + /* Have we failed? */ + + if (ctx->pap_retry > PAP_RETRY_COUNT) + { + DEBUG1(("PAP - timout\n")); + ctx->pap_state &= PAP_TX_TIMEOUT; + } + } + } +} + +/*---------------------------------------------------------------------------*/ diff --git a/netutils/pppd/pap.h b/netutils/pppd/pap.h new file mode 100644 index 000000000..915bc0f27 --- /dev/null +++ b/netutils/pppd/pap.h @@ -0,0 +1,113 @@ +/* + www.mycal.com + --------------------------------------------------------------------------- + pap.h - pap header file + --------------------------------------------------------------------------- + Version + 0.1 Original Version June 3, 2000 + (c)2000 Mycal Labs, All Rights Reserved + --------------------------------------------------------------------------- +*/ +/* + * Copyright (c) 2003, Mike Johnson, Mycal Labs, www.mycal.net + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Mike Johnson/Mycal Labs + * www.mycal.net. + * 4. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the Mycal Modified uIP TCP/IP stack. + * + * $Id: pap.h,v 1.1 2007/05/26 07:14:40 oliverschmidt Exp $ + * + */ + +#ifndef __APPS_NETUTILS_PPPD_PAP_H +#define __APPS_NETUTILS_PPPD_PAP_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "ppp_arch.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* PAP state machine flags */ +/* Client only */ + +#define PAP_TX_UP 0x01 + +/* Server only */ + +#define PAP_RX_UP 0x02 + +#define PAP_RX_AUTH_FAIL 0x10 +#define PAP_TX_AUTH_FAIL 0x20 +#define PAP_RX_TIMEOUT 0x80 +#define PAP_TX_TIMEOUT 0x80 + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +struct ppp_context_s; + +typedef struct _pappkt +{ + u8_t code; + u8_t id; + u16_t len; + u8_t data[0]; +} PAPPKT; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/* Function prototypes */ +void pap_init(struct ppp_context_s *ctx); +void pap_rx(struct ppp_context_s *ctx, u8_t *, u16_t); +void pap_task(struct ppp_context_s *ctx, u8_t *buffer); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __APPS_NETUTILS_PPPD_PAP_H */ diff --git a/netutils/pppd/ppp.c b/netutils/pppd/ppp.c new file mode 100644 index 000000000..b1b19a286 --- /dev/null +++ b/netutils/pppd/ppp.c @@ -0,0 +1,456 @@ +/* + *--------------------------------------------------------------------------- + * ppp.c - PPP Processor/Handler + * + *--------------------------------------------------------------------------- + * + * Version + * 0.1 Original Version Jun 3, 2000 + * + *--------------------------------------------------------------------------- + */ +/* + * Copyright (c) 2003, Mike Johnson, Mycal Labs, www.mycal.net + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Mike Johnson/Mycal Labs + * www.mycal.net. + * 4. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the Mycal Modified uIP TCP/IP stack. + * + * $Id: ppp.c,v 1.2 2010/10/19 18:29:03 adamdunkels Exp $ + * + */ + +/* */ +/* include files */ +/* */ + +#include "ppp_conf.h" +#include "ppp_arch.h" +#include "ppp.h" +#include "ahdlc.h" +#include "ipcp.h" +#include "lcp.h" +#include "pap.h" + +#if PPP_DEBUG +# define DEBUG1(x) debug_printf x +#else +# define DEBUG1(x) +#endif + +/* Set the debug message level */ + +#define PACKET_RX_DEBUG 1 + +/*---------------------------------------------------------------------------*/ +/* Unknown Protocol Handler, sends reject */ + +static void ppp_reject_protocol(struct ppp_context_s *ctx, u16_t protocol, + u8_t *buffer, u16_t count) +{ + u16_t i; + u8_t *dptr, *sptr; + LCPPKT *pkt; + + /* first copy rejected packet back, start from end and work forward, + +++ Pay attention to buffer management when updated. Assumes fixed + PPP blocks. */ + + DEBUG1(("Rejecting Protocol\n")); + if ((count + 6) > PPP_RX_BUFFER_SIZE) + { + /* This is a fatal error +++ do something about it. */ + + DEBUG1(("Cannot Reject Protocol, PKT to big\n")); + return; + } + + dptr = buffer + count + 6; + sptr = buffer + count; + for(i = 0; i < count; ++i) + { + *dptr-- = *sptr--; + } + + pkt = (LCPPKT *)buffer; + pkt->code = PROT_REJ; /* Write Conf_rej */ + /*pkt->id = tid++;*/ /* write tid */ + pkt->len = htons(count + 6); + *((u16_t *)(&pkt->data[0])) = htons(protocol); + + ahdlc_tx(ctx, LCP, buffer, 0, (u16_t)(count + 6), 0); +} + +/*---------------------------------------------------------------------------*/ + +#if PACKET_RX_DEBUG +void dump_ppp_packet(u8_t *buffer, u16_t len) +{ + int i; + + DEBUG1(("\n")); + for(i = 0;i < len; ++i) + { + if ((i & 0x1f) == 0x10) + { + DEBUG1(("\n")); + } + + DEBUG1(("0x%02x ",buffer[i])); + } + + DEBUG1(("\n\n")); +} +#endif + +/*---------------------------------------------------------------------------*/ +/* Initialize and start PPP engine. This just sets things up to + * starting values. This can stay a private method. + */ +/*---------------------------------------------------------------------------*/ + +void ppp_init(struct ppp_context_s *ctx) +{ +#ifdef PPP_STATISTICS + ctx->ppp_rx_frame_count = 0; +#endif + ctx->ppp_flags = 0; + ctx->ip_no_data_time = 0; + ctx->ppp_id = 0; + + pap_init(ctx); + ipcp_init(ctx); + lcp_init(ctx); + + ahdlc_init(ctx); + ahdlc_rx_ready(ctx); +} + +/*---------------------------------------------------------------------------*/ +/* raise_ppp() - This routine will try to bring up a PPP connection, + * It is blocking. In the future we probably want to pass a + * structure with all the options on bringing up a PPP link, like + * server/client, DSN server, username password for PAP... +++ for + * now just use config and bit defines + */ +/*---------------------------------------------------------------------------*/ + +#if 0 +u16_t +ppp_raise(u8_t config, u8_t *username, u8_t *password) +{ + u16_t status = 0; + + /* Initialize PPP engine */ + /* init_ppp(); */ + + pap_init(); + ipcp_init(); + lcp_init(); + + /* Enable PPP */ + + ppp_flags = PPP_RX_READY; + + /* Try to bring up the layers */ + + while (status == 0) + { +#ifdef SYSTEM_POLLER + /* If the the serial interrupt is not hooked to ahdlc_rx, or the + system needs to handle other stuff while were blocking, call + the system poller.*/ + + system_poller(); +#endif + + /* Call the lcp task to bring up the LCP layer */ + + lcp_task(ppp_tx_buffer); + + /* If LCP is up, neg next layer */ + + if (lcp_state & LCP_TX_UP) + { + /* If LCP wants PAP, try to authenticate, else bring up IPCP */ + + if ((lcp_state & LCP_RX_AUTH) && (!(pap_state & PAP_TX_UP))) + { + pap_task(ppp_tx_buffer,username,password); + } + else + { + ipcp_task(ppp_tx_buffer); + } + } + + /* If IPCP came up then our link should be up. */ + + if ((ipcp_state & IPCP_TX_UP) && (ipcp_state & IPCP_RX_UP)) + { + break; + } + + status = check_ppp_errors(); + } + + return status; +} +#endif + +/*---------------------------------------------------------------------------*/ + +void ppp_connect(struct ppp_context_s *ctx) +{ + /* Initialize PPP engine */ + + /* init_ppp(); */ + pap_init(ctx); + ipcp_init(ctx); + lcp_init(ctx); + + /* Enable PPP */ + + ctx->ppp_flags = PPP_RX_READY; +} + +/*---------------------------------------------------------------------------*/ + +void ppp_send(struct ppp_context_s *ctx) +{ + /* If IPCP came up then our link should be up. */ + + if ((ctx->ipcp_state & IPCP_TX_UP) && (ctx->ipcp_state & IPCP_RX_UP)) + { + ahdlc_tx(ctx, IPV4, 0, ctx->ip_buf, 0, ctx->ip_len); + } +} + +/*---------------------------------------------------------------------------*/ + +void ppp_poll(struct ppp_context_s *ctx) +{ + u8_t c; + + ctx->ip_len = 0; + + ++ctx->ip_no_data_time; + if (ctx->ip_no_data_time > PPP_IP_TIMEOUT) + { + ppp_reconnect(ctx); + return; + } + + if (!(ctx->ppp_flags & PPP_RX_READY)) + { + return; + } + + while (ctx->ip_len == 0 && ppp_arch_getchar(ctx, &c)) + { + ahdlc_rx(ctx, c); + } + + /* If IPCP came up then our link should be up. */ + + if ((ctx->ipcp_state & IPCP_TX_UP) && (ctx->ipcp_state & IPCP_RX_UP)) + { + lcp_echo_request(ctx, ctx->ip_buf); + return; + } + + /* Call the lcp task to bring up the LCP layer */ + + lcp_task(ctx, ctx->ip_buf); + + /* If LCP is up, neg next layer */ + + if ((ctx->lcp_state & LCP_TX_UP) && (ctx->lcp_state & LCP_RX_UP)) + { + /* If LCP wants PAP, try to authenticate, else bring up IPCP */ + + if ((ctx->lcp_state & LCP_RX_AUTH) && (!(ctx->pap_state & PAP_TX_UP))) + { + pap_task(ctx, ctx->ip_buf); + } + else + { + ipcp_task(ctx, ctx->ip_buf); + } + } +} + +/*---------------------------------------------------------------------------*/ +/* ppp_upcall() - this is where valid PPP frames from the ahdlc layer are + * sent to be processed and demuxed. + */ +/*---------------------------------------------------------------------------*/ + +void ppp_upcall(struct ppp_context_s *ctx, u16_t protocol, u8_t *buffer, u16_t len) +{ +#ifdef PPP_STATISTICS + ++ctx->ppp_rx_frame_count; + +#ifdef PPP_DEBUG + dump_ppp_packet(buffer, len); +#endif + +#endif /* PPP_STATISTICS */ + + /* Check to see if we have a packet waiting to be processed */ + + if (ctx->ppp_flags & PPP_RX_READY) + { + /* Demux on protocol field */ + + switch(protocol) { + case LCP: /* We must support some level of LCP */ + DEBUG1(("LCP Packet - ")); + lcp_rx(ctx, buffer, len); + DEBUG1(("\n")); + break; + + case PAP: /* PAP should be compile in optional */ + DEBUG1(("PAP Packet - ")); + pap_rx(ctx, buffer, len); + DEBUG1(("\n")); + break; + + case IPCP: /* IPCP should be compile in optional. */ + DEBUG1(("IPCP Packet - ")); + ipcp_rx(ctx, buffer, len); + DEBUG1(("\n")); + break; + + case IPV4: /* We must support IPV4 */ + DEBUG1(("IPV4 Packet---\n")); + memcpy(ctx->ip_buf, buffer, len); + ctx->ip_len = len; + ctx->ip_no_data_time = 0; + DEBUG1(("\n")); + break; + + default: + DEBUG1(("Unknown PPP Packet Type 0x%04x - ",protocol)); + ppp_reject_protocol(ctx, protocol, buffer, len); + DEBUG1(("\n")); + break; + } + } +} + +/*---------------------------------------------------------------------------*/ +/* scan_packet(list,buffer,len) + * + * list = list of supported ID's + * *buffer pointer to the first code in the packet + * length of the codespace + */ + +u16_t scan_packet(struct ppp_context_s *ctx, u16_t protocol, const u8_t *list, + u8_t *buffer, u8_t *options, u16_t len) +{ + const u8_t *tlist; + u8_t *bptr; + u8_t *tptr; + u8_t bad = 0; + u8_t i, j, good; + + bptr = tptr = options; + + /* Scan through the packet and see if it has any unsupported codes */ + + while (bptr < options + len) + { + /* Get code and see if it matches somwhere in the list, if not + we don't support it */ + + i = *bptr++; + + /* DEBUG2("%x - ",i); */ + + tlist = list; + good = 0; + while (*tlist) + { + /* DEBUG2("%x ",*tlist); */ + if (i == *tlist++) + { + good = 1; + break; + } + } + + if (!good) + { + /* We don't understand it, write it back */ + + DEBUG1(("We don't understand option 0x%02x\n",i)); + bad = 1; + *tptr++ = i; + j = *tptr++ = *bptr++; + for(i = 0; i < j - 2; ++i) + { + *tptr++ = *bptr++; + } + } + else + { + /* Advance over to next option */ + + bptr += *bptr - 1; + } + } + + /* Bad? if we we need to send a config Reject */ + + if (bad) + { + /* Write the config Rej packet we've built above, take on the header */ + + bptr = buffer; + *bptr++ = CONF_REJ; /* Write Conf_rej */ + bptr++; /* skip over ID */ + *bptr++ = 0; + *bptr = tptr - buffer; + + /* Length right here? */ + + /* Write the reject frame */ + + DEBUG1(("Writing Reject frame --\n")); + ahdlc_tx(ctx, protocol, buffer, 0, (u16_t)(tptr - buffer), 0); + DEBUG1(("\nEnd writing reject \n")); + } + + return bad; +} + +/*---------------------------------------------------------------------------*/ diff --git a/netutils/pppd/ppp.h b/netutils/pppd/ppp.h new file mode 100644 index 000000000..f70b63c60 --- /dev/null +++ b/netutils/pppd/ppp.h @@ -0,0 +1,233 @@ +/* www.mycal.net +--------------------------------------------------------------------------- + ppp.h - ppp header file +--------------------------------------------------------------------------- + Version + 0.1 Original Version June 3, 2000 + (c)2000 Mycal Labs, All Rights Reserved + --------------------------------------------------------------------------- */ +/* + * Copyright (c) 2003, Mike Johnson, Mycal Labs, www.mycal.net + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Mike Johnson/Mycal Labs + * www.mycal.net. + * 4. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the Mycal Modified uIP TCP/IP stack. + * + * $Id: ppp.h,v 1.1 2007/05/26 07:14:40 oliverschmidt Exp $ + * + */ + +#ifndef __APPS_NETUTILS_PPPD_PPP_H +#define __APPS_NETUTILS_PPPD_PPP_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "ppp_conf.h" +#include "ahdlc.h" +#include "lcp.h" +#include "ipcp.h" +#include "pap.h" +#include "ppp_arch.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define CRC_GOOD_VALUE 0xf0b8 + +/* ppp_rx_status values */ + +#define PPP_RX_IDLE 0 +#define PPP_READY 1 + +/* ppp flags */ + +#define PPP_ESCAPED 0x1 +#define PPP_RX_READY 0x2 +#define PPP_RX_ASYNC_MAP 0x8 +#define PPP_TX_ASYNC_MAP 0x8 +#define PPP_PFC 0x10 +#define PPP_ACFC 0x20 + +/* Supported PPP Protocols */ + +#define LCP 0xc021 +#define PAP 0xc023 +#define IPCP 0x8021 +#define IPV4 0x0021 + +/* LCP codes packet types */ + +#define CONF_REQ 0x1 +#define CONF_ACK 0x2 +#define CONF_NAK 0x3 +#define CONF_REJ 0x4 +#define TERM_REQ 0x5 +#define TERM_ACK 0x6 +#define PROT_REJ 0x8 +#define ECHO_REQ 0x9 +#define ECHO_REP 0xa + +/* Raise PPP config bits */ + +#define USE_PAP 0x1 +#define USE_NOACCMBUG 0x2 +#define USE_GETDNS 0x4 + +#define ppp_setusername(un) strncpy(pap_username, (un), PAP_USERNAME_SIZE) +#define ppp_setpassword(pw) strncpy(pap_password, (pw), PAP_PASSWORD_SIZE) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +struct chat_script_s; + +/* PPP context definition */ + +struct ppp_context_s +{ + /* IP Buffer */ + + u8_t ip_buf[PPP_RX_BUFFER_SIZE]; + u16_t ip_len; + + /* Main status */ + + u8_t ppp_flags; + u8_t ppp_status; + u16_t ppp_tx_mru; + u8_t ppp_id; + + /* IP timeout */ + + u16_t ip_no_data_time; + + /* Interfaces */ + + int tty_fd; + u8_t ttyname[TTYNAMSIZ]; + int if_fd; + u8_t ifname[IFNAMSIZ]; + + /* Addresses */ + + struct in_addr local_ip; +#ifdef IPCP_GET_PEER_IP + struct in_addr peer_ip; +#endif +#ifdef IPCP_GET_PRI_DNS + struct in_addr pri_dns_addr; +#endif +#ifdef IPCP_GET_SEC_DNS + struct in_addr sec_dns_addr; +#endif + + /* LCP */ + + u8_t lcp_state; + u16_t lcp_tx_mru; + u8_t lcp_retry; + time_t lcp_prev_seconds; + + /* PAP */ + + u8_t pap_username[PAP_USERNAME_SIZE]; + u8_t pap_password[PAP_PASSWORD_SIZE]; + u8_t pap_state; + u8_t pap_retry; + time_t pap_prev_seconds; + + /* IPCP */ + + u8_t ipcp_state; + u8_t ipcp_retry; + time_t ipcp_prev_seconds; + + /* AHDLC */ + + u8_t ahdlc_rx_buffer[PPP_RX_BUFFER_SIZE]; + u16_t ahdlc_tx_crc; /* running tx CRC */ + u16_t ahdlc_rx_crc; /* running rx CRC */ + u16_t ahdlc_rx_count; /* number of rx bytes processed, cur frame */ + u8_t ahdlc_flags; /* ahdlc state flags, see above */ + u8_t ahdlc_tx_offline; + + /* Scripts */ + + struct chat_script_s *connect_script; + struct chat_script_s *disconnect_script; + + /* Statistics counters */ + +#ifdef PPP_STATISTICS + u16_t ahdlc_crc_error; + u16_t ahdlc_rx_tobig_error; + u32_t ppp_rx_frame_count; + u32_t ppp_tx_frame_count; +#endif +}; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/* + * Function Prototypes + */ +void ppp_init(struct ppp_context_s *ctx); +void ppp_connect(struct ppp_context_s *ctx); + +extern void ppp_reconnect(struct ppp_context_s *ctx); + +void ppp_send(struct ppp_context_s *ctx); +void ppp_poll(struct ppp_context_s *ctx); + +void ppp_upcall(struct ppp_context_s *ctx, u16_t, u8_t *, u16_t); +u16_t scan_packet(struct ppp_context_s *ctx, u16_t, const u8_t *list, + u8_t *buffer, u8_t *options, u16_t len); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __APPS_NETUTILS_PPPD_PPP_H */ diff --git a/netutils/pppd/ppp_arch.h b/netutils/pppd/ppp_arch.h new file mode 100644 index 000000000..5226df48f --- /dev/null +++ b/netutils/pppd/ppp_arch.h @@ -0,0 +1,59 @@ +#ifndef __APPS_NETUTILS_PPPD_PPP_ARCH_H +#define __APPS_NETUTILS_PPPD_PPP_ARCH_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define TTYNAMSIZ 16 + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +struct ppp_context_s; + +typedef uint8_t u8_t; +typedef uint16_t u16_t; +typedef uint32_t u32_t; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +time_t ppp_arch_clock_seconds(void); + +int ppp_arch_getchar(struct ppp_context_s *ctx, u8_t *p); +int ppp_arch_putchar(struct ppp_context_s *ctx, u8_t c); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __APPS_NETUTILS_PPPD_PPP_ARCH_H */ \ No newline at end of file diff --git a/netutils/pppd/ppp_conf.h b/netutils/pppd/ppp_conf.h new file mode 100644 index 000000000..dfbfbfd22 --- /dev/null +++ b/netutils/pppd/ppp_conf.h @@ -0,0 +1,36 @@ +#ifndef __APPS_NETUTILS_PPPD_PPP_CONF_H +#define __APPS_NETUTILS_PPPD_PPP_CONF_H + +#define IPCP_RETRY_COUNT 5 +#define IPCP_TIMEOUT 5 +#define IPV6CP_RETRY_COUNT 5 +#define IPV6CP_TIMEOUT 5 +#define LCP_RETRY_COUNT 5 +#define LCP_TIMEOUT 5 +#define PAP_RETRY_COUNT 5 +#define PAP_TIMEOUT 5 +#define LCP_ECHO_INTERVAL 20 + +#define PPP_IP_TIMEOUT (6*3600) +#define PPP_MAX_CONNECT 15 + +#define PAP_USERNAME_SIZE 16 +#define PAP_PASSWORD_SIZE 16 +#define PAP_USERNAME "user" +#define PAP_PASSWORD "pass" + +#define xxdebug_printf printf +#define debug_printf printf + +#define PPP_RX_BUFFER_SIZE 1024 //1024 //GD 2048 for 1280 IPv6 MTU +#define PPP_TX_BUFFER_SIZE 64 + +#define AHDLC_TX_OFFLINE 5 +//#define AHDLC_COUNTERS 1 //defined for AHDLC stats support, Guillaume Descamps, September 19th, 2011 + +#define IPCP_GET_PEER_IP 1 + +#define PPP_STATISTICS 1 +#define PPP_DEBUG 1 + +#endif /* __APPS_NETUTILS_PPPD_PPP_CONF_H */ \ No newline at end of file diff --git a/netutils/pppd/pppd.c b/netutils/pppd/pppd.c new file mode 100644 index 000000000..2cd456143 --- /dev/null +++ b/netutils/pppd/pppd.c @@ -0,0 +1,435 @@ +/**************************************************************************** + * netutils/pppd/pppd.c + * + * Copyright (C) 2015 Max Nekludov. All rights reserved. + * Author: Max Nekludov + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "ppp.h" +#include "chat.h" + +#if PPP_ARCH_HAVE_MODEM_RESET +extern void ppp_arch_modem_reset(const char *tty); +#endif + +/* +socat /dev/ttyUSB2,raw,echo=0,b115200,crtscts=0 /dev/ttyUSB7,raw,echo=0,b115200,crtscts=0 +*/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* This type describes the state of the NTP client daemon. Only once + * instance of the NTP daemon is permitted in this implementation. This + * limitation is due only to this global data structure. + */ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct chat_script_s connect_script = +{ + .timeout = 30, + .lines = + { + {"AT", "OK"}, + {"AT+CGDCONT = 1,\"IP\",\"internet\"", "OK"}, + {"ATD*99***1#", "CONNECT"}, + {0, 0} + }, +}; + +static struct chat_script_s disconnect_script = +{ + .timeout = 30, + .lines = + { + {"ATZ", "OK"}, + {0, 0} + }, +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: make_nonblock + ****************************************************************************/ + +static int make_nonblock(int fd) +{ + int flags; + + if( (flags = fcntl(fd, F_GETFL, 0)) < 0) + { + return flags; + } + + if( (flags = fcntl(fd, F_SETFL, flags | O_NONBLOCK)) < 0 ) + { + return flags; + } + + return 0; +} + +/**************************************************************************** + * Name: tun_alloc + ****************************************************************************/ + +static int tun_alloc(char *dev) +{ + struct ifreq ifr; + int fd, err; + + if( (fd = open("/dev/tun", O_RDWR)) < 0 ) + return fd; + + printf("tun fd:%i\n", fd); + + if ((err = make_nonblock(fd)) < 0) + { + close(fd); + return err; + } + + memset(&ifr, 0, sizeof(ifr)); + ifr.ifr_flags = IFF_TUN; + if( *dev ) + { + strncpy(ifr.ifr_name, dev, IFNAMSIZ); + } + + if( (err = ioctl(fd, TUNSETIFF, (unsigned long)&ifr)) < 0 ) + { + close(fd); + return err; + } + + strcpy(dev, ifr.ifr_name); + + return fd; +} + +/**************************************************************************** + * Name: open_tty + ****************************************************************************/ + +static int open_tty(char *dev) +{ + int fd; + int err; + + if( (fd = open(dev, O_RDWR)) < 0 ) + return fd; + + if ((err = make_nonblock(fd)) < 0) + { + close(fd); + return err; + } + + printf("tty fd:%i\n", fd); + + return fd; +} + +/**************************************************************************** + * Name: ppp_check_errors + ****************************************************************************/ + +static u8_t ppp_check_errors(struct ppp_context_s *ctx) +{ + u8_t ret = 0; + + /* Check Errors */ + + if(ctx->lcp_state & (LCP_TX_TIMEOUT | LCP_RX_TIMEOUT | LCP_TERM_PEER)) + { + ret = 1; + } + + if(ctx->pap_state & (PAP_TX_AUTH_FAIL | PAP_RX_AUTH_FAIL | PAP_TX_TIMEOUT | PAP_RX_TIMEOUT)) + { + ret = 2; + } + + if(ctx->ipcp_state & (IPCP_TX_TIMEOUT)) + { + ret = 3; + } + + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: ppp_reconnect + ****************************************************************************/ + +void ppp_reconnect(struct ppp_context_s *ctx) +{ + int ret; + int retry = PPP_MAX_CONNECT; + + netlib_ifdown((char*)ctx->ifname); + + lcp_disconnect(ctx, ++ctx->ppp_id); + sleep(1); + lcp_disconnect(ctx, ++ctx->ppp_id); + sleep(1); + write(ctx->tty_fd, "+++", 3); + sleep(2); + write(ctx->tty_fd, "ATE1\r\n", 6); + + if (ctx->disconnect_script) + { + ret = ppp_chat(ctx->tty_fd, ctx->disconnect_script, 1 /*echo on*/); + if (ret < 0) + { + printf("ppp: disconnect script failed\n"); + } + } + + if (ctx->connect_script) + { + do + { + ret = ppp_chat(ctx->tty_fd, ctx->connect_script, 1 /*echo on*/); + if (ret < 0) + { + printf("ppp: connect script failed\n"); + --retry; + if (retry == 0) + { + retry = PPP_MAX_CONNECT; +#if PPP_ARCH_HAVE_MODEM_RESET + ppp_arch_modem_reset((char*)ctx->ttyname); +#endif + sleep(45); + } + else + { + sleep(10); + } + } + } + while (ret != 0); + } + + ppp_init(ctx); + ppp_connect(ctx); + + ctx->ip_len = 0; +} + +/**************************************************************************** + * Name: ppp_arch_clock_seconds + ****************************************************************************/ + +time_t ppp_arch_clock_seconds(void) +{ + struct timespec ts; + + if (clock_gettime(CLOCK_MONOTONIC, &ts) < 0) + { + return 0; + } + + return ts.tv_sec; +} + +/**************************************************************************** + * Name: ppp_arch_getchar + ****************************************************************************/ + +int ppp_arch_getchar(struct ppp_context_s *ctx, u8_t *c) +{ + int ret; + ret = read(ctx->tty_fd, c, 1); + return ret == 1 ? ret : 0; +} + +/**************************************************************************** + * Name: ppp_arch_putchar + ****************************************************************************/ + +int ppp_arch_putchar(struct ppp_context_s *ctx, u8_t c) +{ + int ret; + struct pollfd fds; + + ret = write(ctx->tty_fd, &c, 1); + if (ret < 0 && errno == EAGAIN) + { + fds.fd = ctx->tty_fd; + fds.events = POLLOUT; + fds.revents = 0; + + ret = poll(&fds, 1, 1000); + if (ret > 0) + { + ret = write(ctx->tty_fd, &c, 1); + } + } + + return ret == 1 ? ret : 0; +} + +/**************************************************************************** + * Name: pppd_main + ****************************************************************************/ + +int pppd_main(int argc, char **argv) +{ + struct pollfd fds[2]; + int ret; + struct ppp_context_s *ctx; + + ctx = (struct ppp_context_s*)malloc(sizeof(struct ppp_context_s)); + memset(ctx, 0, sizeof(struct ppp_context_s)); + + strcpy((char*)ctx->pap_username, PAP_USERNAME); + strcpy((char*)ctx->pap_password, PAP_PASSWORD); + strcpy((char*)ctx->ifname, "ppp%d"); + strcpy((char*)ctx->ttyname, "/dev/ttyS2"); + + ctx->connect_script = &connect_script; + ctx->disconnect_script = &disconnect_script; + + ctx->if_fd = tun_alloc((char*)ctx->ifname); + if (ctx->if_fd < 0) + { + free(ctx); + return 2; + } + + ctx->tty_fd = open_tty((char*)ctx->ttyname); + if (ctx->tty_fd < 0) + { + close(ctx->tty_fd); + free(ctx); + return 2; + } + + fds[0].fd = ctx->if_fd; + fds[0].events = POLLIN; + + fds[1].fd = ctx->tty_fd; + fds[1].events = POLLIN; + + ppp_init(ctx); + ppp_reconnect(ctx); + + while (1) + { + fds[0].revents = fds[1].revents = 0; + + ret = poll(fds, 2, 1000); + + if (ret > 0 && fds[0].revents & POLLIN) + { + ret = read(ctx->if_fd, ctx->ip_buf, PPP_RX_BUFFER_SIZE); + printf("read from tun :%i\n", ret); + if (ret > 0) + { + ctx->ip_len = ret; + ppp_send(ctx); + ctx->ip_len = 0; + } + } + + ppp_poll(ctx); + + if (ppp_check_errors(ctx)) + { + ppp_reconnect(ctx); + } + else + { + if (ctx->ip_len > 0) + { + ret = write(ctx->if_fd, ctx->ip_buf, ctx->ip_len); + //printf("write to tun :%i\n", ret); + ctx->ip_len = 0; + + ret = read(ctx->if_fd, ctx->ip_buf, PPP_RX_BUFFER_SIZE); + //printf("read (after write) from tun :%i\n", ret); + if (ret > 0) + { + ctx->ip_len = ret; + ppp_send(ctx); + ctx->ip_len = 0; + } + } + } + } + + return 1; +}