/* * Copyright (c) 2001,2002 Florian Schulze. * 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. Neither the name of the authors nor the names of the contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS 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 AUTHORS 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. * * test.c - This file is part of lwIP test * */ /* C runtime includes */ #include #include #include #include #include /* lwIP core includes */ #include "lwip/opt.h" #include "lwip/sys.h" #include "lwip/timers.h" #include "lwip/debug.h" #include "lwip/stats.h" #include "lwip/init.h" #include "lwip/tcpip.h" #include "lwip/netif.h" #include "lwip/tcp.h" #include "lwip/udp.h" #include "lwip/dns.h" #include "lwip/dhcp.h" #include "lwip/autoip.h" /* lwIP netif includes */ #include "netif/loopif.h" #include "netif/etharp.h" /* applications includes */ #include "apps/httpserver_raw/httpd.h" #include "apps/httpserver/httpserver-netconn.h" #include "apps/netio/netio.h" #include "apps/netbios/netbios.h" #include "apps/ping/ping.h" #include "apps/rtp/rtp.h" #include "apps/sntp/sntp.h" #include "apps/chargen/chargen.h" #if NO_SYS /* ... then we need information about the timer intervals: */ #include "lwip/ip_frag.h" #include "lwip/igmp.h" #endif /* NO_SYS */ #if PPP_SUPPORT /* PPP includes */ #include "../netif/ppp/ppp.h" #include "../netif/ppp/lcp.h" #include "lwip/sio.h" #include "netif/ppp_oe.h" #endif /* PPP_SUPPORT */ #include "pktif.h" /* include the port-dependent configuration */ #include "lwipcfg_msvc.h" /** Use an ethernet adapter? By default only if PPP is not used. */ #ifndef USE_ETHERNET #define USE_ETHERNET (!PPP_SUPPORT || PPPOE_SUPPORT) #endif /** Use an ethernet adapter for TCP/IP? By default only if PPP is not used. */ #ifndef USE_ETHERNET_TCPIP #define USE_ETHERNET_TCPIP !PPP_SUPPORT #endif /* globales variables for netifs */ #if USE_ETHERNET /* THE ethernet interface */ struct netif netif; #endif /* USE_ETHERNET */ #if LWIP_HAVE_LOOPIF /* THE loopback interface */ struct netif loop_netif; #endif /* LWIP_HAVE_LOOPIF */ #if PPP_SUPPORT /* THE PPP descriptor */ int ppp_desc = -1; int sio_idx = 0; sio_fd_t ppp_sio; #endif /* PPP_SUPPORT */ #if PPP_SUPPORT void pppLinkStatusCallback(void *ctx, int errCode, void *arg) { LWIP_UNUSED_ARG(ctx); switch(errCode) { case PPPERR_NONE: { /* No error. */ struct ppp_addrs *ppp_addrs = arg; printf("pppLinkStatusCallback: PPPERR_NONE\n"); printf(" our_ipaddr=%s\n", ip_ntoa(&ppp_addrs->our_ipaddr)); printf(" his_ipaddr=%s\n", ip_ntoa(&ppp_addrs->his_ipaddr)); printf(" netmask =%s\n", ip_ntoa(&ppp_addrs->netmask)); printf(" dns1 =%s\n", ip_ntoa(&ppp_addrs->dns1)); printf(" dns2 =%s\n", ip_ntoa(&ppp_addrs->dns2)); break; } case PPPERR_PARAM: { /* Invalid parameter. */ printf("pppLinkStatusCallback: PPPERR_PARAM\n"); break; } case PPPERR_OPEN: { /* Unable to open PPP session. */ printf("pppLinkStatusCallback: PPPERR_OPEN\n"); break; } case PPPERR_DEVICE: { /* Invalid I/O device for PPP. */ printf("pppLinkStatusCallback: PPPERR_DEVICE\n"); break; } case PPPERR_ALLOC: { /* Unable to allocate resources. */ printf("pppLinkStatusCallback: PPPERR_ALLOC\n"); break; } case PPPERR_USER: { /* User interrupt. */ printf("pppLinkStatusCallback: PPPERR_USER\n"); break; } case PPPERR_CONNECT: { /* Connection lost. */ printf("pppLinkStatusCallback: PPPERR_CONNECT\n"); break; } case PPPERR_AUTHFAIL: { /* Failed authentication challenge. */ printf("pppLinkStatusCallback: PPPERR_AUTHFAIL\n"); break; } case PPPERR_PROTOCOL: { /* Failed to meet protocol. */ printf("pppLinkStatusCallback: PPPERR_PROTOCOL\n"); break; } default: { printf("pppLinkStatusCallback: unknown errCode %d\n", errCode); break; } } } #endif /* PPP_SUPPORT */ #if LWIP_NETIF_STATUS_CALLBACK void status_callback(struct netif *netif) { if (netif_is_up(netif)) { printf("status_callback==UP, local interface IP is %s\n", ip_ntoa(&netif->ip_addr)); } else { printf("status_callback==DOWN\n"); } } #endif /* LWIP_NETIF_STATUS_CALLBACK */ #if LWIP_NETIF_LINK_CALLBACK void link_callback(struct netif *netif) { if (netif_is_link_up(netif)) { printf("link_callback==UP\n"); #if LWIP_DHCP if (netif->dhcp != NULL) { dhcp_renew(netif); } #endif /* LWIP_DHCP */ } else { printf("link_callback==DOWN\n"); } } #endif /* LWIP_NETIF_LINK_CALLBACK */ /* This function initializes all network interfaces */ static void msvc_netif_init() { #if USE_ETHERNET struct ip_addr ipaddr, netmask, gw; #endif /* USE_ETHERNET */ #if LWIP_HAVE_LOOPIF struct ip_addr loop_ipaddr, loop_netmask, loop_gw; #endif /* LWIP_HAVE_LOOPIF */ #if PPP_SUPPORT const char *username = NULL, *password = NULL; #ifdef PPP_USERNAME username = PPP_USERNAME; #endif #ifdef PPP_PASSWORD password = PPP_PASSWORD; #endif printf("pppInit\n"); pppInit(); pppSetAuth(PPPAUTHTYPE_ANY, username, password); printf("pppOpen\n"); #if PPPOS_SUPPORT ppp_sio = sio_open(sio_idx); if (ppp_sio == NULL) { printf("sio_open error\n"); } else { ppp_desc = pppOpen(ppp_sio, pppLinkStatusCallback, NULL); } #endif /* PPPOS_SUPPORT */ #endif /* PPP_SUPPORT */ #if LWIP_HAVE_LOOPIF IP4_ADDR(&loop_gw, 127,0,0,1); IP4_ADDR(&loop_ipaddr, 127,0,0,1); IP4_ADDR(&loop_netmask, 255,0,0,0); printf("Starting lwIP, loopback interface IP is %s\n", ip_ntoa(&loop_ipaddr)); #if NO_SYS netif_add(&loop_netif, &loop_ipaddr, &loop_netmask, &loop_gw, NULL, loopif_init, ip_input); #else /* NO_SYS */ netif_add(&loop_netif, &loop_ipaddr, &loop_netmask, &loop_gw, NULL, loopif_init, tcpip_input); #endif /* NO_SYS */ netif_set_up(&loop_netif); #endif /* LWIP_HAVE_LOOPIF */ #if USE_ETHERNET gw.addr = 0; ipaddr.addr = 0; netmask.addr = 0; #if USE_ETHERNET_TCPIP #if LWIP_DHCP printf("Starting lwIP, local interface IP is dhcp-enabled\n"); #elif LWIP_AUTOIP printf("Starting lwIP, local interface IP is autoip-enabled\n"); #else /* LWIP_AUTOIP */ LWIP_PORT_INIT_GW(&gw); LWIP_PORT_INIT_IPADDR(&ipaddr); LWIP_PORT_INIT_NETMASK(&netmask); printf("Starting lwIP, local interface IP is %s\n", ip_ntoa(&ipaddr)); #endif /* LWIP_DHCP */ #endif /* USE_ETHERNET_TCPIP */ #if NO_SYS #if LWIP_ARP netif_set_default(netif_add(&netif, &ipaddr, &netmask, &gw, NULL, ethernetif_init, ethernet_input)); #else /* LWIP_ARP */ netif_set_default(netif_add(&netif, &ipaddr, &netmask, &gw, NULL, ethernetif_init, ip_input)); #endif /* LWIP_ARP */ #else /* NO_SYS */ netif_set_default(netif_add(&netif, &ipaddr, &netmask, &gw, NULL, ethernetif_init, tcpip_input)); #endif /* NO_SYS */ #if LWIP_NETIF_STATUS_CALLBACK netif_set_status_callback(&netif, status_callback); #endif /* LWIP_NETIF_STATUS_CALLBACK */ #if LWIP_NETIF_LINK_CALLBACK netif_set_link_callback(&netif, link_callback); #endif /* LWIP_NETIF_LINK_CALLBACK */ #if USE_ETHERNET_TCPIP #if LWIP_DHCP dhcp_start(&netif); #elif LWIP_AUTOIP autoip_start(&netif); #else /* LWIP_DHCP */ netif_set_up(&netif); #endif /* LWIP_DHCP */ #endif /* USE_ETHERNET_TCPIP */ #if PPP_SUPPORT && PPPOE_SUPPORT /* start PPPoE after ethernet netif is added! */ ppp_desc = pppOverEthernetOpen(&netif, NULL, NULL, pppLinkStatusCallback, NULL); #endif /* PPP_SUPPORT && PPPOE_SUPPORT */ #endif /* USE_ETHERNET */ } void dns_found(const char *name, struct ip_addr *addr, void *arg) { LWIP_UNUSED_ARG(arg); printf("%s: %s\n", name, addr ? ip_ntoa(addr) : ""); } /* This function initializes applications */ static void apps_init() { #if LWIP_DNS_APP && LWIP_DNS char* dnsname="3com.com"; struct ip_addr dnsresp; if (dns_gethostbyname(dnsname, &dnsresp, dns_found, 0) == ERR_OK) { dns_found(dnsname, &dnsresp, 0); } #endif /* LWIP_DNS_APP && LWIP_DNS */ #if LWIP_CHARGEN_APP && LWIP_SOCKET chargen_init(); #endif /* LWIP_CHARGEN_APP && LWIP_SOCKET */ #if LWIP_PING_APP && LWIP_RAW && LWIP_ICMP ping_init(); #endif /* LWIP_PING_APP && LWIP_RAW && LWIP_ICMP */ #if LWIP_NETBIOS_APP && LWIP_UDP netbios_init(); #endif /* LWIP_NETBIOS_APP && LWIP_UDP */ #if LWIP_HTTPD_APP && LWIP_TCP #ifdef LWIP_HTTPD_APP_NETCONN http_server_netconn_init(); #else /* LWIP_HTTPD_APP_NETCONN */ httpd_init(); #endif /* LWIP_HTTPD_APP_NETCONN */ #endif /* LWIP_HTTPD_APP && LWIP_TCP */ #if LWIP_NETIO_APP && LWIP_TCP netio_init(); #endif /* LWIP_NETIO_APP && LWIP_TCP */ #if LWIP_RTP_APP && LWIP_SOCKET rtp_init(); #endif /* LWIP_RTP_APP && LWIP_SOCKET */ #if LWIP_SNTP_APP && LWIP_SOCKET sntp_init(); #endif /* LWIP_SNTP_APP && LWIP_SOCKET */ } /* This function initializes this lwIP test. When NO_SYS=1, this is done in * the main_loop context (there is no other one), when NO_SYS=0, this is done * in the tcpip_thread context */ static void test_init(void * arg) { /* remove compiler warning */ #if NO_SYS LWIP_UNUSED_ARG(arg); #else /* NO_SYS */ sys_sem_t init_sem; LWIP_ASSERT("arg != NULL", arg != NULL); init_sem = (sys_sem_t)arg; #endif /* NO_SYS */ /* init network interfaces */ msvc_netif_init(); /* init apps */ apps_init(); #if !NO_SYS sys_sem_signal(init_sem); #endif /* !NO_SYS */ } #if PPP_SUPPORT static void pppCloseCallback(void *arg) { int pd = (int)arg; pppClose(pd); } #endif /* PPP_SUPPORT */ /* This is somewhat different to other ports: we have a main loop here: * a dedicated task that waits for packets to arrive. This would normally be * done from interrupt context with embedded hardware, but we don't get an * interrupt in windows for that :-) */ void main_loop() { #if !NO_SYS sys_sem_t init_sem; #endif /* NO_SYS */ #if PPP_SUPPORT #if !USE_ETHERNET int count; u8_t rxbuf[1024]; #endif volatile int callClosePpp = 0; #endif /* PPP_SUPPORT */ /* initialize lwIP stack, network interfaces and applications */ #if NO_SYS lwip_init(); test_init(NULL); #else /* NO_SYS */ init_sem = sys_sem_new(0); tcpip_init(test_init, init_sem); /* we have to wait for initialization to finish before * calling update_adapter()! */ sys_sem_wait(init_sem); sys_sem_free(init_sem); #endif /* NO_SYS */ /* MAIN LOOP for driver update (and timers if NO_SYS) */ while (!_kbhit()) { #if NO_SYS /* handle timers (already done in tcpip.c when NO_SYS=0) */ sys_check_timeouts(); #endif /* NO_SYS */ #if USE_ETHERNET /* check for packets and link status*/ ethernetif_poll(&netif); #else /* USE_ETHERNET */ #if 0 /* set this to 1 if PPP_INPROC_OWNTHREAD==0 or not defined (see ppp.c) */ /* try to read characters from serial line and pass them to PPPoS */ count = sio_read(ppp_sio, (u8_t*)rxbuf, 1024); if(count > 0) { pppos_input(ppp_desc, rxbuf, count); } else #endif { /* nothing received, give other tasks a chance to run */ sys_msleep(1); } #endif /* USE_ETHERNET */ #if !LWIP_NETIF_LOOPBACK_MULTITHREADING /* check for loopback packets on all netifs */ netif_poll_all(); #endif /* !LWIP_NETIF_LOOPBACK_MULTITHREADING */ #if PPP_SUPPORT { int do_hup = 0; if(do_hup) { pppSigHUP(ppp_desc); do_hup = 0; } } if(callClosePpp && (ppp_desc >= 0)) { /* make sure to disconnect PPP before stopping the program... */ callClosePpp = 0; #if NO_SYS pppClose(ppp_desc); #else tcpip_callback_with_block(pppCloseCallback, (void*)ppp_desc, 0); #endif ppp_desc = -1; } #endif /* PPP_SUPPORT */ } #if PPP_SUPPORT if(ppp_desc >= 0) { u32_t started; printf("Closing PPP connection...\n"); /* make sure to disconnect PPP before stopping the program... */ #if NO_SYS pppClose(ppp_desc); #else tcpip_callback_with_block(pppCloseCallback, (void*)ppp_desc, 0); #endif ppp_desc = -1; /* Wait for some time to let PPP finish... */ started = sys_now(); do { #if USE_ETHERNET ethernetif_poll(&netif); #else /* USE_ETHERNET */ sys_msleep(50); #endif /* USE_ETHERNET */ /* @todo: need a better check here: only wait until PPP is down */ } while(sys_now() - started < 5000); } #endif /* PPP_SUPPORT */ #if USE_ETHERNET /* release the pcap library... */ ethernetif_shutdown(&netif); #endif /* USE_ETHERNET */ } #if PPP_SUPPORT && PPPOS_SUPPORT int main(int argc, char **argv) #else /* PPP_SUPPORT && PPPOS_SUPPORT */ int main(void) #endif /* PPP_SUPPORT && PPPOS_SUPPORT */ { #if PPP_SUPPORT && PPPOS_SUPPORT if(argc > 1) { sio_idx = atoi(argv[1]); } printf("Using serial port %d for PPP\n", sio_idx); #endif /* PPP_SUPPORT && PPPOS_SUPPORT */ /* no stdio-buffering, please! */ setvbuf(stdout, NULL,_IONBF, 0); main_loop(); return 0; }