Index: tools/tools/mq-testing/tcp/Makefile =================================================================== --- /dev/null +++ tools/tools/mq-testing/tcp/Makefile @@ -0,0 +1,93 @@ +# +# $FreeBSD$ +# + +CCDEP=cc +CC=cc + +ARCH=unix +CFLAGS=-g -Wall -D$(ARCH) -DIPv4 -pedantic -Werror \ + -Wparentheses -Wsequence-point -Wswitch-default \ + -Wextra -Wundef -Wshadow -Wpointer-arith -Wbad-function-cast \ + -Wc++-compat -Wwrite-strings -Wold-style-definition \ + -Wmissing-prototypes -Wredundant-decls -Wnested-externs +LDFLAGS=-lpthread -lutil +ARFLAGS=rs + +CONTRIBDIR=$(HOME)/lwip/lwip-1.4.1/contrib-1.4.1 +LWIPDIR=$(HOME)/lwip/lwip-1.4.1/lwip-1.4.1/src +LWIPARCH=$(CONTRIBDIR)/ports/unix + +CFLAGS:=$(CFLAGS) \ + -I. \ + -I$(LWIPDIR)/include \ + -I$(LWIPARCH)/include \ + -I$(LWIPDIR)/include/ipv4 \ + -I$(LWIPDIR) + +# COREFILES, CORE4FILES: The minimum set of files needed for lwIP. +COREFILES=$(LWIPDIR)/core/mem.c \ + $(LWIPDIR)/core/memp.c \ + $(LWIPDIR)/core/netif.c \ + $(LWIPDIR)/core/pbuf.c \ + $(LWIPDIR)/core/raw.c \ + $(LWIPDIR)/core/stats.c \ + $(LWIPDIR)/core/sys.c \ + $(LWIPDIR)/core/tcp.c \ + $(LWIPDIR)/core/tcp_in.c \ + $(LWIPDIR)/core/tcp_out.c \ + $(LWIPDIR)/core/udp.c \ + $(LWIPDIR)/core/dhcp.c \ + $(LWIPDIR)/core/init.c \ + $(LWIPDIR)/core/timers.c \ + $(LWIPDIR)/core/def.c +CORE4FILES=$(wildcard $(LWIPDIR)/core/ipv4/*.c) \ + $(LWIPDIR)/core/ipv4/inet.c \ + $(LWIPDIR)/core/ipv4/inet_chksum.c + +# APIFILES: The files which implement the sequential and socket APIs. +APIFILES=$(LWIPDIR)/api/api_lib.c \ + $(LWIPDIR)/api/api_msg.c \ + $(LWIPDIR)/api/tcpip.c \ + $(LWIPDIR)/api/err.c \ + $(LWIPDIR)/api/sockets.c \ + $(LWIPDIR)/api/netbuf.c \ + $(LWIPDIR)/api/netdb.c + +# NETIFFILES: Files implementing various generic network interface functions. +NETIFFILES=$(LWIPDIR)/netif/etharp.c + +# ARCHFILES: Architecture specific files. +ARCHFILES=$(wildcard $(LWIPARCH)/*.c) + +# LWIPFILES: All the above. +LWIPFILES=$(COREFILES) $(CORE4FILES) $(APIFILES) \ + $(NETIFFILES) $(ARCHFILES) +LWIPFILESW=$(wildcard $(LWIPFILES)) +LWIPOBJS=$(notdir $(LWIPFILESW:.c=.o)) +LWIPLIB=liblwip4.a + +CLIENTFILES=client.c vmeif.c +CLIENTOBJS=$(notdir $(CLIENTFILES:.c=.o)) + +%.o: + $(CC) $(CFLAGS) -c $(<:.o=.c) + +all: client server +.PHONY: all + +clean: + rm -f *.o $(LWIPLIB) client server *.s .depend* *.core core + +depend dep: .depend + +-include .depend + +$(LWIPLIB): $(LWIPOBJS) + $(AR) $(ARFLAGS) $(LWIPLIB) $? + +.depend: $(CLIENTFILES) $(LWIPFILES) + $(CCDEP) $(CFLAGS) -MM $^ > .depend || rm -f .depend + +client: .depend $(LWIPLIB) $(CLIENTOBJS) + $(CC) $(CFLAGS) $(LDFLAGS) -o client $(CLIENTOBJS) $(LWIPLIB) Index: tools/tools/mq-testing/tcp/client.c =================================================================== --- /dev/null +++ tools/tools/mq-testing/tcp/client.c @@ -0,0 +1,206 @@ +/*- + * Copyright (c) 2015, Tiwei Bie + * 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 unmodified, 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. + * + * 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. + */ + +#include +#include +#include +#include +#include + +#include "lwip/tcpip.h" +#include "lwip/sockets.h" + +#include "vmeif.h" +#include "common.h" + +static ip_addr_t ipaddr, netmask, gw; +static char payload[1024]; +static struct netif netif; +static int quiet = 0; +static int nr_connections = 10000; + +static const char *gw_str = "192.168.10.1"; +static const char *ip_str = "192.168.10.2"; +static const char *nm_str = "255.255.255.0"; + +/* nonstatic debug cmd option, exported in lwipopts.h */ +unsigned char debug_flags; + +static void +usage(const char *prgname) +{ + (void)prgname; + fprintf(stderr, + "Usage: %s [-g gateway] [-i address] [-m netmask]\n" + " %*s [-n connections] [-dhq]\n", + prgname, (int)strlen(prgname), ""); + exit(EXIT_FAILURE); +} + +static void +init_netifs(void) +{ + netif_set_default(netif_add(&netif, &ipaddr, &netmask, &gw, + NULL, vmeif_init, tcpip_input)); + netif_set_up(&netif); +} + +static void +tcpip_init_done(void *arg) +{ + sys_sem_t *sem = arg; + init_netifs(); + sys_sem_signal(sem); +} + +static void +client_routine(void) +{ + struct sockaddr_in daddr; + int sd, *sds; + int i; + + sds = malloc(sizeof(int) * nr_connections); + + memset(&daddr, 0, sizeof(daddr)); + daddr.sin_family = AF_INET; + daddr.sin_addr.s_addr = gw.addr; + daddr.sin_port = htons(SERVER_PORT); + + for (i = 0; i < nr_connections; i++) { + sd = lwip_socket(AF_INET, SOCK_STREAM, 0); + if (sd < 0) { + fprintf(stderr, "Failed to create socket\n"); + exit(EXIT_FAILURE); + } + + if (lwip_connect(sd, (struct sockaddr *)&daddr, + sizeof(daddr)) < 0) { + fprintf(stderr, "Failed to connect to server sd=%d\n", + i); + exit(EXIT_FAILURE); + } + + sds[i] = sd; + } + + while (1) { + for (i = 0; i < nr_connections; i++) { + sd = sds[i]; + + snprintf(payload, sizeof(payload), + "message from socket %d", i); + + if (lwip_send(sd, payload, strlen(payload), 0) < 0) { + fprintf(stderr, + "Failed to send data to server\n"); + exit(EXIT_FAILURE); + } + } + } +} + +static void +main_thread(void) +{ + sys_sem_t sem; + + netif_init(); + + if (sys_sem_new(&sem, 0) != ERR_OK) { + fprintf(stderr, "Failed to create semaphore\n"); + exit(EXIT_FAILURE); + } + + tcpip_init(tcpip_init_done, &sem); + sys_sem_wait(&sem); + + if (!quiet) + printf("TCP/IP initialized.\n"); + + client_routine(); +} + +static void +signal_handler(int arg) +{ + if (arg == SIGINT) + exit(EXIT_SUCCESS); +} + +int +main(int argc, char **argv) +{ + int ch; + + debug_flags = LWIP_DBG_OFF; + + while ((ch = getopt(argc, argv, "g:i:m:n:dhq")) != -1) { + switch (ch) { + case 'd': + debug_flags |= + (LWIP_DBG_ON | LWIP_DBG_TRACE | LWIP_DBG_STATE | + LWIP_DBG_FRESH | LWIP_DBG_HALT); + break; + case 'g': + gw_str = optarg; + break; + case 'i': + ip_str = optarg; + break; + case 'm': + nm_str = optarg; + break; + case 'n': + sscanf(optarg, "%d", &nr_connections); + break; + case 'q': + quiet = 1; + break; + case 'h': + default: + usage(argv[0]); + break; + } + } + + gw.addr = inet_addr(gw_str); + ipaddr.addr = inet_addr(ip_str); + netmask.addr = inet_addr(nm_str); + + signal(SIGINT, signal_handler); + + if (!quiet) { + printf("host at %s\n", ip_str); + printf("netmask: %s\n", nm_str); + printf("gateway: %s\n", gw_str); + printf("connections: %d\n", nr_connections); + } + + main_thread(); + + return (0); +} Index: tools/tools/mq-testing/tcp/common.h =================================================================== --- /dev/null +++ tools/tools/mq-testing/tcp/common.h @@ -0,0 +1,34 @@ +/*- + * Copyright (c) 2015, Tiwei Bie + * 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 unmodified, 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. + * + * 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. + */ + +/* $FreeBSD$ */ + +#ifndef _COMMON_H_ +#define _COMMON_H_ + +#define SERVER_PORT 8000 + +#endif Index: tools/tools/mq-testing/tcp/lwipopts.h =================================================================== --- /dev/null +++ tools/tools/mq-testing/tcp/lwipopts.h @@ -0,0 +1,311 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * 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. 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 lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIPOPTS_H__ +#define __LWIPOPTS_H__ + +#define LWIP_DBG_MIN_LEVEL 0 +#define LWIP_COMPAT_SOCKETS 1 +#define TAPIF_DEBUG LWIP_DBG_ON +#define TUNIF_DEBUG LWIP_DBG_OFF +#define UNIXIF_DEBUG LWIP_DBG_OFF +#define DELIF_DEBUG LWIP_DBG_OFF +#define SIO_FIFO_DEBUG LWIP_DBG_OFF +#define TCPDUMP_DEBUG LWIP_DBG_ON + +#define PPP_DEBUG LWIP_DBG_OFF +#define MEM_DEBUG LWIP_DBG_OFF +#define MEMP_DEBUG LWIP_DBG_OFF +#define PBUF_DEBUG LWIP_DBG_OFF +#define API_LIB_DEBUG LWIP_DBG_OFF +#define API_MSG_DEBUG LWIP_DBG_OFF +#define TCPIP_DEBUG LWIP_DBG_OFF +#define NETIF_DEBUG LWIP_DBG_OFF +#define SOCKETS_DEBUG LWIP_DBG_OFF +#define DEMO_DEBUG LWIP_DBG_OFF +#define IP_DEBUG LWIP_DBG_OFF +#define IP_REASS_DEBUG LWIP_DBG_OFF +#define RAW_DEBUG LWIP_DBG_OFF +#define ICMP_DEBUG LWIP_DBG_OFF +#define UDP_DEBUG LWIP_DBG_OFF +#define TCP_DEBUG LWIP_DBG_OFF +#define TCP_INPUT_DEBUG LWIP_DBG_OFF +#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF +#define TCP_RTO_DEBUG LWIP_DBG_OFF +#define TCP_CWND_DEBUG LWIP_DBG_OFF +#define TCP_WND_DEBUG LWIP_DBG_OFF +#define TCP_FR_DEBUG LWIP_DBG_OFF +#define TCP_QLEN_DEBUG LWIP_DBG_OFF +#define TCP_RST_DEBUG LWIP_DBG_OFF + +extern unsigned char debug_flags; +#define LWIP_DBG_TYPES_ON debug_flags + +#define NO_SYS 0 +#define LWIP_SOCKET (NO_SYS==0) +#define LWIP_NETCONN (NO_SYS==0) + + +/* ---------- Memory options ---------- */ +/* MEM_ALIGNMENT: should be set to the alignment of the CPU for which + lwIP is compiled. 4 byte alignment -> define MEM_ALIGNMENT to 4, 2 + byte alignment -> define MEM_ALIGNMENT to 2. */ +/* MSVC port: intel processors don't need 4-byte alignment, + but are faster that way! */ +#define MEM_ALIGNMENT 4 + +/* MEM_SIZE: the size of the heap memory. If the application will send +a lot of data that needs to be copied, this should be set high. */ +#define MEM_SIZE 10240 + +/* MEMP_NUM_PBUF: the number of memp struct pbufs. If the application + sends a lot of data out of ROM (or other static memory), this + should be set high. */ +#define MEMP_NUM_PBUF 16 +/* MEMP_NUM_RAW_PCB: the number of UDP protocol control blocks. One + per active RAW "connection". */ +#define MEMP_NUM_RAW_PCB 3 +/* MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One + per active UDP "connection". */ +#define MEMP_NUM_UDP_PCB 4 +/* MEMP_NUM_TCP_PCB: the number of simulatenously active TCP + connections. */ +#define MEMP_NUM_TCP_PCB 60000 +/* MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP + connections. */ +#define MEMP_NUM_TCP_PCB_LISTEN 8 +/* MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP + segments. */ +#define MEMP_NUM_TCP_SEG 16 +/* MEMP_NUM_SYS_TIMEOUT: the number of simulateously active + timeouts. */ +#define MEMP_NUM_SYS_TIMEOUT 3 + +/* The following four are used only with the sequential API and can be + set to 0 if the application only will use the raw API. */ +/* MEMP_NUM_NETBUF: the number of struct netbufs. */ +#define MEMP_NUM_NETBUF 2 +/* MEMP_NUM_NETCONN: the number of struct netconns. */ +#define MEMP_NUM_NETCONN 60000 +/* MEMP_NUM_TCPIP_MSG_*: the number of struct tcpip_msg, which is used + for sequential API communication and incoming packets. Used in + src/api/tcpip.c. */ +#define MEMP_NUM_TCPIP_MSG_API 16 +#define MEMP_NUM_TCPIP_MSG_INPKT 16 + +/* ---------- Pbuf options ---------- */ +/* PBUF_POOL_SIZE: the number of buffers in the pbuf pool. */ +#define PBUF_POOL_SIZE 120 + +/* PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. */ +#define PBUF_POOL_BUFSIZE 128 + +/* PBUF_LINK_HLEN: the number of bytes that should be allocated for a + link level header. */ +#define PBUF_LINK_HLEN 16 + +/** SYS_LIGHTWEIGHT_PROT + * define SYS_LIGHTWEIGHT_PROT in lwipopts.h if you want inter-task protection + * for certain critical regions during buffer allocation, deallocation and memory + * allocation and deallocation. + */ +#define SYS_LIGHTWEIGHT_PROT 1 + +/* ---------- TCP options ---------- */ +#define LWIP_TCP 1 +#define TCP_TTL 255 + +/* Controls if TCP should queue segments that arrive out of + order. Define to 0 if your device is low on memory. */ +#define TCP_QUEUE_OOSEQ 1 + +/* TCP Maximum segment size. */ +#define TCP_MSS 1024 + +/* TCP sender buffer space (bytes). */ +#define TCP_SND_BUF 2048 + +/* TCP sender buffer space (pbufs). This must be at least = 2 * + TCP_SND_BUF/TCP_MSS for things to work. */ +#define TCP_SND_QUEUELEN (4 * TCP_SND_BUF/TCP_MSS) + +/* TCP writable space (bytes). This must be less than or equal + to TCP_SND_BUF. It is the amount of space which must be + available in the tcp snd_buf for select to return writable */ +#define TCP_SNDLOWAT (TCP_SND_BUF/2) + +/* TCP receive window. */ +#define TCP_WND 8096 + +/* Maximum number of retransmissions of data segments. */ +#define TCP_MAXRTX 12 + +/* Maximum number of retransmissions of SYN segments. */ +#define TCP_SYNMAXRTX 4 + +/* ---------- ARP options ---------- */ +#define LWIP_ARP 1 +#define ARP_TABLE_SIZE 10 +#define ARP_QUEUEING 1 + +/* ---------- IP options ---------- */ +/* Define IP_FORWARD to 1 if you wish to have the ability to forward + IP packets across network interfaces. If you are going to run lwIP + on a device with only one network interface, define this to 0. */ +#define IP_FORWARD 1 + + +/* IP reassembly and segmentation.These are orthogonal even + * if they both deal with IP fragments */ +#define IP_REASSEMBLY 1 +#define IP_REASS_MAX_PBUFS 10 +#define MEMP_NUM_REASSDATA 10 +#define IP_FRAG 1 + +/* ---------- ICMP options ---------- */ +#define ICMP_TTL 255 + +/* ---------- DHCP options ---------- */ +/* Define LWIP_DHCP to 1 if you want DHCP configuration of + interfaces. */ +#define LWIP_DHCP 0 + +/* 1 if you want to do an ARP check on the offered address + (recommended if using DHCP). */ +#define DHCP_DOES_ARP_CHECK (LWIP_DHCP) + +/* ---------- AUTOIP options ------- */ +#define LWIP_AUTOIP 0 + +/* ---------- SNMP options ---------- */ +/** @todo SNMP is experimental for now + @note UDP must be available for SNMP transport */ +#ifndef LWIP_SNMP +#define LWIP_SNMP 0 +#endif + +#ifndef SNMP_PRIVATE_MIB +#define SNMP_PRIVATE_MIB 0 +#endif + +/* ---------- UDP options ---------- */ +#define LWIP_UDP 1 +#define UDP_TTL 255 + +/* ---------- RAW options ---------- */ +#define LWIP_RAW 1 +#define RAW_TTL 255 + +/* ---------- Statistics options ---------- */ +/* individual STATS options can be turned off by defining them to 0 + * (e.g #define TCP_STATS 0). All of them are turned off if LWIP_STATS + * is 0 + * */ + +#define LWIP_STATS 1 + +/* ---------- PPP options ---------- */ + +#define PPP_SUPPORT 0 /* Set > 0 for PPP */ + +#if PPP_SUPPORT > 0 + +#define NUM_PPP 1 /* Max PPP sessions. */ + + +/* Select modules to enable. Ideally these would be set in the makefile but + * we're limited by the command line length so you need to modify the settings + * in this file. + */ +#define PAP_SUPPORT 1 /* Set > 0 for PAP. */ +#define CHAP_SUPPORT 1 /* Set > 0 for CHAP. */ +#define MSCHAP_SUPPORT 0 /* Set > 0 for MSCHAP (NOT FUNCTIONAL!) */ +#define CBCP_SUPPORT 0 /* Set > 0 for CBCP (NOT FUNCTIONAL!) */ +#define CCP_SUPPORT 0 /* Set > 0 for CCP (NOT FUNCTIONAL!) */ +#define VJ_SUPPORT 1 /* Set > 0 for VJ header compression. */ +#define MD5_SUPPORT 1 /* Set > 0 for MD5 (see also CHAP) */ + + +/* + * Timeouts. + */ +#define FSM_DEFTIMEOUT 6 /* Timeout time in seconds */ +#define FSM_DEFMAXTERMREQS 2 /* Maximum Terminate-Request transmissions */ +#define FSM_DEFMAXCONFREQS 10 /* Maximum Configure-Request transmissions */ +#define FSM_DEFMAXNAKLOOPS 5 /* Maximum number of nak loops */ + +#define UPAP_DEFTIMEOUT 6 /* Timeout (seconds) for retransmitting req */ +#define UPAP_DEFREQTIME 30 /* Time to wait for auth-req from peer */ + +#define CHAP_DEFTIMEOUT 6 /* Timeout time in seconds */ +#define CHAP_DEFTRANSMITS 10 /* max # times to send challenge */ + + +/* Interval in seconds between keepalive echo requests, 0 to disable. */ +#if 1 +#define LCP_ECHOINTERVAL 0 +#else +#define LCP_ECHOINTERVAL 10 +#endif + +/* Number of unanswered echo requests before failure. */ +#define LCP_MAXECHOFAILS 3 + +/* Max Xmit idle time (in jiffies) before resend flag char. */ +#define PPP_MAXIDLEFLAG 100 + +/* + * Packet sizes + * + * Note - lcp shouldn't be allowed to negotiate stuff outside these + * limits. See lcp.h in the pppd directory. + * (XXX - these constants should simply be shared by lcp.c instead + * of living in lcp.h) + */ +#define PPP_MTU 1500 /* Default MTU (size of Info field) */ +#if 0 +#define PPP_MAXMTU 65535 - (PPP_HDRLEN + PPP_FCSLEN) +#else +#define PPP_MAXMTU 1500 /* Largest MTU we allow */ +#endif +#define PPP_MINMTU 64 +#define PPP_MRU 1500 /* default MRU = max length of info field */ +#define PPP_MAXMRU 1500 /* Largest MRU we allow */ +#define PPP_DEFMRU 296 /* Try for this */ +#define PPP_MINMRU 128 /* No MRUs below this */ + + +#define MAXNAMELEN 256 /* max length of hostname or name for auth */ +#define MAXSECRETLEN 256 /* max length of password or secret */ + +#endif /* PPP_SUPPORT > 0 */ + +#endif /* __LWIPOPTS_H__ */ Index: tools/tools/mq-testing/tcp/server.c =================================================================== --- /dev/null +++ tools/tools/mq-testing/tcp/server.c @@ -0,0 +1,216 @@ +/*- + * Copyright (c) 2015, Tiwei Bie + * 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 unmodified, 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. + * + * 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. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include "common.h" + +static int verbose = 0; + +#define NR_EVENTS 10 + +static void +usage(const char *prgname) +{ + fprintf(stderr, "Usage: %s [-hv]\n", prgname); + exit(EXIT_FAILURE); +} + +static char * +addr2str(int af, void *addr) +{ + static char msg[1024]; + char addrstr[INET6_ADDRSTRLEN]; + + switch (af) { + case AF_INET: + snprintf(msg, sizeof(msg), "%s:%d", + inet_ntoa(((struct sockaddr_in *)addr)->sin_addr), + ntohs(((struct sockaddr_in *)addr)->sin_port)); + break; + case AF_INET6: + snprintf(msg, sizeof(msg), "%s:%d", + inet_ntop(AF_INET6, + &((struct sockaddr_in6 *)addr)->sin6_addr, + addrstr, sizeof(addrstr)), + ntohs(((struct sockaddr_in6 *)addr)->sin6_port)); + break; + } + + return (msg); +} + +static int +kq_add(int kq, int fd) +{ + struct kevent changes[1]; + int ret; + + EV_SET(&changes[0], fd, EVFILT_READ, EV_ADD, 0, 0, NULL); + ret = kevent(kq, changes, 1, NULL, 0, NULL); + + return (ret); +} + +static int +kq_delete(int kq, int fd) +{ + struct kevent changes[1]; + int ret; + + EV_SET(&changes[0], fd, EVFILT_READ, EV_DELETE, 0, 0, NULL); + ret = kevent(kq, changes, 1, NULL, 0, NULL); + + return (ret); +} + +static void +accept_new_connection(int kq, int fd, int n) +{ + struct sockaddr_in from; + socklen_t length; + int newfd, i; + + for (i = 0; i < n; i++) { + length = sizeof(from); + newfd = accept(fd, (struct sockaddr *)&from, &length); + if (newfd < 0) + err(EXIT_FAILURE, "accept"); + + if (kq_add(kq, newfd) < 0) + err(EXIT_FAILURE, "kq_add"); + + if (verbose) + printf("accept connection from %s\n", + addr2str(AF_INET, &from)); + } +} + +static void +receive_data(int kq, int fd, int n) +{ + char msg[BUFSIZ]; + int i; + + n = read(fd, msg, sizeof(msg)); + if (n < 0) + err(EXIT_FAILURE, "read"); + + if (n == 0) { + if (kq_delete(kq, fd) < 0) + err(EXIT_FAILURE, "kq_delete"); + return; + } + + if (verbose) { + printf("len=%d ", n); + for (i = 0; i < n && msg[i]; i++) { + if (isprint(msg[i])) + printf("%c", msg[i]); + } + printf("\n"); + } +} + +int +main(int argc, char **argv) +{ + int servfd, kq; + struct sockaddr_in sin; + int ch, on; + + while ((ch = getopt(argc, argv, "hv")) != -1) { + switch (ch) { + case 'v': + verbose = 1; + break; + case 'h': + default: + usage(argv[0]); + break; + } + } + + servfd = socket(AF_INET, SOCK_STREAM, 0); + if (servfd < 0) + err(EXIT_FAILURE, "socket"); + + memset(&sin, 0, sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = INADDR_ANY; + sin.sin_port = htons(SERVER_PORT); + + on = 1; + if (setsockopt(servfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) + err(EXIT_FAILURE, "setsockopt"); + + if (bind(servfd, (struct sockaddr *)&sin, sizeof(sin)) < 0) + err(EXIT_FAILURE, "bind"); + + if (listen(servfd, 5) < 0) + err(EXIT_FAILURE, "listen"); + + if ((kq = kqueue()) < 0) + err(EXIT_FAILURE, "kqueue"); + + if (kq_add(kq, servfd) < 0) + err(EXIT_FAILURE, "kq_add"); + + while (1) { + struct kevent events[NR_EVENTS]; + int n, i; + + n = kevent(kq, NULL, 0, events, NR_EVENTS, NULL); + if (n < 0) + err(EXIT_FAILURE, "kevent"); + + for (i = 0; i < n; i++) { + int sd, data; + + sd = events[i].ident; + data = events[i].data; + + if (sd == servfd) + accept_new_connection(kq, sd, data); + else + receive_data(kq, sd, data); + } + } + + return (0); +} Index: tools/tools/mq-testing/tcp/vmeif.h =================================================================== --- /dev/null +++ tools/tools/mq-testing/tcp/vmeif.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * 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. 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 lwIP TCP/IP stack. + * + * Author: Adam Dunkels + */ +#ifndef _VMEIF_H_ +#define _VMEIF_H_ + +#include "lwip/netif.h" + +err_t vmeif_init(struct netif *netif); + +#endif /* _VMEIF_H_ */ Index: tools/tools/mq-testing/tcp/vmeif.c =================================================================== --- /dev/null +++ tools/tools/mq-testing/tcp/vmeif.c @@ -0,0 +1,298 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * Copyright (c) 2015 Tiwei Bie + * + * 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. 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 lwIP TCP/IP stack. + * + * Author: Adam Dunkels + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "lwip/debug.h" + +#include "lwip/opt.h" +#include "lwip/def.h" +#include "lwip/ip.h" +#include "lwip/mem.h" +#include "lwip/pbuf.h" +#include "lwip/sys.h" + +#include "netif/etharp.h" + +#include "vmeif.h" + +#define IFCONFIG_BIN "/sbin/ifconfig " + +#define DEVVME "/dev/vme0" +#define IFCONFIG_ARGS "vme0 inet %d.%d.%d.%d" + +#define IFNAME0 't' +#define IFNAME1 'p' + +#ifndef VMEIF_DEBUG +#define VMEIF_DEBUG LWIP_DBG_OFF +#endif + +struct vmeif { + struct eth_addr *ethaddr; + int fd; +}; + +/* Forward declarations. */ +static void vmeif_input(struct netif *netif); +static void vmeif_thread(void *data); + +static void +low_level_init(struct netif *netif) +{ + struct vmeif *vmeif; + char buf[sizeof(IFCONFIG_ARGS) + sizeof(IFCONFIG_BIN) + 50]; + + vmeif = (struct vmeif *)netif->state; + + /* Obtain MAC address from network interface. */ + + /* (We just fake an address...) */ + vmeif->ethaddr->addr[0] = 0xbc; + vmeif->ethaddr->addr[1] = 0xae; + vmeif->ethaddr->addr[2] = 0xc5; + vmeif->ethaddr->addr[3] = 0x23; + vmeif->ethaddr->addr[4] = 0x61; + vmeif->ethaddr->addr[5] = 0x22; + + /* Do whatever else is needed to initialize interface. */ + + vmeif->fd = open(DEVVME, O_RDWR); + LWIP_DEBUGF(VMEIF_DEBUG, ("vmeif_init: fd %d\n", vmeif->fd)); + if (vmeif->fd == -1) { + perror("vmeif_init: cannot open " DEVVME); + exit(1); + } + + sprintf(buf, IFCONFIG_BIN IFCONFIG_ARGS, + ip4_addr1(&(netif->gw)), + ip4_addr2(&(netif->gw)), + ip4_addr3(&(netif->gw)), ip4_addr4(&(netif->gw))); + + LWIP_DEBUGF(VMEIF_DEBUG, ("vmeif_init: system(\"%s\");\n", buf)); + system(buf); + sys_thread_new("vmeif_thread", vmeif_thread, netif, + DEFAULT_THREAD_STACKSIZE, DEFAULT_THREAD_PRIO); + +} + +/* + * low_level_output(): + * + * Should do the actual transmission of the packet. The packet is + * contained in the pbuf that is passed to the function. This pbuf + * might be chained. + */ +static err_t +low_level_output(struct netif *netif, struct pbuf *p) +{ + struct pbuf *q; + char buf[1514]; + char *bufptr; + struct vmeif *vmeif; + + vmeif = (struct vmeif *)netif->state; + + /* initiate transfer(); */ + + bufptr = &buf[0]; + + for (q = p; q != NULL; q = q->next) { + /* Send the data from the pbuf to the interface, one pbuf at a + time. The size of the data in each pbuf is kept in the ->len + variable. */ + /* send data from(q->payload, q->len); */ + memcpy(bufptr, q->payload, q->len); + bufptr += q->len; + } + + /* signal that packet should be sent(); */ + if (write(vmeif->fd, buf, p->tot_len) == -1) { + perror("vmeif: write"); + } + return (ERR_OK); +} + +/* + * low_level_input(): + * + * Should allocate a pbuf and transfer the bytes of the incoming + * packet from the interface into the pbuf. + */ +static struct pbuf * +low_level_input(struct vmeif *vmeif) +{ + struct pbuf *p, *q; + u16_t len; + char buf[1514]; + char *bufptr; + + /* Obtain the size of the packet and put it into the "len" + variable. */ + len = read(vmeif->fd, buf, sizeof(buf)); + + /* We allocate a pbuf chain of pbufs from the pool. */ + p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL); + + if (p != NULL) { + /* We iterate over the pbuf chain until we have read the entire + packet into the pbuf. */ + bufptr = &buf[0]; + for (q = p; q != NULL; q = q->next) { + /* Read enough bytes to fill this pbuf in the chain. The + available data in the pbuf is given by the q->len + variable. */ + /* read data into(q->payload, q->len); */ + memcpy(q->payload, bufptr, q->len); + bufptr += q->len; + } + /* acknowledge that packet has been read(); */ + } else { + /* drop packet(); */ + } + + return (p); +} + +static void +vmeif_thread(void *arg) +{ + struct netif *netif; + struct vmeif *vmeif; + fd_set fdset; + int ret; + + netif = (struct netif *)arg; + vmeif = (struct vmeif *)netif->state; + + while (1) { + FD_ZERO(&fdset); + FD_SET(vmeif->fd, &fdset); + + /* Wait for a packet to arrive. */ + ret = select(vmeif->fd + 1, &fdset, NULL, NULL, NULL); + + if (ret == 1) { + /* Handle incoming packet. */ + vmeif_input(netif); + } else if (ret == -1) { + perror("vmeif_thread: select"); + } + } +} + +/* + * vmeif_input(): + * + * This function should be called when a packet is ready to be read + * from the interface. It uses the function low_level_input() that + * should handle the actual reception of bytes from the network + * interface. + */ +static void +vmeif_input(struct netif *netif) +{ + struct vmeif *vmeif; + struct eth_hdr *ethhdr; + struct pbuf *p; + + vmeif = (struct vmeif *)netif->state; + + p = low_level_input(vmeif); + + if (p == NULL) { + LWIP_DEBUGF(VMEIF_DEBUG, + ("vmeif_input: low_level_input returned NULL\n")); + return; + } + ethhdr = (struct eth_hdr *)p->payload; + + switch (htons(ethhdr->type)) { + /* IP or ARP packet? */ + case ETHTYPE_IP: + case ETHTYPE_ARP: + /* full packet send to tcpip_thread to process */ + if (netif->input(p, netif) != ERR_OK) { + LWIP_DEBUGF(NETIF_DEBUG, + ("ethernetif_input: IP input error\n")); + pbuf_free(p); + p = NULL; + } + break; + default: + pbuf_free(p); + break; + } +} + +/* + * vmeif_init(): + * + * Should be called at the beginning of the program to set up the + * network interface. It calls the function low_level_init() to do the + * actual setup of the hardware. + */ +err_t +vmeif_init(struct netif *netif) +{ + struct vmeif *vmeif; + + vmeif = mem_malloc(sizeof(struct vmeif)); + if (!vmeif) + return (ERR_MEM); + + netif->state = vmeif; + netif->name[0] = IFNAME0; + netif->name[1] = IFNAME1; + netif->output = etharp_output; + netif->linkoutput = low_level_output; + netif->mtu = 1500; + /* hardware address length */ + netif->hwaddr_len = 6; + + vmeif->ethaddr = (struct eth_addr *)&(netif->hwaddr[0]); + + netif->flags = + NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_IGMP; + + low_level_init(netif); + + return (ERR_OK); +}