/** * Perform Sanity check of user-configurable values, and initialize all modules. */ void lwip_init(void) { esp_ms_timer_init(); // espressif /* Modules initialization */ stats_init(); #if !NO_SYS sys_init(); #endif /* !NO_SYS */ mem_init(); memp_init(); pbuf_init(); netif_init(); #if LWIP_IPV4 ip_init(); #if LWIP_ARP etharp_init(); #endif /* LWIP_ARP */ #endif /* LWIP_IPV4 */ #if LWIP_RAW raw_init(); #endif /* LWIP_RAW */ #if LWIP_UDP udp_init(); #endif /* LWIP_UDP */ #if LWIP_TCP tcp_init(); #endif /* LWIP_TCP */ #if LWIP_SNMP snmp_init(); #endif /* LWIP_SNMP */ #if LWIP_AUTOIP autoip_init(); #endif /* LWIP_AUTOIP */ #if LWIP_IGMP igmp_init(); #endif /* LWIP_IGMP */ #if LWIP_DNS dns_init(); #endif /* LWIP_DNS */ #if LWIP_IPV6 ip6_init(); nd6_init(); #if LWIP_IPV6_MLD mld6_init(); #endif /* LWIP_IPV6_MLD */ #endif /* LWIP_IPV6 */ #if PPP_SUPPORT ppp_init(); #endif #if LWIP_TIMERS sys_timeouts_init(); #endif /* LWIP_TIMERS */ }
/* bind for PPP */ static int pppoe_session_bind_ppp(pppoe_session *_this) { int len; npppd_ppp *ppp; struct sockaddr_dl sdl; ppp = NULL; if ((ppp = ppp_create()) == NULL) goto fail; PPPOE_SESSION_ASSERT(_this->ppp == NULL); if (_this->ppp != NULL) return -1; _this->ppp = ppp; ppp->tunnel_type = PPP_TUNNEL_PPPOE; ppp->phy_context = _this; ppp->send_packet = pppoe_session_ppp_output; ppp->phy_close = pppoe_session_close_by_ppp; strlcpy(ppp->phy_label, PPPOE_SESSION_LISTENER_LABEL(_this), sizeof(ppp->phy_label)); memset(&sdl, 0, sizeof(sdl)); sdl.sdl_len = sizeof(sdl); sdl.sdl_family = AF_LINK; len = strlen(pppoe_session_listen_ifname(_this)); memcpy(sdl.sdl_data, pppoe_session_listen_ifname(_this), len); sdl.sdl_nlen = len; sdl.sdl_alen = ETHER_ADDR_LEN; memcpy(sdl.sdl_data + len, _this->ether_addr, ETHER_ADDR_LEN); memcpy(&ppp->phy_info.peer_dl, &sdl, sizeof(sdl)); if (ppp_init(npppd_get_npppd(), ppp) != 0) goto fail; ppp->has_acf = 0; pppoe_session_log(_this, LOG_NOTICE, "logtype=PPPBind ppp=%d", ppp->id); ppp_start(ppp); return 0; fail: pppoe_session_log(_this, LOG_ERR, "failed binding ppp"); if (ppp != NULL) ppp_destroy(ppp); _this->ppp = NULL; return 1; }
void ppp_reconnect(struct ppp_context_s *ctx) { int ret; int retry = PPP_MAX_CONNECT; struct pppd_settings_s *pppd_settings = ctx->settings; netlib_ifdown((char*)ctx->ifname); lcp_disconnect(ctx, ++ctx->ppp_id); sleep(1); lcp_disconnect(ctx, ++ctx->ppp_id); sleep(1); write(ctx->ctl.fd, "+++", 3); sleep(2); write(ctx->ctl.fd, "ATE1\r\n", 6); if (pppd_settings->disconnect_script) { ret = chat(&ctx->ctl, pppd_settings->disconnect_script); if (ret < 0) { printf("ppp: disconnect script failed\n"); } } if (pppd_settings->connect_script) { do { ret = chat(&ctx->ctl, pppd_settings->connect_script); if (ret < 0) { printf("ppp: connect script failed\n"); --retry; if (retry == 0) { retry = PPP_MAX_CONNECT; #ifdef PPP_ARCH_HAVE_MODEM_RESET ppp_arch_modem_reset(pppd_settings->ttyname); #endif sleep(45); } else { sleep(10); } } } while (ret != 0); } ppp_init(ctx); ppp_connect(ctx); ctx->ip_len = 0; }
/* bind() for ppp */ static int pptp_call_bind_ppp(pptp_call *_this) { npppd_ppp *ppp; ppp = NULL; if ((ppp = ppp_create()) == NULL) goto fail; PPTP_CALL_ASSERT(_this->ppp == NULL); if (_this->ppp != NULL) return -1; _this->ppp = ppp; ppp->phy_context = _this; ppp->tunnel_type = NPPPD_TUNNEL_PPTP; ppp->send_packet = pptp_call_ppp_output; ppp->phy_close = pptp_call_closed_by_ppp; strlcpy(ppp->phy_label, PPTP_CTRL_LISTENER_TUN_NAME(_this->ctrl), sizeof(ppp->phy_label)); PPTP_CALL_ASSERT(sizeof(ppp->phy_info) >= _this->ctrl->peer.ss_len); memcpy(&ppp->phy_info, &_this->ctrl->peer, MIN(sizeof(ppp->phy_info), _this->ctrl->peer.ss_len)); if (ppp_init(npppd_get_npppd(), ppp) != 0) goto fail; pptp_call_log(_this, LOG_NOTICE, "logtype=PPPBind ppp=%d", ppp->id); ppp_start(ppp); return 0; fail: pptp_call_log(_this, LOG_ERR, "failed binding ppp"); if (ppp != NULL) ppp_destroy(ppp); _this->ppp = NULL; return 1; }
PACK_STRUCT_END #ifdef PACK_STRUCT_USE_INCLUDES # include "arch/epstruct.h" #endif #define PACKED_STRUCT_TEST_EXPECTED_SIZE 5 #endif /* Compile-time sanity checks for configuration errors. * These can be done independently of LWIP_DEBUG, without penalty. */ #ifndef BYTE_ORDER #error "BYTE_ORDER is not defined, you have to define it in your cc.h" #endif #if (!IP_SOF_BROADCAST && IP_SOF_BROADCAST_RECV) #error "If you want to use broadcast filter per pcb on recv operations, you have to define IP_SOF_BROADCAST=1 in your lwipopts.h" #endif #if (!LWIP_UDP && LWIP_UDPLITE) #error "If you want to use UDP Lite, you have to define LWIP_UDP=1 in your lwipopts.h" #endif #if (!LWIP_UDP && LWIP_DHCP) #error "If you want to use DHCP, you have to define LWIP_UDP=1 in your lwipopts.h" #endif #if (!LWIP_UDP && LWIP_MULTICAST_TX_OPTIONS) #error "If you want to use IGMP/LWIP_MULTICAST_TX_OPTIONS, you have to define LWIP_UDP=1 in your lwipopts.h" #endif #if (!LWIP_UDP && LWIP_DNS) #error "If you want to use DNS, you have to define LWIP_UDP=1 in your lwipopts.h" #endif #if !MEMP_MEM_MALLOC /* MEMP_NUM_* checks are disabled when not using the pool allocator */ #if (LWIP_ARP && ARP_QUEUEING && (MEMP_NUM_ARP_QUEUE<=0)) #error "If you want to use ARP Queueing, you have to define MEMP_NUM_ARP_QUEUE>=1 in your lwipopts.h" #endif #if (LWIP_RAW && (MEMP_NUM_RAW_PCB<=0)) #error "If you want to use RAW, you have to define MEMP_NUM_RAW_PCB>=1 in your lwipopts.h" #endif #if (LWIP_UDP && (MEMP_NUM_UDP_PCB<=0)) #error "If you want to use UDP, you have to define MEMP_NUM_UDP_PCB>=1 in your lwipopts.h" #endif #if (LWIP_TCP && (MEMP_NUM_TCP_PCB<=0)) #error "If you want to use TCP, you have to define MEMP_NUM_TCP_PCB>=1 in your lwipopts.h" #endif #if (LWIP_IGMP && (MEMP_NUM_IGMP_GROUP<=1)) #error "If you want to use IGMP, you have to define MEMP_NUM_IGMP_GROUP>1 in your lwipopts.h" #endif #if (LWIP_IGMP && !LWIP_MULTICAST_TX_OPTIONS) #error "If you want to use IGMP, you have to define LWIP_MULTICAST_TX_OPTIONS==1 in your lwipopts.h" #endif #if (LWIP_IGMP && !LWIP_IPV4) #error "IGMP needs LWIP_IPV4 enabled in your lwipopts.h" #endif #if (LWIP_MULTICAST_TX_OPTIONS && !LWIP_IPV4) #error "LWIP_MULTICAST_TX_OPTIONS needs LWIP_IPV4 enabled in your lwipopts.h" #endif #if ((LWIP_NETCONN || LWIP_SOCKET) && (MEMP_NUM_TCPIP_MSG_API<=0)) #error "If you want to use Sequential API, you have to define MEMP_NUM_TCPIP_MSG_API>=1 in your lwipopts.h" #endif /* There must be sufficient timeouts, taking into account requirements of the subsystems. */ #if LWIP_TIMERS && (MEMP_NUM_SYS_TIMEOUT < (LWIP_TCP + IP_REASSEMBLY + LWIP_ARP + (2*LWIP_DHCP) + LWIP_AUTOIP + LWIP_IGMP + LWIP_DNS + PPP_SUPPORT + (LWIP_IPV6 ? (1 + LWIP_IPV6_REASS + LWIP_IPV6_MLD) : 0))) #error "MEMP_NUM_SYS_TIMEOUT is too low to accomodate all required timeouts" #endif #if (IP_REASSEMBLY && (MEMP_NUM_REASSDATA > IP_REASS_MAX_PBUFS)) #error "MEMP_NUM_REASSDATA > IP_REASS_MAX_PBUFS doesn't make sense since each struct ip_reassdata must hold 2 pbufs at least!" #endif #endif /* !MEMP_MEM_MALLOC */ #if LWIP_WND_SCALE #if (LWIP_TCP && (TCP_WND > 0xffffffff)) #error "If you want to use TCP, TCP_WND must fit in an u32_t, so, you have to reduce it in your lwipopts.h" #endif #if (LWIP_TCP && LWIP_WND_SCALE && (TCP_RCV_SCALE > 14)) #error "The maximum valid window scale value is 14!" #endif #if (LWIP_TCP && (TCP_WND > (0xFFFFU << TCP_RCV_SCALE))) #error "TCP_WND is bigger than the configured LWIP_WND_SCALE allows!" #endif #if (LWIP_TCP && ((TCP_WND >> TCP_RCV_SCALE) == 0)) #error "TCP_WND is too small for the configured LWIP_WND_SCALE (results in zero window)!" #endif #else /* LWIP_WND_SCALE */ #if (LWIP_TCP && (TCP_WND > 0xffff)) #error "If you want to use TCP, TCP_WND must fit in an u16_t, so, you have to reduce it in your lwipopts.h (or enable window scaling)" #endif #endif /* LWIP_WND_SCALE */ #if (LWIP_TCP && (TCP_SND_QUEUELEN > 0xffff)) #error "If you want to use TCP, TCP_SND_QUEUELEN must fit in an u16_t, so, you have to reduce it in your lwipopts.h" #endif #if (LWIP_TCP && (TCP_SND_QUEUELEN < 2)) #error "TCP_SND_QUEUELEN must be at least 2 for no-copy TCP writes to work" #endif #if (LWIP_TCP && ((TCP_MAXRTX > 12) || (TCP_SYNMAXRTX > 12))) #error "If you want to use TCP, TCP_MAXRTX and TCP_SYNMAXRTX must less or equal to 12 (due to tcp_backoff table), so, you have to reduce them in your lwipopts.h" #endif #if (LWIP_TCP && TCP_LISTEN_BACKLOG && ((TCP_DEFAULT_LISTEN_BACKLOG < 0) || (TCP_DEFAULT_LISTEN_BACKLOG > 0xff))) #error "If you want to use TCP backlog, TCP_DEFAULT_LISTEN_BACKLOG must fit into an u8_t" #endif #if (LWIP_NETIF_API && (NO_SYS==1)) #error "If you want to use NETIF API, you have to define NO_SYS=0 in your lwipopts.h" #endif #if ((LWIP_SOCKET || LWIP_NETCONN) && (NO_SYS==1)) #error "If you want to use Sequential API, you have to define NO_SYS=0 in your lwipopts.h" #endif #if (LWIP_PPP_API && (NO_SYS==1)) #error "If you want to use PPP API, you have to define NO_SYS=0 in your lwipopts.h" #endif #if (LWIP_PPP_API && (PPP_SUPPORT==0)) #error "If you want to use PPP API, you have to enable PPP_SUPPORT in your lwipopts.h" #endif #if (((!LWIP_DHCP) || (!LWIP_AUTOIP)) && LWIP_DHCP_AUTOIP_COOP) #error "If you want to use DHCP/AUTOIP cooperation mode, you have to define LWIP_DHCP=1 and LWIP_AUTOIP=1 in your lwipopts.h" #endif #if (((!LWIP_DHCP) || (!LWIP_ARP)) && DHCP_DOES_ARP_CHECK) #error "If you want to use DHCP ARP checking, you have to define LWIP_DHCP=1 and LWIP_ARP=1 in your lwipopts.h" #endif #if (!LWIP_ARP && LWIP_AUTOIP) #error "If you want to use AUTOIP, you have to define LWIP_ARP=1 in your lwipopts.h" #endif #if (LWIP_TCP && ((LWIP_EVENT_API && LWIP_CALLBACK_API) || (!LWIP_EVENT_API && !LWIP_CALLBACK_API))) #error "One and exactly one of LWIP_EVENT_API and LWIP_CALLBACK_API has to be enabled in your lwipopts.h" #endif #if (MEM_LIBC_MALLOC && MEM_USE_POOLS) #error "MEM_LIBC_MALLOC and MEM_USE_POOLS may not both be simultaneously enabled in your lwipopts.h" #endif #if (MEM_USE_POOLS && !MEMP_USE_CUSTOM_POOLS) #error "MEM_USE_POOLS requires custom pools (MEMP_USE_CUSTOM_POOLS) to be enabled in your lwipopts.h" #endif #if (PBUF_POOL_BUFSIZE <= MEM_ALIGNMENT) #error "PBUF_POOL_BUFSIZE must be greater than MEM_ALIGNMENT or the offset may take the full first pbuf" #endif #if (DNS_LOCAL_HOSTLIST && !DNS_LOCAL_HOSTLIST_IS_DYNAMIC && !(defined(DNS_LOCAL_HOSTLIST_INIT))) #error "you have to define define DNS_LOCAL_HOSTLIST_INIT {{'host1', 0x123}, {'host2', 0x234}} to initialize DNS_LOCAL_HOSTLIST" #endif #if PPP_SUPPORT && !PPPOS_SUPPORT && !PPPOE_SUPPORT && !PPPOL2TP_SUPPORT #error "PPP_SUPPORT needs at least one of PPPOS_SUPPORT, PPPOE_SUPPORT or PPPOL2TP_SUPPORT turned on" #endif #if PPP_SUPPORT && !PPP_IPV4_SUPPORT && !PPP_IPV6_SUPPORT #error "PPP_SUPPORT needs PPP_IPV4_SUPPORT and/or PPP_IPV6_SUPPORT turned on" #endif #if PPP_SUPPORT && PPP_IPV4_SUPPORT && !LWIP_IPV4 #error "PPP_IPV4_SUPPORT needs LWIP_IPV4 turned on" #endif #if PPP_SUPPORT && PPP_IPV6_SUPPORT && !LWIP_IPV6 #error "PPP_IPV6_SUPPORT needs LWIP_IPV6 turned on" #endif #if !LWIP_ETHERNET && (LWIP_ARP || PPPOE_SUPPORT) #error "LWIP_ETHERNET needs to be turned on for LWIP_ARP or PPPOE_SUPPORT" #endif #if (LWIP_IGMP || LWIP_IPV6) && !defined(LWIP_RAND) #error "When using IGMP or IPv6, LWIP_RAND() needs to be defined to a random-function returning an u32_t random value (in arch/cc.h)" #endif #if LWIP_TCPIP_CORE_LOCKING_INPUT && !LWIP_TCPIP_CORE_LOCKING #error "When using LWIP_TCPIP_CORE_LOCKING_INPUT, LWIP_TCPIP_CORE_LOCKING must be enabled, too" #endif #if LWIP_TCP && LWIP_NETIF_TX_SINGLE_PBUF && !TCP_OVERSIZE #error "LWIP_NETIF_TX_SINGLE_PBUF needs TCP_OVERSIZE enabled to create single-pbuf TCP packets" #endif #if LWIP_NETCONN && LWIP_TCP #if NETCONN_COPY != TCP_WRITE_FLAG_COPY #error "NETCONN_COPY != TCP_WRITE_FLAG_COPY" #endif #if NETCONN_MORE != TCP_WRITE_FLAG_MORE #error "NETCONN_MORE != TCP_WRITE_FLAG_MORE" #endif #endif /* LWIP_NETCONN && LWIP_TCP */ #if LWIP_SOCKET /* Check that the SO_* socket options and SOF_* lwIP-internal flags match */ #if SO_REUSEADDR != SOF_REUSEADDR #error "WARNING: SO_REUSEADDR != SOF_REUSEADDR" #endif #if SO_KEEPALIVE != SOF_KEEPALIVE #error "WARNING: SO_KEEPALIVE != SOF_KEEPALIVE" #endif #if SO_BROADCAST != SOF_BROADCAST #error "WARNING: SO_BROADCAST != SOF_BROADCAST" #endif #endif /* LWIP_SOCKET */ /* Compile-time checks for deprecated options. */ #ifdef MEMP_NUM_TCPIP_MSG #error "MEMP_NUM_TCPIP_MSG option is deprecated. Remove it from your lwipopts.h." #endif #ifdef TCP_REXMIT_DEBUG #error "TCP_REXMIT_DEBUG option is deprecated. Remove it from your lwipopts.h." #endif #ifdef RAW_STATS #error "RAW_STATS option is deprecated. Remove it from your lwipopts.h." #endif #ifdef ETHARP_QUEUE_FIRST #error "ETHARP_QUEUE_FIRST option is deprecated. Remove it from your lwipopts.h." #endif #ifdef ETHARP_ALWAYS_INSERT #error "ETHARP_ALWAYS_INSERT option is deprecated. Remove it from your lwipopts.h." #endif #if !NO_SYS && LWIP_TCPIP_CORE_LOCKING && LWIP_COMPAT_MUTEX && !defined(LWIP_COMPAT_MUTEX_ALLOWED) #error "LWIP_COMPAT_MUTEX cannot prevent priority inversion. It is recommended to implement priority-aware mutexes. (Define LWIP_COMPAT_MUTEX_ALLOWED to disable this error.)" #endif #ifndef LWIP_DISABLE_TCP_SANITY_CHECKS #define LWIP_DISABLE_TCP_SANITY_CHECKS 0 #endif #ifndef LWIP_DISABLE_MEMP_SANITY_CHECKS #define LWIP_DISABLE_MEMP_SANITY_CHECKS 0 #endif /* MEMP sanity checks */ #if MEMP_MEM_MALLOC #if !LWIP_DISABLE_MEMP_SANITY_CHECKS #if LWIP_NETCONN || LWIP_SOCKET #if !MEMP_NUM_NETCONN && LWIP_SOCKET #error "lwip_sanity_check: WARNING: MEMP_NUM_NETCONN cannot be 0 when using sockets!" #endif #else /* MEMP_MEM_MALLOC */ #if MEMP_NUM_NETCONN > (MEMP_NUM_TCP_PCB+MEMP_NUM_TCP_PCB_LISTEN+MEMP_NUM_UDP_PCB+MEMP_NUM_RAW_PCB) #error "lwip_sanity_check: WARNING: MEMP_NUM_NETCONN should be less than the sum of MEMP_NUM_{TCP,RAW,UDP}_PCB+MEMP_NUM_TCP_PCB_LISTEN. If you know what you are doing, define LWIP_DISABLE_MEMP_SANITY_CHECKS to 1 to disable this error." #endif #endif /* LWIP_NETCONN || LWIP_SOCKET */ #endif /* !LWIP_DISABLE_MEMP_SANITY_CHECKS */ #if MEM_USE_POOLS #error "MEMP_MEM_MALLOC and MEM_USE_POOLS cannot be enabled at the same time" #endif #ifdef LWIP_HOOK_MEMP_AVAILABLE #error "LWIP_HOOK_MEMP_AVAILABLE doesn't make sense with MEMP_MEM_MALLOC" #endif #endif /* MEMP_MEM_MALLOC */ /* TCP sanity checks */ #if !LWIP_DISABLE_TCP_SANITY_CHECKS #if LWIP_TCP #if !MEMP_MEM_MALLOC && (MEMP_NUM_TCP_SEG < TCP_SND_QUEUELEN) #error "lwip_sanity_check: WARNING: MEMP_NUM_TCP_SEG should be at least as big as TCP_SND_QUEUELEN. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." #endif #if TCP_SND_BUF < (2 * TCP_MSS) #error "lwip_sanity_check: WARNING: TCP_SND_BUF must be at least as much as (2 * TCP_MSS) for things to work smoothly. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." #endif #if TCP_SND_QUEUELEN < (2 * (TCP_SND_BUF / TCP_MSS)) #error "lwip_sanity_check: WARNING: TCP_SND_QUEUELEN must be at least as much as (2 * TCP_SND_BUF/TCP_MSS) for things to work. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." #endif #if TCP_SNDLOWAT >= TCP_SND_BUF #error "lwip_sanity_check: WARNING: TCP_SNDLOWAT must be less than TCP_SND_BUF. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." #endif #if TCP_SNDLOWAT >= (0xFFFF - (4 * TCP_MSS)) #error "lwip_sanity_check: WARNING: TCP_SNDLOWAT must at least be 4*MSS below u16_t overflow!" #endif #if TCP_SNDQUEUELOWAT >= TCP_SND_QUEUELEN #error "lwip_sanity_check: WARNING: TCP_SNDQUEUELOWAT must be less than TCP_SND_QUEUELEN. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." #endif #if !MEMP_MEM_MALLOC && PBUF_POOL_SIZE && (PBUF_POOL_BUFSIZE <= (PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN)) #error "lwip_sanity_check: WARNING: PBUF_POOL_BUFSIZE does not provide enough space for protocol headers. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." #endif #if !MEMP_MEM_MALLOC && PBUF_POOL_SIZE && (TCP_WND > (PBUF_POOL_SIZE * (PBUF_POOL_BUFSIZE - (PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN)))) #error "lwip_sanity_check: WARNING: TCP_WND is larger than space provided by PBUF_POOL_SIZE * (PBUF_POOL_BUFSIZE - protocol headers). If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." #endif #if TCP_WND < TCP_MSS #error "lwip_sanity_check: WARNING: TCP_WND is smaller than MSS. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." #endif #endif /* LWIP_TCP */ #endif /* !LWIP_DISABLE_TCP_SANITY_CHECKS */ /** * @ingroup lwip_nosys * Initialize all modules. * Use this in NO_SYS mode. Use tcpip_init() otherwise. */ void lwip_init(void) { #ifndef LWIP_SKIP_PACKING_CHECK LWIP_ASSERT("Struct packing not implemented correctly. Check your lwIP port.", sizeof(struct packed_struct_test) == PACKED_STRUCT_TEST_EXPECTED_SIZE); #endif /* Modules initialization */ stats_init(); #if !NO_SYS sys_init(); #endif /* !NO_SYS */ mem_init(); memp_init(); pbuf_init(); netif_init(); #if LWIP_IPV4 ip_init(); #if LWIP_ARP etharp_init(); #endif /* LWIP_ARP */ #endif /* LWIP_IPV4 */ #if LWIP_RAW raw_init(); #endif /* LWIP_RAW */ #if LWIP_UDP udp_init(); #endif /* LWIP_UDP */ #if LWIP_TCP tcp_init(); #endif /* LWIP_TCP */ #if LWIP_IGMP igmp_init(); #endif /* LWIP_IGMP */ #if LWIP_DNS dns_init(); #endif /* LWIP_DNS */ #if PPP_SUPPORT ppp_init(); #endif #if LWIP_TIMERS sys_timeouts_init(); #endif /* LWIP_TIMERS */ }
void main_thread_entry(cyg_addrword_t p) { CYG_TEST_INFO("Initializing lwIP"); cyg_lwip_simple_init(); test_state = TEST_CHAT_INIT; req_state = REQ_DNS_INIT; while (1) { cyg_lwip_simple_poll(); switch (test_state) { case TEST_INITIAL: diag_printf("INFO:<Starting test run (%d/%d)>\n", run, NUM_RUNS); test_state = TEST_CHAT_INIT; break; case TEST_CHAT_INIT: CYG_TEST_INFO("Initializing chat"); sd = sio_open(SIO_DEV_PPPOS); if (!sd) CYG_TEST_FAIL_FINISH("Cannot open serial"); chat = chat_new(sd, chat_items, CHAT_TIMEOUT, chat_cb, chat_send_cb, NULL); if (!chat) CYG_TEST_FAIL_FINISH("Cannot allocate chat"); test_state = TEST_CHAT_RUN; break; case TEST_CHAT_RUN: chat_poll(chat); break; case TEST_CHAT_FINISH: chat_free(chat); if (chat_ok) test_state = TEST_PPP_INIT; else test_state = TEST_NEXT_RUN; break; case TEST_PPP_INIT: CYG_TEST_INFO("Initializing PPP"); if (ppp_init() != ERR_OK) CYG_TEST_FAIL_FINISH("Cannot initialize PPP"); pd = ppp_open_serial(sd, ppp_status_cb, (void *) pd); if (pd < 0) CYG_TEST_FAIL_FINISH("Cannot open PPP over serial"); ppp_set_auth(PPPAUTHTYPE_ANY, CYGDAT_NET_LWIP_PPP_TEST_USERNAME, CYGDAT_NET_LWIP_PPP_TEST_PASSWORD); test_state = TEST_PPP_INIT_WAIT; break; case TEST_PPP_INIT_WAIT: ppp_poll(pd); break; case TEST_PPP_UP: ppp_poll(pd); handle_req_state(); break; case TEST_PPP_CLOSE: ppp_close(pd); test_state = TEST_PPP_CLOSE_WAIT; break; case TEST_PPP_CLOSE_WAIT: ppp_poll(pd); if (!ppp_is_open(pd)) // Escape from data mode sio_write(sd, (u8_t *) "+++", 3); cyg_thread_delay(200); test_state = TEST_NEXT_RUN; break; case TEST_NEXT_RUN: if (run < NUM_RUNS) { run++; test_state = TEST_INITIAL; } else { test_state = TEST_FINISH; } break; case TEST_FINISH: test_state = TEST_CHAT_INIT; diag_printf("INFO:<Test done (%d/%d) successful runs\n", success, NUM_RUNS); break; } cyg_thread_yield(); } }
/* bind ppp */ static int l2tp_call_bind_ppp(l2tp_call *_this, dialin_proxy_info *dpi) { int code, errcode; npppd_ppp *ppp; code = L2TP_CDN_RCODE_BUSY; errcode = 0; ppp = NULL; if ((ppp = ppp_create()) == NULL) goto fail; ASSERT(_this->ppp == NULL); if (_this->ppp != NULL) return -1; _this->ppp = ppp; ppp->tunnel_type = NPPPD_TUNNEL_L2TP; ppp->phy_context = _this; ppp->send_packet = l2tp_call_ppp_output; ppp->phy_close = l2tp_call_closed_by_ppp; strlcpy(ppp->phy_label, L2TP_CTRL_LISTENER_TUN_NAME(_this->ctrl), sizeof(ppp->phy_label)); L2TP_CALL_ASSERT(sizeof(ppp->phy_info) >= _this->ctrl->peer.ss_len); memcpy(&ppp->phy_info, &_this->ctrl->peer, MIN(sizeof(ppp->phy_info), _this->ctrl->peer.ss_len)); strlcpy(ppp->calling_number, _this->calling_number, sizeof(ppp->calling_number)); if (ppp_init(npppd_get_npppd(), ppp) != 0) { l2tp_call_log(_this, LOG_ERR, "failed binding ppp"); goto fail; } l2tp_call_log(_this, LOG_NOTICE, "logtype=PPPBind ppp=%d", ppp->id); if (DIALIN_PROXY_IS_REQUESTED(dpi)) { if (!L2TP_CTRL_CONF(_this->ctrl)->accept_dialin) { l2tp_call_log(_this, LOG_ERR, "'accept_dialin' is 'false' in the setting."); code = L2TP_CDN_RCODE_ERROR_CODE; errcode = L2TP_ECODE_INVALID_MESSAGE; goto fail; } if (ppp_dialin_proxy_prepare(ppp, dpi) != 0) { code = L2TP_CDN_RCODE_TEMP_NOT_AVALIABLE; goto fail; } } ppp_start(ppp); return 0; fail: if (ppp != NULL) ppp_destroy(ppp); _this->ppp = NULL; l2tp_call_disconnect(_this, code, 0, NULL, NULL, 0); return 1; }
static int send_pptp_start_ctrl_conn_rply(struct pptp_conn_t *conn, int res_code, int err_code) { struct pptp_start_ctrl_conn msg = { .header = PPTP_HEADER_CTRL(PPTP_START_CTRL_CONN_RPLY), .version = htons(PPTP_VERSION), .result_code = res_code, .error_code = err_code, .framing_cap = htonl(3), .bearer_cap = htonl(3), .max_channels = htons(1), .firmware_rev = htons(PPTP_FIRMWARE_VERSION), }; memset(msg.hostname, 0, sizeof(msg.hostname)); strcpy((char*)msg.hostname, PPTP_HOSTNAME); memset(msg.vendor, 0, sizeof(msg.vendor)); strcpy((char*)msg.vendor, PPTP_VENDOR); if (conf_verbose) log_ppp_info2("send [PPTP Start-Ctrl-Conn-Reply <Version %i> <Result %i> <Error %i> <Framing %x> <Bearer %x> <Max-Chan %i>]\n", msg.version, msg.result_code, msg.error_code, ntohl(msg.framing_cap), ntohl(msg.bearer_cap), ntohs(msg.max_channels)); return post_msg(conn, &msg, sizeof(msg)); } static int pptp_start_ctrl_conn_rqst(struct pptp_conn_t *conn) { struct pptp_start_ctrl_conn *msg = (struct pptp_start_ctrl_conn *)conn->in_buf; if (conf_verbose) log_ppp_info2("recv [PPTP Start-Ctrl-Conn-Request <Version %i> <Framing %x> <Bearer %x> <Max-Chan %i>]\n", msg->version, ntohl(msg->framing_cap), ntohl(msg->bearer_cap), ntohs(msg->max_channels)); if (conn->state != STATE_IDLE) { log_ppp_warn("unexpected PPTP_START_CTRL_CONN_RQST\n"); if (send_pptp_start_ctrl_conn_rply(conn, PPTP_CONN_RES_EXISTS, 0)) return -1; return 0; } if (msg->version != htons(PPTP_VERSION)) { log_ppp_warn("PPTP version mismatch: expecting %x, received %s\n", PPTP_VERSION, msg->version); if (send_pptp_start_ctrl_conn_rply(conn, PPTP_CONN_RES_PROTOCOL, 0)) return -1; return 0; } /*if (!(ntohl(msg->framing_cap) & PPTP_FRAME_SYNC)) { log_ppp_warn("connection does not supports sync mode\n"); if (send_pptp_start_ctrl_conn_rply(conn, PPTP_CONN_RES_GE, 0)) return -1; return 0; }*/ if (send_pptp_start_ctrl_conn_rply(conn, PPTP_CONN_RES_SUCCESS, 0)) return -1; triton_timer_mod(&conn->timeout_timer, 0); conn->state = STATE_ESTB; return 0; } static int send_pptp_out_call_rply(struct pptp_conn_t *conn, struct pptp_out_call_rqst *rqst, int call_id, int res_code, int err_code) { struct pptp_out_call_rply msg = { .header = PPTP_HEADER_CTRL(PPTP_OUT_CALL_RPLY), .call_id = htons(call_id), .call_id_peer = rqst->call_id, .result_code = res_code, .error_code = err_code, .cause_code = 0, .speed = rqst->bps_max, .recv_size = rqst->recv_size, .delay = 0, .channel = 0, }; if (conf_verbose) log_ppp_info2("send [PPTP Outgoing-Call-Reply <Call-ID %x> <Peer-Call-ID %x> <Result %i> <Error %i> <Cause %i> <Speed %i> <Window-Size %i> <Delay %i> <Channel %x>]\n", ntohs(msg.call_id), ntohs(msg.call_id_peer), msg.result_code, msg.error_code, ntohs(msg.cause_code), ntohl(msg.speed), ntohs(msg.recv_size), ntohs(msg.delay), ntohl(msg.channel)); return post_msg(conn, &msg, sizeof(msg)); } static int pptp_out_call_rqst(struct pptp_conn_t *conn) { struct pptp_out_call_rqst *msg = (struct pptp_out_call_rqst *)conn->in_buf; struct sockaddr_pppox src_addr, dst_addr; struct sockaddr_in addr; socklen_t addrlen; int pptp_sock; if (conf_verbose) log_ppp_info2("recv [PPTP Outgoing-Call-Request <Call-ID %x> <Call-Serial %x> <Min-BPS %i> <Max-BPS %i> <Bearer %x> <Framing %x> <Window-Size %i> <Delay %i>]\n", ntohs(msg->call_id), ntohs(msg->call_sernum), ntohl(msg->bps_min), ntohl(msg->bps_max), ntohl(msg->bearer), ntohl(msg->framing), ntohs(msg->recv_size), ntohs(msg->delay)); if (conn->state != STATE_ESTB) { log_ppp_warn("unexpected PPTP_OUT_CALL_RQST\n"); if (send_pptp_out_call_rply(conn, msg, 0, PPTP_CALL_RES_GE, PPTP_GE_NOCONN)) return -1; return 0; } memset(&src_addr, 0, sizeof(src_addr)); src_addr.sa_family = AF_PPPOX; src_addr.sa_protocol = PX_PROTO_PPTP; src_addr.sa_addr.pptp.call_id = 0; addrlen = sizeof(addr); getsockname(conn->hnd.fd, (struct sockaddr*)&addr, &addrlen); src_addr.sa_addr.pptp.sin_addr = addr.sin_addr; memset(&dst_addr, 0, sizeof(dst_addr)); dst_addr.sa_family = AF_PPPOX; dst_addr.sa_protocol = PX_PROTO_PPTP; dst_addr.sa_addr.pptp.call_id = htons(msg->call_id); addrlen = sizeof(addr); getpeername(conn->hnd.fd, (struct sockaddr*)&addr, &addrlen); dst_addr.sa_addr.pptp.sin_addr = addr.sin_addr; pptp_sock = socket(AF_PPPOX, SOCK_STREAM, PX_PROTO_PPTP); if (pptp_sock < 0) { log_ppp_error("failed to create PPTP socket (%s)\n", strerror(errno)); return -1; } fcntl(pptp_sock, F_SETFD, fcntl(pptp_sock, F_GETFD) | FD_CLOEXEC); if (bind(pptp_sock, (struct sockaddr*)&src_addr, sizeof(src_addr))) { log_ppp_error("failed to bind PPTP socket (%s)\n", strerror(errno)); close(pptp_sock); return -1; } addrlen = sizeof(src_addr); getsockname(pptp_sock, (struct sockaddr*)&src_addr, &addrlen); if (connect(pptp_sock, (struct sockaddr*)&dst_addr, sizeof(dst_addr))) { log_ppp_error("failed to connect PPTP socket (%s)\n", strerror(errno)); close(pptp_sock); return -1; } if (send_pptp_out_call_rply(conn, msg, src_addr.sa_addr.pptp.call_id, PPTP_CALL_RES_OK, 0)) return -1; conn->call_id = src_addr.sa_addr.pptp.call_id; conn->peer_call_id = msg->call_id; conn->ppp.fd = pptp_sock; conn->ppp.chan_name = _strdup(inet_ntoa(dst_addr.sa_addr.pptp.sin_addr)); triton_event_fire(EV_CTRL_STARTED, &conn->ppp); if (establish_ppp(&conn->ppp)) { close(pptp_sock); //if (send_pptp_stop_ctrl_conn_rqst(conn, 0, 0)) conn->state = STATE_FIN; return -1; } conn->state = STATE_PPP; __sync_sub_and_fetch(&stat_starting, 1); __sync_add_and_fetch(&stat_active, 1); if (conn->timeout_timer.tpd) triton_timer_del(&conn->timeout_timer); if (conf_echo_interval) { conn->echo_timer.period = conf_echo_interval * 1000; triton_timer_add(&conn->ctx, &conn->echo_timer, 0); } return 0; } static int send_pptp_call_disconnect_notify(struct pptp_conn_t *conn, int result) { struct pptp_call_clear_ntfy msg = { .header = PPTP_HEADER_CTRL(PPTP_CALL_CLEAR_NTFY), .call_id = htons(conn->peer_call_id), .result_code = result, .error_code = 0, .cause_code = 0, }; if (conf_verbose) log_ppp_info2("send [PPTP Call-Disconnect-Notify <Call-ID %x> <Result %i> <Error %i> <Cause %i>]\n", ntohs(msg.call_id), msg.result_code, msg.error_code, msg.cause_code); return post_msg(conn, &msg, sizeof(msg)); } static int pptp_call_clear_rqst(struct pptp_conn_t *conn) { struct pptp_call_clear_rqst *rqst = (struct pptp_call_clear_rqst *)conn->in_buf; if (conf_verbose) log_ppp_info2("recv [PPTP Call-Clear-Request <Call-ID %x>]\n", ntohs(rqst->call_id)); if (conn->echo_timer.tpd) triton_timer_del(&conn->echo_timer); if (conn->state == STATE_PPP) { __sync_sub_and_fetch(&stat_active, 1); conn->state = STATE_CLOSE; ppp_terminate(&conn->ppp, TERM_USER_REQUEST, 1); } return send_pptp_call_disconnect_notify(conn, 4); } static int pptp_echo_rqst(struct pptp_conn_t *conn) { struct pptp_echo_rqst *in_msg = (struct pptp_echo_rqst *)conn->in_buf; struct pptp_echo_rply out_msg = { .header = PPTP_HEADER_CTRL(PPTP_ECHO_RPLY), .identifier = in_msg->identifier, .result_code = 1, }; if (conf_verbose) { log_ppp_debug("recv [PPTP Echo-Request <Identifier %x>]\n", in_msg->identifier); log_ppp_debug("send [PPTP Echo-Reply <Identifier %x>]\n", out_msg.identifier); } return post_msg(conn, &out_msg, sizeof(out_msg)); } static int pptp_echo_rply(struct pptp_conn_t *conn) { struct pptp_echo_rply *msg = (struct pptp_echo_rply *)conn->in_buf; if (conf_verbose) log_ppp_debug("recv [PPTP Echo-Reply <Identifier %x>]\n", msg->identifier); /*if (msg->identifier != conn->echo_sent) { log_ppp_warn("pptp:echo: identifier mismatch\n"); //return -1; }*/ conn->echo_sent = 0; return 0; } static void pptp_send_echo(struct triton_timer_t *t) { struct pptp_conn_t *conn = container_of(t, typeof(*conn), echo_timer); struct pptp_echo_rqst msg = { .header = PPTP_HEADER_CTRL(PPTP_ECHO_RQST), }; if (++conn->echo_sent == conf_echo_failure) { log_ppp_warn("pptp: no echo reply\n"); disconnect(conn); return; } conn->echo_sent = random(); msg.identifier = conn->echo_sent; if (conf_verbose) log_ppp_debug("send [PPTP Echo-Request <Identifier %x>]\n", msg.identifier); if (post_msg(conn, &msg, sizeof(msg))) disconnect(conn); } static int process_packet(struct pptp_conn_t *conn) { struct pptp_header *hdr = (struct pptp_header *)conn->in_buf; switch(ntohs(hdr->ctrl_type)) { case PPTP_START_CTRL_CONN_RQST: return pptp_start_ctrl_conn_rqst(conn); case PPTP_STOP_CTRL_CONN_RQST: return pptp_stop_ctrl_conn_rqst(conn); case PPTP_STOP_CTRL_CONN_RPLY: return pptp_stop_ctrl_conn_rply(conn); case PPTP_OUT_CALL_RQST: return pptp_out_call_rqst(conn); case PPTP_ECHO_RQST: return pptp_echo_rqst(conn); case PPTP_ECHO_RPLY: return pptp_echo_rply(conn); case PPTP_CALL_CLEAR_RQST: return pptp_call_clear_rqst(conn); case PPTP_SET_LINK_INFO: if (conf_verbose) log_ppp_info2("recv [PPTP Set-Link-Info]\n"); return 0; default: log_ppp_warn("recv [PPTP Unknown (%x)]\n", ntohs(hdr->ctrl_type)); } return 0; } static int pptp_read(struct triton_md_handler_t *h) { struct pptp_conn_t *conn=container_of(h,typeof(*conn),hnd); struct pptp_header *hdr=(struct pptp_header *)conn->in_buf; int n; while(1) { n = read(h->fd, conn->in_buf + conn->in_size, PPTP_CTRL_SIZE_MAX - conn->in_size); if (n < 0) { if (errno == EINTR) continue; if (errno == EAGAIN) return 0; log_ppp_error("pptp: read: %s\n",strerror(errno)); goto drop; } if (n == 0) { if (conf_verbose) log_ppp_info2("pptp: disconnect by peer\n"); goto drop; } conn->in_size += n; if (conn->in_size >= sizeof(*hdr)) { if (hdr->magic != htonl(PPTP_MAGIC)) { log_ppp_error("pptp: invalid magic\n"); goto drop; } if (ntohs(hdr->length) >= PPTP_CTRL_SIZE_MAX) { log_ppp_error("pptp: message is too long\n"); goto drop; } if (ntohs(hdr->length) > conn->in_size) continue; if (ntohs(hdr->length) <= conn->in_size) { if (ntohs(hdr->length) != PPTP_CTRL_SIZE(ntohs(hdr->ctrl_type))) { log_ppp_error("pptp: invalid message length\n"); goto drop; } if (process_packet(conn)) goto drop; conn->in_size -= ntohs(hdr->length); if (conn->in_size) memmove(conn->in_buf, conn->in_buf + ntohs(hdr->length), conn->in_size); } } } drop: disconnect(conn); return 1; } static int pptp_write(struct triton_md_handler_t *h) { struct pptp_conn_t *conn = container_of(h, typeof(*conn), hnd); int n; while (1) { n = write(h->fd, conn->out_buf+conn->out_pos, conn->out_size-conn->out_pos); if (n < 0) { if (errno == EINTR) continue; if (errno == EAGAIN) n = 0; else { if (errno != EPIPE) { if (conf_verbose) log_ppp_info2("pptp: post_msg: %s\n", strerror(errno)); } disconnect(conn); return 1; } } conn->out_pos += n; if (conn->out_pos == conn->out_size) { conn->out_pos = 0; conn->out_size = 0; triton_md_disable_handler(h, MD_MODE_WRITE); return 0; } } } static void pptp_timeout(struct triton_timer_t *t) { struct pptp_conn_t *conn = container_of(t, typeof(*conn), timeout_timer); disconnect(conn); } static void pptp_close(struct triton_context_t *ctx) { struct pptp_conn_t *conn = container_of(ctx, typeof(*conn), ctx); if (conn->state == STATE_PPP) { __sync_sub_and_fetch(&stat_active, 1); conn->state = STATE_CLOSE; ppp_terminate(&conn->ppp, TERM_ADMIN_RESET, 1); if (send_pptp_call_disconnect_notify(conn, 3)) { triton_context_call(&conn->ctx, (void (*)(void*))disconnect, conn); return; } } else { if (send_pptp_stop_ctrl_conn_rqst(conn, 0)) { triton_context_call(&conn->ctx, (void (*)(void*))disconnect, conn); return; } } if (conn->timeout_timer.tpd) triton_timer_mod(&conn->timeout_timer, 0); else triton_timer_add(ctx, &conn->timeout_timer, 0); } static void ppp_started(struct ppp_t *ppp) { log_ppp_debug("pptp: ppp started\n"); } static void ppp_finished(struct ppp_t *ppp) { struct pptp_conn_t *conn = container_of(ppp, typeof(*conn), ppp); if (conn->state != STATE_CLOSE) { log_ppp_debug("pptp: ppp finished\n"); conn->state = STATE_CLOSE; __sync_sub_and_fetch(&stat_active, 1); if (send_pptp_call_disconnect_notify(conn, 3)) triton_context_call(&conn->ctx, (void (*)(void*))disconnect, conn); else if (send_pptp_stop_ctrl_conn_rqst(conn, 0)) triton_context_call(&conn->ctx, (void (*)(void*))disconnect, conn); else { if (conn->timeout_timer.tpd) triton_timer_mod(&conn->timeout_timer, 0); else triton_timer_add(&conn->ctx, &conn->timeout_timer, 0); } } } //================================== struct pptp_serv_t { struct triton_context_t ctx; struct triton_md_handler_t hnd; }; static int pptp_connect(struct triton_md_handler_t *h) { struct sockaddr_in addr; socklen_t size = sizeof(addr); int sock; struct pptp_conn_t *conn; while(1) { sock = accept(h->fd, (struct sockaddr *)&addr, &size); if (sock < 0) { if (errno == EAGAIN) return 0; log_error("pptp: accept failed: %s\n", strerror(errno)); continue; } if (ppp_shutdown) { close(sock); continue; } if (triton_module_loaded("connlimit") && connlimit_check(cl_key_from_ipv4(addr.sin_addr.s_addr))) { close(sock); return 0; } log_info2("pptp: new connection from %s\n", inet_ntoa(addr.sin_addr)); if (iprange_client_check(addr.sin_addr.s_addr)) { log_warn("pptp: IP is out of client-ip-range, droping connection...\n"); close(sock); continue; } if (fcntl(sock, F_SETFL, O_NONBLOCK)) { log_error("pptp: failed to set nonblocking mode: %s, closing connection...\n", strerror(errno)); close(sock); continue; } conn = mempool_alloc(conn_pool); memset(conn, 0, sizeof(*conn)); conn->hnd.fd = sock; conn->hnd.read = pptp_read; conn->hnd.write = pptp_write; conn->ctx.close = pptp_close; conn->ctx.before_switch = log_switch; conn->in_buf = _malloc(PPTP_CTRL_SIZE_MAX); conn->out_buf = _malloc(PPTP_CTRL_SIZE_MAX); conn->timeout_timer.expire = pptp_timeout; conn->timeout_timer.period = conf_timeout * 1000; conn->echo_timer.expire = pptp_send_echo; conn->ctrl.ctx = &conn->ctx; conn->ctrl.started = ppp_started; conn->ctrl.finished = ppp_finished; conn->ctrl.max_mtu = PPTP_MAX_MTU; conn->ctrl.type = CTRL_TYPE_PPTP; conn->ctrl.name = "pptp"; conn->ctrl.calling_station_id = _malloc(17); conn->ctrl.called_station_id = _malloc(17); u_inet_ntoa(addr.sin_addr.s_addr, conn->ctrl.calling_station_id); getsockname(sock, &addr, &size); u_inet_ntoa(addr.sin_addr.s_addr, conn->ctrl.called_station_id); ppp_init(&conn->ppp); conn->ppp.ctrl = &conn->ctrl; triton_context_register(&conn->ctx, &conn->ppp); triton_md_register_handler(&conn->ctx, &conn->hnd); triton_md_enable_handler(&conn->hnd,MD_MODE_READ); triton_timer_add(&conn->ctx, &conn->timeout_timer, 0); triton_context_wakeup(&conn->ctx); triton_event_fire(EV_CTRL_STARTING, &conn->ppp); __sync_add_and_fetch(&stat_starting, 1); } return 0; } static void pptp_serv_close(struct triton_context_t *ctx) { struct pptp_serv_t *s=container_of(ctx,typeof(*s),ctx); triton_md_unregister_handler(&s->hnd); close(s->hnd.fd); triton_context_unregister(ctx); } static struct pptp_serv_t serv= { .hnd.read = pptp_connect, .ctx.close = pptp_serv_close, .ctx.before_switch = log_switch, }; static int show_stat_exec(const char *cmd, char * const *fields, int fields_cnt, void *client) { cli_send(client, "pptp:\r\n"); cli_sendv(client," starting: %u\r\n", stat_starting); cli_sendv(client," active: %u\r\n", stat_active); return CLI_CMD_OK; } void __export pptp_get_stat(unsigned int **starting, unsigned int **active) { *starting = &stat_starting; *active = &stat_active; } static void load_config(void) { char *opt; opt = conf_get_opt("pptp", "timeout"); if (opt && atoi(opt) > 0) conf_timeout = atoi(opt); opt = conf_get_opt("pptp", "echo-interval"); if (opt && atoi(opt) >= 0) conf_echo_interval = atoi(opt); opt = conf_get_opt("pptp", "echo-failure"); if (opt && atoi(opt) > 0) conf_echo_failure = atoi(opt); opt = conf_get_opt("pptp", "verbose"); if (opt && atoi(opt) > 0) conf_verbose = 1; } static void pptp_init(void) { struct sockaddr_in addr; char *opt; system("modprobe pptp"); serv.hnd.fd = socket(PF_INET, SOCK_STREAM, 0); if (serv.hnd.fd < 0) { log_emerg("pptp: failed to create server socket: %s\n", strerror(errno)); return; } fcntl(serv.hnd.fd, F_SETFD, fcntl(serv.hnd.fd, F_GETFD) | FD_CLOEXEC); addr.sin_family = AF_INET; addr.sin_port = htons(PPTP_PORT); opt = conf_get_opt("pptp", "bind"); if (opt) addr.sin_addr.s_addr = inet_addr(opt); else addr.sin_addr.s_addr = htonl(INADDR_ANY); setsockopt(serv.hnd.fd, SOL_SOCKET, SO_REUSEADDR, &serv.hnd.fd, 4); if (bind (serv.hnd.fd, (struct sockaddr *) &addr, sizeof (addr)) < 0) { log_emerg("pptp: failed to bind socket: %s\n", strerror(errno)); close(serv.hnd.fd); return; } if (listen (serv.hnd.fd, 100) < 0) { log_emerg("pptp: failed to listen socket: %s\n", strerror(errno)); close(serv.hnd.fd); return; } if (fcntl(serv.hnd.fd, F_SETFL, O_NONBLOCK)) { log_emerg("pptp: failed to set nonblocking mode: %s\n", strerror(errno)); close(serv.hnd.fd); return; } conn_pool = mempool_create(sizeof(struct pptp_conn_t)); load_config(); triton_context_register(&serv.ctx, NULL); triton_md_register_handler(&serv.ctx, &serv.hnd); triton_md_enable_handler(&serv.hnd, MD_MODE_READ); triton_context_wakeup(&serv.ctx); cli_register_simple_cmd2(show_stat_exec, NULL, 2, "show", "stat"); triton_event_register_handler(EV_CONFIG_RELOAD, (triton_event_func)load_config); } DEFINE_INIT(20, pptp_init);
int pppd(struct pppd_settings_s *pppd_settings) { 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->ifname, "ppp%d"); ctx->settings = pppd_settings; ctx->if_fd = tun_alloc((char*)ctx->ifname); if (ctx->if_fd < 0) { free(ctx); return 2; } ctx->ctl.fd = open_tty(pppd_settings->ttyname); if (ctx->ctl.fd < 0) { close(ctx->ctl.fd); free(ctx); return 2; } ctx->ctl.echo = true; ctx->ctl.verbose = true; ctx->ctl.timeout = 30; fds[0].fd = ctx->if_fd; fds[0].events = POLLIN; fds[1].fd = ctx->ctl.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); ctx->ip_len = 0; ret = read(ctx->if_fd, ctx->ip_buf, PPP_RX_BUFFER_SIZE); if (ret > 0) { ctx->ip_len = ret; ppp_send(ctx); ctx->ip_len = 0; } } } } return 1; }
/*-----------------------------------------------------------------------------------*/ void maintask(void) { struct phybusif_cb *cb; CLKBLK ks_clk *tmr; u8_t bt_timer = 0; u16_t http_timer = 0; u16_t dma0bsz = TCR0+1; /* DMA 0 Buf size */ u8_t bt_ip_timer = 0; mem_init(); memp_init(); pbuf_init(); netif_init(); ip_init(); tcp_init(); sio_print("TCP/IP initialized.\n"); lwbt_memp_init(); phybusif_init(); if(hci_init() != ERR_OK) { sio_print("HCI initialization failed!"); } l2cap_init(); sdp_init(); rfcomm_init(); ppp_init(); sio_print("Bluetooth initialized.\n"); httpd_init(); sio_print("Applications started.\n"); cb = mem_malloc(sizeof(struct phybusif_cb)); cb->dmabuf = get_dm0ichars(); phybusif_reset(cb); tmr = KS_alloc_timer(); if(tmr == 0) { sio_print("tmr==0!\n"); } KS_start_timer(tmr, (TICKS)0, (TICKS)100/CLKTICK, TIMERSEM); /* TCP timer ticks every 100ms */ /* Reset Bluetooth module */ PD7.0 = 1; /* Enable output */ sio_print("Reseting BT module\n"); P7.0 = 1; /* Stop reset */ KS_delay(SELFTASK,(TICKS)4000/CLKTICK); /* Wait for bluetooth module to init */ /* Control application initialisation */ bt_ip_start(); while(1) { dma_input(cb, dma0bsz); /* Check for input */ /* Handle timers */ if(KS_inqsema(TIMERSEM) == SEMA_DONE) { KS_wait(TIMERSEM); tcp_tmr(); ++bt_timer; if(bt_timer == 10) { l2cap_tmr(); rfcomm_tmr(); ppp_tmr(); bt_timer = 0; ++bt_ip_timer; if(bt_ip_timer == 240) { bt_ip_tmr(); bt_ip_timer = 0; } } } } }
/*-----------------------------------------------------------------------------------*/ int main(int argc, char **argv) { struct phybusif_cb *cb; struct timeval tcptv, bttv, now; struct timezone tz; u8_t btiptmr = 0; #ifdef PERF perf_init("/tmp/minimal.perf"); #endif /* PERF */ #ifdef STATS stats_init(); #endif /* STATS */ mem_init(); memp_init(); pbuf_init(); netif_init(); ip_init(); //udp_init(); tcp_init(); printf("TCP/IP initialized.\n"); lwbt_memp_init(); phybusif_init(); if(hci_init() != ERR_OK) { printf("HCI initialization failed!"); exit(-1); } l2cap_init(); sdp_init(); rfcomm_init(); ppp_init(); printf("Bluetooth initialized.\n"); //echo_init(); httpd_init(); printf("Applications started.\n"); cb = malloc(sizeof(struct phybusif_cb)); phybusif_reset(cb); gettimeofday(&bttv, &tz); /* Initialize Bluetooth timer (1s) */ gettimeofday(&tcptv, &tz); /* Initialize TCP timer (TCP_TMR_INTERVAL) */ /* Host controller initialization for DTs according to LAN access point (LAP) and dial up networking (DUN) profile */ bt_ip_start(NULL); while(1) { phybusif_input(cb); /* Check for input */ gettimeofday(&now, &tz); /* Get current time */ /* Check if TCP timer should be called */ if((now.tv_sec - tcptv.tv_sec) * 1000000 + (now.tv_usec - tcptv.tv_usec) >= TCP_TMR_INTERVAL * 1000) { gettimeofday(&tcptv, &tz); /* Reset TCP timer */ tcp_tmr(); } /* Check if Bluetooth and NAT timers should be called */ if((now.tv_sec - bttv.tv_sec) * 1000000 + (now.tv_usec - bttv.tv_usec) >= 1000000) { gettimeofday(&bttv, &tz); /* Restart Bluetooth timer */ l2cap_tmr(); rfcomm_tmr(); ppp_tmr(); nat_tmr(); if(++btiptmr == 240) { /* Akes server special */ bt_ip_tmr(); btiptmr = 0; } } } return 0; }