├── rules ├── crc.mk ├── ipc.mk ├── tap.mk ├── tun.mk ├── pcap.mk ├── cyassl.mk ├── polarssl.mk ├── nat.mk ├── ipv4.mk ├── mcast.mk ├── mld.mk ├── olsr.mk ├── igmp.mk ├── memory_manager.mk ├── ppp.mk ├── devloop.mk ├── ipfilter.mk ├── ipv4frag.mk ├── ipv6frag.mk ├── wolfssl.mk ├── sntp_client.mk ├── mdns.mk ├── eth.mk ├── tcp.mk ├── udp.mk ├── dhcp_client.mk ├── dhcp_server.mk ├── dns_client.mk ├── slaacv4.mk ├── dns_sd.mk ├── icmp4.mk ├── ipv6.mk └── 6lowpan.mk ├── test ├── coverage.sh ├── examples │ ├── noop.c │ ├── natbox.c │ ├── Makefile │ ├── utils.h │ ├── slaacv4.c │ ├── sntp.c │ ├── mdns.c │ ├── udp_sendto_test.c │ ├── dhcp_server.c │ ├── dns_sd.c │ └── dhcp_client.c ├── README.md ├── python │ ├── http_server_linux.py │ ├── noop.py │ ├── ping.py │ ├── ping_linux.py │ ├── ping_delay.py │ ├── tcpbench_rx_linux.py │ ├── udpecho.py │ ├── tcpbench_tx_linux.py │ ├── ping_nat.py │ ├── tcpbench.py │ ├── tcpecho_linux.py │ ├── tcpbench-tap.py │ ├── tcpbench-delay.py │ ├── zmq_linux.py │ ├── dhcp.py │ ├── fairness_bottleneck.py │ ├── fairness_bottleneck_linux.py │ ├── fairness.py │ ├── traceroute_from_linux.py │ ├── traceroute_nat_from_linux.py │ ├── multicast_send.py │ ├── fragmentation.py │ ├── reassembly.py │ └── multicast_recv.py ├── dummy.c ├── Makefile ├── vde_sock_start_user.sh ├── pico_faulty.c ├── vde_sock_start.sh ├── perf.sh ├── unit │ ├── unit_timer.c │ ├── modunit_seq.c │ ├── modunit_pico_strings.c │ ├── unit_mocks.c │ ├── modunit_queue.c │ ├── modunit_pico_dev_loop.c │ ├── unit_rbtree.c │ └── unit_dns.c ├── olsr_test.sh ├── units.sh └── pico_faulty.h ├── docs ├── wiki_images │ ├── petri_net.gif │ ├── pico_frame.png │ ├── port_to_os.dia │ ├── port_to_os.png │ ├── picoTCP_logo.png │ ├── Protocol input.dia │ ├── Protocol output.dia │ ├── Protocol_input.png │ ├── Protocol_output.png │ ├── driver_stack_memory.dia │ └── driver_stack_memory.png └── user_manual │ ├── build.sh │ ├── chap_license.tex │ ├── template_api.tex │ ├── layout1.tex │ ├── README.md │ ├── chap_api_aodv.tex │ ├── chap_api_slaacv4.tex │ ├── chap_api_olsr.tex │ ├── chap_api_mld.tex │ ├── chap_api_igmp.tex │ ├── layout.tex │ ├── chap_api_dhcp_d.tex │ ├── user_doc.tex │ └── chap_api_ipfilter.tex ├── COPYING ├── .gitignore ├── modules ├── pico_fragments.h ├── pico_dev_radio_mgr.h ├── pico_dev_loop.h ├── pico_dev_tap.h ├── pico_dev_tun.h ├── pico_dev_null.h ├── pico_ethernet.h ├── pico_dev_ipc.h ├── pico_dev_radiotest.h ├── pico_socket_udp.h ├── pico_dev_tap_windows.h ├── pico_dev_vde.h ├── pico_slaacv4.h ├── pico_strings.h ├── pico_dev_pcap.h ├── pico_sntp_client.h ├── pico_igmp.h ├── pico_olsr.h ├── pico_hotplug_detection.h ├── pico_ipfilter.h ├── pico_dev_ppp.h ├── pico_dhcp_client.h ├── pico_dhcp_server.h ├── pico_ipv6_nd.h ├── pico_socket_tcp.h ├── pico_udp.h ├── pico_arp.h ├── pico_802154.h ├── pico_6lowpan.h ├── pico_dev_loop.c ├── pico_dns_client.h ├── pico_dev_null.c ├── pico_mcast.h ├── pico_dev_mock.h ├── pico_strings.c ├── pico_posix.c ├── pico_nat.h ├── pico_dev_tun.c ├── pico_dev_pcap.c ├── pico_dev_tap_windows_private.h ├── pico_dev_ipc.c └── pico_tftp.h ├── MODTREE ├── include ├── arch │ ├── pico_cortex_m.h │ ├── pico_none.h │ ├── pico_linux.h │ ├── pico_arm9.h │ ├── pico_msp430.h │ ├── pico_avr.h │ ├── pico_dos.h │ ├── pico_pic32.h │ ├── pico_esp8266.h │ ├── pico_atsamd21j18.h │ ├── pico_pic24.h │ └── pico_generic_gcc.h ├── pico_socket_multicast.h ├── pico_eth.h ├── pico_md5.h ├── pico_module_eth.h ├── pico_constants.h ├── pico_device.h ├── pico_tree.h ├── pico_protocol.h └── pico_addressing.h ├── RFC └── get_all_rfc ├── .travis.yml ├── mkdeps.sh ├── CONTRIBUTING.md ├── stack └── pico_md5.c └── modcheck.py /rules/crc.mk: -------------------------------------------------------------------------------- 1 | OPTIONS+=-DPICO_SUPPORT_CRC 2 | -------------------------------------------------------------------------------- /rules/ipc.mk: -------------------------------------------------------------------------------- 1 | MOD_OBJ+=$(LIBBASE)modules/pico_dev_ipc.o 2 | -------------------------------------------------------------------------------- /rules/tap.mk: -------------------------------------------------------------------------------- 1 | MOD_OBJ+=$(LIBBASE)modules/pico_dev_tap.o 2 | -------------------------------------------------------------------------------- /rules/tun.mk: -------------------------------------------------------------------------------- 1 | MOD_OBJ+=$(LIBBASE)modules/pico_dev_tun.o 2 | -------------------------------------------------------------------------------- /rules/pcap.mk: -------------------------------------------------------------------------------- 1 | MOD_OBJ+=$(LIBBASE)modules/pico_dev_pcap.o 2 | -------------------------------------------------------------------------------- /rules/cyassl.mk: -------------------------------------------------------------------------------- 1 | OPTIONS+=-DPICO_SUPPORT_CYASSL 2 | LDFLAGS+=-lcyassl 3 | 4 | -------------------------------------------------------------------------------- /rules/polarssl.mk: -------------------------------------------------------------------------------- 1 | OPTIONS += -DPICO_SUPPORT_POLARSSL 2 | LDFLAGS += -lpolarssl 3 | -------------------------------------------------------------------------------- /rules/nat.mk: -------------------------------------------------------------------------------- 1 | OPTIONS+=-DPICO_SUPPORT_NAT 2 | MOD_OBJ+=$(LIBBASE)modules/pico_nat.o 3 | -------------------------------------------------------------------------------- /rules/ipv4.mk: -------------------------------------------------------------------------------- 1 | OPTIONS+=-DPICO_SUPPORT_IPV4 2 | MOD_OBJ+=$(LIBBASE)modules/pico_ipv4.o 3 | -------------------------------------------------------------------------------- /rules/mcast.mk: -------------------------------------------------------------------------------- 1 | OPTIONS+=-DPICO_SUPPORT_MCAST 2 | MOD_OBJ+=$(LIBBASE)modules/pico_mcast.o 3 | -------------------------------------------------------------------------------- /rules/mld.mk: -------------------------------------------------------------------------------- 1 | OPTIONS+=-DPICO_SUPPORT_MLD 2 | MOD_OBJ+=$(LIBBASE)modules/pico_mld.o 3 | 4 | -------------------------------------------------------------------------------- /rules/olsr.mk: -------------------------------------------------------------------------------- 1 | OPTIONS+=-DPICO_SUPPORT_OLSR 2 | MOD_OBJ+=$(LIBBASE)modules/pico_olsr.o 3 | -------------------------------------------------------------------------------- /rules/igmp.mk: -------------------------------------------------------------------------------- 1 | OPTIONS+=-DPICO_SUPPORT_IGMP 2 | MOD_OBJ+=$(LIBBASE)modules/pico_igmp.o 3 | 4 | -------------------------------------------------------------------------------- /rules/memory_manager.mk: -------------------------------------------------------------------------------- 1 | OPTIONS+=-DPICO_SUPPORT_MM 2 | MOD_OBJ+=$(LIBBASE)modules/pico_mm.o 3 | -------------------------------------------------------------------------------- /rules/ppp.mk: -------------------------------------------------------------------------------- 1 | OPTIONS+=-DPICO_SUPPORT_PPP 2 | MOD_OBJ+=$(LIBBASE)modules/pico_dev_ppp.o 3 | 4 | -------------------------------------------------------------------------------- /rules/devloop.mk: -------------------------------------------------------------------------------- 1 | OPTIONS+=-DPICO_SUPPORT_DEVLOOP 2 | MOD_OBJ+=$(LIBBASE)modules/pico_dev_loop.o 3 | -------------------------------------------------------------------------------- /rules/ipfilter.mk: -------------------------------------------------------------------------------- 1 | OPTIONS+=-DPICO_SUPPORT_IPFILTER 2 | MOD_OBJ+=$(LIBBASE)modules/pico_ipfilter.o 3 | -------------------------------------------------------------------------------- /rules/ipv4frag.mk: -------------------------------------------------------------------------------- 1 | OPTIONS+=-DPICO_SUPPORT_IPV4FRAG 2 | MOD_OBJ+=$(LIBBASE)modules/pico_fragments.o 3 | -------------------------------------------------------------------------------- /rules/ipv6frag.mk: -------------------------------------------------------------------------------- 1 | OPTIONS+=-DPICO_SUPPORT_IPV6FRAG 2 | MOD_OBJ+=$(LIBBASE)modules/pico_fragments.o 3 | -------------------------------------------------------------------------------- /rules/wolfssl.mk: -------------------------------------------------------------------------------- 1 | OPTIONS+=-DPICO_SUPPORT_CYASSL -DPICO_SUPPORT_WOLFSSL 2 | LDFLAGS+=-lwolfssl 3 | 4 | -------------------------------------------------------------------------------- /test/coverage.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ./test/units.sh || exit 1 3 | ./test/autotest.sh || exit 2 4 | exit 0 5 | -------------------------------------------------------------------------------- /rules/sntp_client.mk: -------------------------------------------------------------------------------- 1 | OPTIONS+=-DPICO_SUPPORT_SNTP_CLIENT 2 | MOD_OBJ+=$(LIBBASE)modules/pico_sntp_client.o 3 | -------------------------------------------------------------------------------- /docs/wiki_images/petri_net.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tass-belgium/picotcp/HEAD/docs/wiki_images/petri_net.gif -------------------------------------------------------------------------------- /docs/wiki_images/pico_frame.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tass-belgium/picotcp/HEAD/docs/wiki_images/pico_frame.png -------------------------------------------------------------------------------- /docs/wiki_images/port_to_os.dia: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tass-belgium/picotcp/HEAD/docs/wiki_images/port_to_os.dia -------------------------------------------------------------------------------- /docs/wiki_images/port_to_os.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tass-belgium/picotcp/HEAD/docs/wiki_images/port_to_os.png -------------------------------------------------------------------------------- /docs/user_manual/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | pdflatex user_doc.tex && pdflatex user_doc.tex && pdflatex user_doc.tex 4 | -------------------------------------------------------------------------------- /docs/wiki_images/picoTCP_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tass-belgium/picotcp/HEAD/docs/wiki_images/picoTCP_logo.png -------------------------------------------------------------------------------- /docs/wiki_images/Protocol input.dia: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tass-belgium/picotcp/HEAD/docs/wiki_images/Protocol input.dia -------------------------------------------------------------------------------- /docs/wiki_images/Protocol output.dia: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tass-belgium/picotcp/HEAD/docs/wiki_images/Protocol output.dia -------------------------------------------------------------------------------- /docs/wiki_images/Protocol_input.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tass-belgium/picotcp/HEAD/docs/wiki_images/Protocol_input.png -------------------------------------------------------------------------------- /docs/wiki_images/Protocol_output.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tass-belgium/picotcp/HEAD/docs/wiki_images/Protocol_output.png -------------------------------------------------------------------------------- /rules/mdns.mk: -------------------------------------------------------------------------------- 1 | OPTIONS+=-DPICO_SUPPORT_MDNS 2 | MOD_OBJ+=$(LIBBASE)modules/pico_mdns.o $(LIBBASE)modules/pico_dns_common.o 3 | -------------------------------------------------------------------------------- /rules/eth.mk: -------------------------------------------------------------------------------- 1 | OPTIONS+=-DPICO_SUPPORT_ETH 2 | MOD_OBJ+=$(LIBBASE)modules/pico_arp.o 3 | MOD_OBJ+=$(LIBBASE)modules/pico_ethernet.o 4 | -------------------------------------------------------------------------------- /docs/wiki_images/driver_stack_memory.dia: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tass-belgium/picotcp/HEAD/docs/wiki_images/driver_stack_memory.dia -------------------------------------------------------------------------------- /docs/wiki_images/driver_stack_memory.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tass-belgium/picotcp/HEAD/docs/wiki_images/driver_stack_memory.png -------------------------------------------------------------------------------- /rules/tcp.mk: -------------------------------------------------------------------------------- 1 | OPTIONS+=-DPICO_SUPPORT_TCP 2 | MOD_OBJ+=$(LIBBASE)modules/pico_tcp.o 3 | MOD_OBJ+=$(LIBBASE)modules/pico_socket_tcp.o 4 | -------------------------------------------------------------------------------- /rules/udp.mk: -------------------------------------------------------------------------------- 1 | OPTIONS+=-DPICO_SUPPORT_UDP 2 | MOD_OBJ+=$(LIBBASE)modules/pico_udp.o 3 | MOD_OBJ+=$(LIBBASE)modules/pico_socket_udp.o 4 | -------------------------------------------------------------------------------- /rules/dhcp_client.mk: -------------------------------------------------------------------------------- 1 | OPTIONS+=-DPICO_SUPPORT_DHCPC 2 | MOD_OBJ+=$(LIBBASE)modules/pico_dhcp_client.o $(LIBBASE)modules/pico_dhcp_common.o 3 | -------------------------------------------------------------------------------- /rules/dhcp_server.mk: -------------------------------------------------------------------------------- 1 | OPTIONS+=-DPICO_SUPPORT_DHCPD 2 | MOD_OBJ+=$(LIBBASE)modules/pico_dhcp_server.o $(LIBBASE)modules/pico_dhcp_common.o 3 | -------------------------------------------------------------------------------- /rules/dns_client.mk: -------------------------------------------------------------------------------- 1 | OPTIONS+=-DPICO_SUPPORT_DNS_CLIENT 2 | MOD_OBJ+=$(LIBBASE)modules/pico_dns_client.o $(LIBBASE)modules/pico_dns_common.o 3 | -------------------------------------------------------------------------------- /rules/slaacv4.mk: -------------------------------------------------------------------------------- 1 | OPTIONS+=-DPICO_SUPPORT_SLAACV4 2 | MOD_OBJ+=$(LIBBASE)modules/pico_slaacv4.o $(LIBBASE)modules/pico_hotplug_detection.o 3 | -------------------------------------------------------------------------------- /rules/dns_sd.mk: -------------------------------------------------------------------------------- 1 | OPTIONS+=-DPICO_SUPPORT_DNS_SD 2 | MOD_OBJ+=$(LIBBASE)modules/pico_dns_sd.o $(LIBBASE)modules/pico_mdns.o $(LIBBASE)modules/pico_dns_common.o -------------------------------------------------------------------------------- /rules/icmp4.mk: -------------------------------------------------------------------------------- 1 | OPTIONS+=-DPICO_SUPPORT_ICMP4 2 | MOD_OBJ+=$(LIBBASE)modules/pico_icmp4.o 3 | ifneq ($(PING),0) 4 | OPTIONS+=-DPICO_SUPPORT_PING 5 | endif 6 | -------------------------------------------------------------------------------- /rules/ipv6.mk: -------------------------------------------------------------------------------- 1 | OPTIONS+=-DPICO_SUPPORT_IPV6 -DPICO_SUPPORT_ICMP6 2 | MOD_OBJ+=$(LIBBASE)modules/pico_ipv6.o $(LIBBASE)modules/pico_ipv6_nd.o $(LIBBASE)modules/pico_icmp6.o 3 | include rules/ipv6frag.mk 4 | -------------------------------------------------------------------------------- /test/examples/noop.c: -------------------------------------------------------------------------------- 1 | /* NOOP */ 2 | #include 3 | void app_noop(void) 4 | { 5 | while(1) { 6 | pico_stack_tick(); 7 | usleep(2000); 8 | } 9 | } 10 | 11 | /* END NOOP */ 12 | -------------------------------------------------------------------------------- /test/README.md: -------------------------------------------------------------------------------- 1 | To run these tests on your linux system, you will have to install these dependencies: 2 | * vde2 3 | * libvdeplug2-dev 4 | * libpcap0.8-dev 5 | 6 | This will allow you to compile the 'make test' and run the tests 7 | -------------------------------------------------------------------------------- /test/python/http_server_linux.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | from topology import * 3 | 4 | T = Topology() 5 | net1 = Network(T, "pyt0") 6 | 7 | h2 = Host(T, net1, args="httpd") 8 | 9 | sleep(1) 10 | start(T) 11 | 12 | wait(h2) 13 | cleanup() 14 | -------------------------------------------------------------------------------- /test/python/noop.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | from topology import * 3 | 4 | T = Topology() 5 | net1 = Network(T, "pyt0") 6 | 7 | #h1 = Host(T, net1) 8 | h2 = Host(T, net1, args="noop") 9 | 10 | sleep(1) 11 | start(T) 12 | 13 | wait(h2) 14 | cleanup() 15 | -------------------------------------------------------------------------------- /test/python/ping.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | from topology import * 3 | 4 | T = Topology() 5 | net1 = Network(T) 6 | 7 | h1 = Host(T, net1) 8 | h2 = Host(T, net1, args="ping:172.16.1.1:") 9 | 10 | sleep(1) 11 | start(T) 12 | 13 | wait(h2) 14 | cleanup() 15 | -------------------------------------------------------------------------------- /test/dummy.c: -------------------------------------------------------------------------------- 1 | #include "pico_stack.h" 2 | 3 | #if defined(PICO_SUPPORT_RTOS) || defined (PICO_SUPPORT_PTHREAD) 4 | volatile uint32_t pico_ms_tick; 5 | #endif 6 | 7 | int main(void) 8 | { 9 | pico_stack_init(); 10 | pico_stack_tick(); 11 | return 0; 12 | } 13 | -------------------------------------------------------------------------------- /test/python/ping_linux.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | from topology import * 3 | 4 | T = Topology() 5 | net1 = Network(T, "pyt0") 6 | 7 | #h1 = Host(T, net1) 8 | h2 = Host(T, net1, args="ping:172.16.1.1:") 9 | 10 | sleep(1) 11 | start(T) 12 | 13 | wait(h2) 14 | cleanup() 15 | -------------------------------------------------------------------------------- /test/python/ping_delay.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | from topology import * 3 | 4 | T = Topology() 5 | net1 = Network(T) 6 | 7 | h1 = Host(T, net1, delay1="200") 8 | h2 = Host(T, net1, args="ping:172.16.1.1:") 9 | 10 | sleep(1) 11 | start(T) 12 | 13 | wait(h2) 14 | cleanup() 15 | -------------------------------------------------------------------------------- /test/python/tcpbench_rx_linux.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | from topology import * 3 | 4 | T = Topology() 5 | net1 = Network(T, "pyt0") 6 | 7 | h2 = Host(T, net1, args="tcpbench:r:6660:") 8 | 9 | sleep(1) 10 | raw_input("Press enter to continue ...") 11 | start(T) 12 | 13 | wait(h2) 14 | cleanup() 15 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. 2 | 3 | Released under the GNU General Public License, version 2, or (at your option) 4 | version 3. 5 | See LICENSE.GPLv2 and LICENSE.GPLv3 for details. 6 | 7 | Different licensing models may exist, at the sole discretion of 8 | the Copyright holders. 9 | -------------------------------------------------------------------------------- /test/python/udpecho.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # 3 | 4 | from topology import * 5 | 6 | T = Topology() 7 | net1 = Network(T,"udp0") 8 | echo = Host(T, net1, args="udpecho:172.16.1.2:7770:7770:1400:") 9 | 10 | 11 | sleep(1) 12 | raw_input("Press enter to continue ...") 13 | 14 | start(T) 15 | wait(echo) 16 | cleanup() 17 | -------------------------------------------------------------------------------- /test/python/tcpbench_tx_linux.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | from topology import * 3 | 4 | T = Topology() 5 | net1 = Network(T, "pyt0") 6 | 7 | #h1 = Host(T, net1) 8 | h3 = Host(T, net1, args="tcpbench:t:172.16.1.1:6660:") 9 | 10 | sleep(1) 11 | raw_input("Press enter to continue ...") 12 | start(T) 13 | 14 | wait(h3) 15 | cleanup() 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.d 2 | *.o 3 | *.a 4 | *.out 5 | *.swp 6 | tags 7 | build 8 | UNIT_* 9 | core 10 | core.* 11 | .DS_Store 12 | cscope.files 13 | cscope.out 14 | *.so 15 | *.aux 16 | *.pdf 17 | *.toc 18 | *.gz 19 | *.log 20 | *.pyc 21 | *.elf 22 | *.gcov 23 | *.gcda 24 | *.gcno 25 | *.expand 26 | *.pcap 27 | .ycm_extra_conf.py 28 | .clang_complete 29 | -------------------------------------------------------------------------------- /test/Makefile: -------------------------------------------------------------------------------- 1 | CC=gcc 2 | CFLAGS=-ggdb -I../build/include/ -L../build/lib/ -lpicotcp -lvdeplug 3 | APPNAME=test_tftp_app_client 4 | 5 | .PHONY: clean 6 | all: test_tftp_app_client 7 | test_tftp_app_client: test_tftp_app_client.o 8 | $(CC) -o test_tftp_app_client ../build/modules/pico_dev_vde.o $^ $(CFLAGS) 9 | clean: 10 | rm -f ${APPNAME}.o 11 | -------------------------------------------------------------------------------- /test/python/ping_nat.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | from topology import * 3 | 4 | T = Topology() 5 | net1 = Network(T, 'nat0') 6 | net2 = Network(T) 7 | 8 | 9 | h1 = Host(T, net1, args="ping:172.16.2.1:") 10 | h2 = Host(T, net2) 11 | router1 = Host(T, net1, net2, args="natbox:172.16.2.2:") 12 | 13 | sleep(1) 14 | start(T) 15 | 16 | wait(h1) 17 | cleanup() 18 | -------------------------------------------------------------------------------- /test/python/tcpbench.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # 3 | 4 | from topology import * 5 | 6 | T = Topology() 7 | net1 = Network(T) 8 | send1 = Host(T, net1, args="tcpbench:t:172.16.1.2:7770:") 9 | recv1 = Host(T, net1, args="tcpbench:r:7770:") 10 | 11 | 12 | sleep(1) 13 | #raw_input("Press enter to continue ...") 14 | 15 | start(T) 16 | wait(send1) 17 | cleanup() 18 | -------------------------------------------------------------------------------- /test/python/tcpecho_linux.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | from topology import * 3 | 4 | T = Topology() 5 | net1 = Network(T, "pyt0") 6 | 7 | #h1 = Host(T, net1) 8 | h2 = Host(T, net1, args="tcpecho:8888", delay1="20", loss1="0.01") 9 | #h3 = Host(T, net1, args="tcpbench:t:172.16.1.1:") 10 | 11 | sleep(1) 12 | start(T) 13 | 14 | #wait(h3) 15 | wait(h2) 16 | cleanup() 17 | -------------------------------------------------------------------------------- /test/python/tcpbench-tap.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # 3 | 4 | from topology import * 5 | 6 | T = Topology() 7 | net1 = Network(T, "pyt0") 8 | send1 = Host(T, net1, args="tcpbench:t:172.16.1.3:7770:") 9 | recv1 = Host(T, net1, args="tcpbench:r:7770:") 10 | 11 | 12 | sleep(1) 13 | raw_input("Press enter to continue ...") 14 | 15 | start(T) 16 | wait(send1) 17 | cleanup() 18 | -------------------------------------------------------------------------------- /test/python/tcpbench-delay.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # 3 | 4 | from topology import * 5 | 6 | T = Topology() 7 | net1 = Network(T, "vde0") 8 | 9 | send1 = Host(T, net1, args="tcpbench:t:172.16.1.3:7770:") 10 | recv1 = Host(T, net1, args="tcpbench:r:7770:", delay1="30", loss1="1") 11 | 12 | 13 | sleep(1) 14 | raw_input("Press enter to continue ...") 15 | 16 | start(T) 17 | wait(send1) 18 | cleanup() 19 | -------------------------------------------------------------------------------- /modules/pico_fragments.h: -------------------------------------------------------------------------------- 1 | #ifndef PICO_FRAGMENTS_H 2 | #define PICO_FRAGMENTS_H 3 | #include "pico_ipv4.h" 4 | #include "pico_ipv6.h" 5 | #include "pico_addressing.h" 6 | #include "pico_frame.h" 7 | 8 | void pico_ipv6_process_frag(struct pico_ipv6_exthdr *frag, struct pico_frame *f, uint8_t proto); 9 | void pico_ipv4_process_frag(struct pico_ipv4_hdr *hdr, struct pico_frame *f, uint8_t proto); 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /test/vde_sock_start_user.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | function help(){ 3 | echo 'Cmd line arguments can be:' 4 | echo 'start: to start the vde setup for the autotest.' 5 | echo 'stop: to cleanup the vde setup for the autotest.' 6 | exit 7 | } 8 | 9 | function start_vde(){ 10 | vde_switch -s /tmp/pic0.ctl -m 777 -M /tmp/pico.mgmt -d -hub 11 | vde_switch -s /tmp/pic1.ctl -m 777 -M /tmp/pici.mgmt -d -hub 12 | } 13 | 14 | start_vde 15 | 16 | -------------------------------------------------------------------------------- /docs/user_manual/chap_license.tex: -------------------------------------------------------------------------------- 1 | Unless you have received a written document by PicoTCP copyright holders stating otherwise, 2 | the software described in this document is distributed under the terms of the GNU General 3 | Public License version 2 only. 4 | 5 | The terms of the license are reported below. 6 | 7 | \begin{center} 8 | {\bf\large GNU General Public license} 9 | {\bf Version 2, June 1991} 10 | \end{center} 11 | \input {gpl-2.0} 12 | -------------------------------------------------------------------------------- /MODTREE: -------------------------------------------------------------------------------- 1 | RTOS: 2 | IPV4: ETH 3 | IPV6: 4 | DEVLOOP: 5 | CRC: 6 | ETH: 7 | TCP: IPV4 8 | UDP: IPV4 9 | IPV4FRAG: IPV4 10 | NAT: IPV4 UDP 11 | ICMP4: IPV4 12 | MCAST: UDP 13 | PING: ICMP4 14 | DHCP_CLIENT: UDP 15 | DHCP_SERVER: UDP 16 | DNS_CLIENT: UDP 17 | IPFILTER: IPV4 18 | OLSR: MCAST 19 | SLAACV4: IPV4 20 | SNTP_CLIENT: DNS_CLIENT 21 | TFTP: UDP 22 | MDNS: MCAST 23 | DNS_SD: MDNS 24 | AODV: IPV4 UDP 25 | PPP: IPV4 26 | 6LOWPAN: IPV6 27 | IEEE802154: 6LOWPAN 28 | -------------------------------------------------------------------------------- /include/arch/pico_cortex_m.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved. 3 | See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage. 4 | 5 | *********************************************************************/ 6 | #ifndef _INCLUDE_PICO_CORTEX_M 7 | #define _INCLUDE_PICO_CORTEX_M 8 | 9 | #include "pico_generic_gcc.h" 10 | 11 | #endif /* PICO_CORTEX_M */ 12 | 13 | -------------------------------------------------------------------------------- /RFC/get_all_rfc: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | wget -O rfc4614.txt http://tools.ietf.org/rfc/rfc4614.txt 4 | 5 | 6 | for RFC in `grep "\[RFC" rfc4614.txt | sed -e "s/^.*RFC/rfc/" | grep -v "rfc \|rfc$" | sed -e "s/\].*$/.txt/g" |sort |uniq`; do 7 | wget -O ${RFC} http://tools.ietf.org/rfc/${RFC} 8 | done 9 | 10 | wget -O rfc3927.txt http://tools.ietf.org/rfc/rfc3927.txt 11 | 12 | # Get PPP related RFC's 13 | for RFC in $(echo 1332 1334 1661 1662 1877 1994 | sed -r "s/[^ ]+/rfc&.txt/g"); do 14 | wget -O ${RFC} http://tools.ietf.org/rfc/${RFC} 15 | done 16 | -------------------------------------------------------------------------------- /modules/pico_dev_radio_mgr.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved. 3 | See LICENSE and COPYING for usage. 4 | 5 | Authors: Jelle De Vleeschouwer 6 | *********************************************************************/ 7 | 8 | #ifndef __PICO_DEV_RADIO_MGR_H_ 9 | #define __PICO_DEV_RADIO_MGR_H_ 10 | 11 | /* Start listening for TCP connection requests on 'LISTENING_PORT' */ 12 | int pico_radio_mgr_start(void); 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /include/pico_socket_multicast.h: -------------------------------------------------------------------------------- 1 | #ifndef PICO_SOCKET_MULTICAST_H 2 | #define PICO_SOCKET_MULTICAST_H 3 | int pico_socket_mcast_filter(struct pico_socket *s, union pico_address *mcast_group, union pico_address *src); 4 | void pico_multicast_delete(struct pico_socket *s); 5 | int pico_setsockopt_mcast(struct pico_socket *s, int option, void *value); 6 | int pico_getsockopt_mcast(struct pico_socket *s, int option, void *value); 7 | int pico_udp_get_mc_ttl(struct pico_socket *s, uint8_t *ttl); 8 | int pico_udp_set_mc_ttl(struct pico_socket *s, void *_ttl); 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /modules/pico_dev_loop.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved. 3 | See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage. 4 | 5 | *********************************************************************/ 6 | #ifndef INCLUDE_PICO_LOOP 7 | #define INCLUDE_PICO_LOOP 8 | #include "pico_config.h" 9 | #include "pico_device.h" 10 | 11 | void pico_loop_destroy(struct pico_device *loop); 12 | struct pico_device *pico_loop_create(void); 13 | 14 | #endif 15 | 16 | -------------------------------------------------------------------------------- /modules/pico_dev_tap.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved. 3 | See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage. 4 | 5 | *********************************************************************/ 6 | #ifndef INCLUDE_PICO_TAP 7 | #define INCLUDE_PICO_TAP 8 | #include "pico_config.h" 9 | #include "pico_device.h" 10 | 11 | void pico_tap_destroy(struct pico_device *tap); 12 | struct pico_device *pico_tap_create(char *name); 13 | 14 | #endif 15 | 16 | -------------------------------------------------------------------------------- /modules/pico_dev_tun.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved. 3 | See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage. 4 | 5 | *********************************************************************/ 6 | #ifndef INCLUDE_PICO_TUN 7 | #define INCLUDE_PICO_TUN 8 | #include "pico_config.h" 9 | #include "pico_device.h" 10 | 11 | void pico_tun_destroy(struct pico_device *tun); 12 | struct pico_device *pico_tun_create(char *name); 13 | 14 | #endif 15 | 16 | -------------------------------------------------------------------------------- /modules/pico_dev_null.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved. 3 | See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage. 4 | 5 | *********************************************************************/ 6 | #ifndef INCLUDE_PICO_NULL 7 | #define INCLUDE_PICO_NULL 8 | #include "pico_config.h" 9 | #include "pico_device.h" 10 | 11 | void pico_null_destroy(struct pico_device *null); 12 | struct pico_device *pico_null_create(const char *name); 13 | 14 | #endif 15 | 16 | -------------------------------------------------------------------------------- /modules/pico_ethernet.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved. 3 | See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage. 4 | 5 | . 6 | 7 | Authors: Daniele Lacamera 8 | *********************************************************************/ 9 | 10 | #ifndef INCLUDE_PICO_ETHERNET 11 | #define INCLUDE_PICO_ETHERNET 12 | 13 | #include "pico_config.h" 14 | #include "pico_frame.h" 15 | 16 | extern struct pico_protocol pico_proto_ethernet; 17 | 18 | #endif /* INCLUDE_PICO_ETHERNET */ 19 | -------------------------------------------------------------------------------- /modules/pico_dev_ipc.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved. 3 | See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage. 4 | 5 | *********************************************************************/ 6 | #ifndef INCLUDE_PICO_IPC 7 | #define INCLUDE_PICO_IPC 8 | #include "pico_config.h" 9 | #include "pico_device.h" 10 | 11 | void pico_ipc_destroy(struct pico_device *ipc); 12 | struct pico_device *pico_ipc_create(const char *sock_path, const char *name, const uint8_t *mac); 13 | 14 | #endif 15 | 16 | -------------------------------------------------------------------------------- /include/pico_eth.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved. 3 | See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage. 4 | 5 | *********************************************************************/ 6 | #ifndef INCLUDE_PICO_ETH 7 | #define INCLUDE_PICO_ETH 8 | #include "pico_addressing.h" 9 | #include "pico_ipv4.h" 10 | #include "pico_ipv6.h" 11 | 12 | 13 | PACKED_STRUCT_DEF pico_eth_hdr { 14 | uint8_t daddr[6]; 15 | uint8_t saddr[6]; 16 | uint16_t proto; 17 | }; 18 | 19 | #define PICO_SIZE_ETHHDR 14 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /test/pico_faulty.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "pico_faulty.h" 5 | 6 | /* #warning "COMPILING for MEMORY TESTS!" */ 7 | 8 | uint32_t mm_failure_count = 0; 9 | uint32_t cur_mem, max_mem; 10 | 11 | static int called_atexit = 0; 12 | 13 | 14 | void memory_stats(void) 15 | { 16 | fprintf(stderr, " ################ MAX MEMORY USED in this test: %u\n", max_mem); 17 | 18 | } 19 | 20 | int pico_set_mm_failure(uint32_t nxt) 21 | { 22 | if (!called_atexit) { 23 | atexit(memory_stats); 24 | called_atexit++; 25 | } 26 | 27 | mm_failure_count = nxt; 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | before_install: 2 | - sudo apt-get update -qq 3 | - sudo apt-get install -y vde2 check libvdeplug2-dev libpcap-dev psmisc 4 | - sudo pip install cpp-coveralls 5 | - make clean 6 | - rm -f *.gc* 7 | 8 | install: make GCOV=1 && make units ARCH=faulty GCOV=1 && make test GCOV=1 9 | language: c 10 | script: 11 | - ./test/coverage.sh 12 | after_success: 13 | - coveralls --exclude test/ --exclude modules/ptsocket --exclude build --exclude modules/pico_dev_mock.c --exclude modules/pico_dev_null.c --exclude modules/pico_dev_pcap.c --exclude modules/pico_dev_tap_windows.c --exclude modules/pico_dev_tun.c --gcov-options='\-lp' 14 | -------------------------------------------------------------------------------- /modules/pico_dev_radiotest.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved. 3 | See LICENSE and COPYING for usage. 4 | 5 | Authors: Daniele Lacamera, Jelle De Vleeschouwer 6 | *********************************************************************/ 7 | 8 | #ifndef INCLUDE_PICO_DEV_RADIOTEST 9 | #define INCLUDE_PICO_DEV_RADIOTEST 10 | 11 | #include "pico_device.h" 12 | #include "pico_config.h" 13 | 14 | struct pico_device *pico_radiotest_create(uint8_t addr, uint8_t area0, uint8_t area1, int loop, char *dump); 15 | 16 | #endif /* INCLUDE_PICO_DEV_RADIOTEST */ 17 | -------------------------------------------------------------------------------- /include/pico_md5.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | * PicoTCP. Copyright (c) 2015-2017 Altran Intelligent Systems. Some rights reserved. 3 | * See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage. 4 | * 5 | * Authors: Daniele Lacamera 6 | * *********************************************************************/ 7 | 8 | #ifndef PICO_MD5_INCLUDE 9 | #define PICO_MD5_INCLUDE 10 | 11 | #include 12 | #include 13 | 14 | void pico_md5sum(uint8_t *dst, const uint8_t *src, size_t len); 15 | void pico_register_md5sum(void (*md5)(uint8_t *, const uint8_t *, size_t)); 16 | 17 | #endif /* PICO_MD5_INCLUDE */ 18 | -------------------------------------------------------------------------------- /modules/pico_socket_udp.h: -------------------------------------------------------------------------------- 1 | #ifndef PICO_SOCKET_UDP_H 2 | #define PICO_SOCKET_UDP_H 3 | 4 | struct pico_socket *pico_socket_udp_open(void); 5 | int pico_socket_udp_deliver(struct pico_sockport *sp, struct pico_frame *f); 6 | 7 | 8 | #ifdef PICO_SUPPORT_UDP 9 | int pico_setsockopt_udp(struct pico_socket *s, int option, void *value); 10 | int pico_getsockopt_udp(struct pico_socket *s, int option, void *value); 11 | # define pico_socket_udp_recv(s, buf, len, addr, port) pico_udp_recv(s, buf, len, addr, port, NULL) 12 | #else 13 | # define pico_socket_udp_recv(...) (0) 14 | # define pico_getsockopt_udp(...) (-1) 15 | # define pico_setsockopt_udp(...) (-1) 16 | #endif 17 | 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /docs/user_manual/template_api.tex: -------------------------------------------------------------------------------- 1 | \section{MODULE} 2 | 3 | % Short description/overview of module functions 4 | 5 | 6 | \subsection{FUNCTION} 7 | 8 | \subsubsection*{Description} 9 | 10 | \subsubsection*{Function prototype} 11 | 12 | \subsubsection*{Parameters} 13 | 14 | \subsubsection*{Return value} 15 | 16 | \subsubsection*{Errors} 17 | 18 | \subsubsection*{Example} 19 | 20 | 21 | \subsection{FUNCTION} 22 | 23 | \subsubsection*{Description} 24 | 25 | \subsubsection*{Function prototype} 26 | 27 | \subsubsection*{Parameters} 28 | 29 | \subsubsection*{Return value} 30 | 31 | \subsubsection*{Errors} 32 | 33 | \subsubsection*{Example} 34 | 35 | 36 | \subsection{FUNCTION} 37 | 38 | % ... -------------------------------------------------------------------------------- /modules/pico_dev_tap_windows.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | PicoTCP. Copyright (c) 2014-2017 Altran Intelligent Systems. Some rights reserved. 3 | See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage. 4 | 5 | *********************************************************************/ 6 | #ifndef INCLUDE_PICO_TAP 7 | #define INCLUDE_PICO_TAP 8 | #include "pico_config.h" 9 | #include "pico_device.h" 10 | 11 | /* will look for the first TAP device available, and use it */ 12 | struct pico_device *pico_tap_create(char *name, uint8_t *mac); 13 | /* TODO: not implemented yet */ 14 | /* void pico_tap_destroy(struct pico_device *null); */ 15 | 16 | #endif 17 | 18 | -------------------------------------------------------------------------------- /modules/pico_dev_vde.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved. 3 | See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage. 4 | 5 | 6 | *********************************************************************/ 7 | #ifndef INCLUDE_PICO_VDE 8 | #define INCLUDE_PICO_VDE 9 | #include "pico_config.h" 10 | #include "pico_device.h" 11 | #include 12 | 13 | void pico_vde_destroy(struct pico_device *vde); 14 | struct pico_device *pico_vde_create(char *sock, char *name, uint8_t *mac); 15 | void pico_vde_set_packetloss(struct pico_device *dev, uint32_t in_pct, uint32_t out_pct); 16 | 17 | #endif 18 | 19 | -------------------------------------------------------------------------------- /test/python/zmq_linux.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | from topology import * 3 | import zmq 4 | import sys 5 | 6 | T = Topology() 7 | net1 = Network(T, "pyt0") 8 | 9 | #h1 = Host(T, net1) 10 | h2 = Host(T, net1, args="zeromq_prod:") 11 | 12 | sleep(1) 13 | raw_input("Press enter to continue ...") 14 | start(T) 15 | 16 | # Zeromq part 17 | ctx = zmq.Context() 18 | z = ctx.socket(zmq.SUB) 19 | z.setsockopt(zmq.SUBSCRIBE, "") 20 | z.connect("tcp://172.16.1.2:1207") 21 | print "In the loop..." 22 | for i in range(20): 23 | if z.poll(20000) == 0: 24 | print "Timeout!!!" 25 | cleanup() 26 | sys.exit(1) 27 | else: 28 | msg = z.recv() 29 | print "Recvd msg len=%d content: %s" % (len(msg), msg) 30 | 31 | 32 | 33 | 34 | cleanup() 35 | -------------------------------------------------------------------------------- /modules/pico_slaacv4.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved. 3 | See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage. 4 | 5 | Authors: Bogdan Lupu 6 | *********************************************************************/ 7 | #ifndef INCLUDE_PICO_SUPPORT_SLAACV4 8 | #define INCLUDE_PICO_SUPPORT_SLAACV4 9 | #include "pico_arp.h" 10 | 11 | #define PICO_SLAACV4_SUCCESS 0 12 | #define PICO_SLAACV4_ERROR 1 13 | 14 | int pico_slaacv4_claimip(struct pico_device *dev, void (*cb)(struct pico_ip4 *ip, uint8_t code)); 15 | void pico_slaacv4_unregisterip(void); 16 | 17 | #endif /* _INCLUDE_PICO_SUPPORT_SLAACV4 */ 18 | 19 | -------------------------------------------------------------------------------- /modules/pico_strings.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | PicoTCP. Copyright (c) 2015-2017 Altran ISY BeNeLux. Some rights reserved. 3 | See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage. 4 | 5 | . 6 | 7 | Author: Michele Di Pede 8 | *********************************************************************/ 9 | 10 | #ifndef PICO_STRINGS_H 11 | #define PICO_STRINGS_H 12 | #include 13 | #include 14 | 15 | char *get_string_terminator_position(char *const block, size_t len); 16 | int pico_strncasecmp(const char *const str1, const char *const str2, size_t n); 17 | size_t pico_strnlen(const char *str, size_t n); 18 | 19 | int num2string(int32_t num, char *buf, int len); 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /include/arch/pico_none.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved. 3 | See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage. 4 | *********************************************************************/ 5 | 6 | #ifndef PICO_SUPPORT_ARCHNONE 7 | #define PICO_SUPPORT_ARCHNONE 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #define dbg(...) do {} while(0) 15 | #define pico_zalloc(x) NULL 16 | #define pico_free(x) do {} while(0) 17 | #define PICO_TIME() 666 18 | #define PICO_TIME_MS() 666000 19 | #define PICO_IDLE() do {} while(0) 20 | 21 | #endif /* PICO_SUPPORT_ARCHNONE */ 22 | 23 | -------------------------------------------------------------------------------- /test/vde_sock_start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | gksu "vdecmd -s /tmp/pico.mgmt shutdown" 4 | gksu "vdecmd -s /tmp/pico1.mgmt shutdown" 5 | gksu "vde_switch -t pic0 -s /tmp/pic0.ctl -m 777 -M /tmp/pico.mgmt -d -hub" 6 | gksu "vde_switch -t pic1 -x -s /tmp/pic1.ctl -m 777 -M /tmp/pico1.mgmt -d -hub" 7 | 8 | # we prefer to use ip over ifconfig (which is obsolete), but the script has to work when ip is not available as well 9 | USINGIP=1 10 | command -v ip >/dev/null 2>&1 || USINGIP=0 11 | 12 | if [ $USINGIP -eq 1 ]; 13 | then 14 | gksu "ip addr add 10.40.0.1/24 dev pic0" 15 | gksu "ip addr add 10.50.0.1/24 dev pic1" 16 | else 17 | gksu "ifconfig pic0 10.40.0.1 netmask 255.255.255.0" 18 | gksu "ifconfig pic1 10.50.0.1 netmask 255.255.255.0" 19 | fi 20 | #ping 10.40.0.3 & 21 | 22 | 23 | -------------------------------------------------------------------------------- /modules/pico_dev_pcap.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved. 3 | See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage. 4 | 5 | 6 | Author: Daniele Lacamera 7 | *********************************************************************/ 8 | #ifndef INCLUDE_PICO_PCAP 9 | #define INCLUDE_PICO_PCAP 10 | #include "pico_config.h" 11 | #include "pico_device.h" 12 | #include 13 | 14 | void pico_pcap_destroy(struct pico_device *pcap); 15 | struct pico_device *pico_pcap_create_live(char *ifname, char *name, uint8_t *mac); 16 | struct pico_device *pico_pcap_create_fromfile(char *filename, char *name, uint8_t *mac); 17 | 18 | #endif 19 | 20 | -------------------------------------------------------------------------------- /include/arch/pico_linux.h: -------------------------------------------------------------------------------- 1 | #ifndef PICO_SUPPORT_LINUX 2 | #define PICO_SUPPORT_LINUX 3 | 4 | #include "linux/types.h" 5 | #include "linux/mm.h" 6 | #include "linux/slab.h" 7 | #include "linux/jiffies.h" 8 | 9 | #define dbg printk 10 | 11 | #define pico_zalloc(x) kcalloc(x, 1, GFP_ATOMIC) /* All allocations are GFP_ATOMIC for now */ 12 | #define pico_free(x) kfree(x) 13 | 14 | 15 | static inline unsigned long PICO_TIME(void) 16 | { 17 | return (unsigned long)(jiffies_to_msecs(jiffies) / 1000); 18 | } 19 | 20 | static inline unsigned long PICO_TIME_MS(void) 21 | { 22 | return (unsigned long)jiffies_to_msecs(jiffies); 23 | } 24 | 25 | static inline void PICO_IDLE(void) 26 | { 27 | unsigned long now = jiffies; 28 | while (now == jiffies) { 29 | ; 30 | } 31 | } 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /docs/user_manual/layout1.tex: -------------------------------------------------------------------------------- 1 | % Altran Intelligent Systems 2 | % 3 | % LAYOUT TEXT 4 | % =========== 5 | 6 | %\documentclass[11pt, a4paper, openright,oneside]{book} 7 | \documentclass[11pt, a4paper,oneside]{report} 8 | 9 | \usepackage[english]{babel} 10 | \usepackage[latin1]{inputenc} 11 | %\usepackage[T1]{fontenc} 12 | \usepackage{graphicx} 13 | \usepackage{natbib} 14 | %\usepackage{hyperref} 15 | \usepackage[hang,flushmargin]{footmisc} 16 | 17 | \usepackage{fullpage} 18 | \parskip 4pt % sets spacing between paragraphs 19 | \parindent 0pt % sets leading space for paragraphs 20 | 21 | \makeatletter 22 | \renewcommand{\@makechapterhead}[1]{% 23 | %\vspace*{50 pt}% 24 | {\setlength{\parindent}{0pt} \raggedright \normalfont 25 | \bfseries\Huge\thechapter.\ #1 26 | \par\nobreak\vspace{40 pt}}} 27 | \makeatother 28 | -------------------------------------------------------------------------------- /mkdeps.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ "$#" -eq 0 ]; then 4 | echo "Supply PREFIX for building pico_defines.h" 5 | exit 1 6 | fi 7 | 8 | PREFIX=$1 9 | shift 10 | echo "/* PicoTCP - Definition file - DO NOT EDIT */" >$PREFIX/include/pico_defines.h 11 | echo "/* This file is automatically generated at compile time */" >>$PREFIX/include/pico_defines.h 12 | echo "#ifndef PICO_DEFINES_H" >>$PREFIX/include/pico_defines.h 13 | echo "#define PICO_DEFINES_H" >>$PREFIX/include/pico_defines.h 14 | echo >>$PREFIX/include/pico_defines.h 15 | 16 | for i in $@; do 17 | if (echo $i | grep "^-D" |grep PICO_SUPPORT >/dev/null); then 18 | my_def=`echo $i |sed -e "s/-D//g"` 19 | echo "#define $my_def" >> $PREFIX/include/pico_defines.h 20 | fi 21 | done 22 | echo "#endif" >>$PREFIX/include/pico_defines.h 23 | -------------------------------------------------------------------------------- /test/perf.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | THRESHOLD=300 3 | sh ./test/vde_sock_start_user.sh 4 | sleep 2 5 | 6 | (iperf -s >/tmp/iperf.log)& 7 | ./build/test/picoapp.elf --vde pic0:/tmp/pic0.ctl:10.50.0.2:255.255.255.0:10.50.0.1: --app iperfc:10.50.0.1: &>/dev/null 8 | killall iperf 9 | RES=`cat /tmp/iperf.log |grep Mbits |sed -e "s/.*Bytes//g" |sed -e "s/^[ ]*//g"` 10 | SPEED=`echo $RES | cut -d " " -f 1` 11 | UNITS=`echo $RES | cut -d " " -f 2` 12 | 13 | if [ ["$UNITS"] != ["Mbits/sec"] ]; then 14 | echo "Wrong test result units: expected Mbits/sec, got $UNITS" 15 | exit 1 16 | fi 17 | 18 | if (test $SPEED -lt $THRESHOLD); then 19 | echo "Speed too low: expected $THRESHOLD MBits/s, got $SPEED $UNITS" 20 | exit 2 21 | fi 22 | 23 | echo Test result: $SPEED $UNITS 24 | 25 | rm -f /tmp/iperf.log 26 | exit 0 27 | -------------------------------------------------------------------------------- /docs/user_manual/README.md: -------------------------------------------------------------------------------- 1 | Downloading the manual 2 | ---------------------- 3 | 4 | With every git commit, we rebuild the documentation and make the [user_doc.pdf](http://162.13.84.104/user_doc.pdf) file (click to download) publicly available. 5 | 6 | If for some reason, you're looking for an older version of the documentation, please check out the wanted commit in git, and compile the manual as described below. 7 | 8 | Compiling the manual 9 | -------------------- 10 | 11 | The picoTCP user manual is written in LaTeX, which needs to be compiled to get a readable version. 12 | First and foremost you need the compiler and some packages: 13 | * sudo apt-get install texlive 14 | * sudo apt-get install texlive-latex-extra 15 | 16 | Now, cd into docs/user_manual and do 17 | * ./build.sh 18 | 19 | A user_doc.pdf should be generated in the current directory 20 | 21 | -------------------------------------------------------------------------------- /modules/pico_sntp_client.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved. 3 | See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage. 4 | 5 | Author: Toon Stegen 6 | *********************************************************************/ 7 | #ifndef INCLUDE_PICO_SNTP_CLIENT 8 | #define INCLUDE_PICO_SNTP_CLIENT 9 | 10 | #include "pico_config.h" 11 | #include "pico_protocol.h" 12 | 13 | struct pico_timeval 14 | { 15 | pico_time tv_sec; 16 | pico_time tv_msec; 17 | }; 18 | 19 | int pico_sntp_sync(const char *sntp_server, void (*cb_synced)(pico_err_t status)); 20 | int pico_sntp_sync_ip(union pico_address *sntp_addr, void (*cb_synced)(pico_err_t status)); 21 | int pico_sntp_gettimeofday(struct pico_timeval *tv); 22 | 23 | #endif /* _INCLUDE_PICO_SNTP_CLIENT */ 24 | -------------------------------------------------------------------------------- /include/pico_module_eth.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved. 3 | See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage. 4 | 5 | *********************************************************************/ 6 | #ifndef PICO_MODULE_IPV4_H 7 | #define PICO_MODULE_IPV4_H 8 | 9 | struct pico_arp_entry { 10 | struct eth dest; 11 | #ifdef PICO_CONFIG_IPV4 12 | struct ipv4 addr_ipv4; 13 | #endif 14 | RB_ENTRY(pico_arp_entry) node; 15 | }; 16 | 17 | /* Configured device */ 18 | struct pico_eth_link { 19 | struct pico_device *dev; 20 | struct eth address; 21 | struct eth netmask; 22 | RB_ENTRY(pico_eth_link) node; 23 | }; 24 | 25 | #ifndef IS_MODULE_ETH 26 | # define _mod extern 27 | #else 28 | # define _mod 29 | #endif 30 | _mod struct pico_module pico_module_eth; 31 | #undef _mod 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | 2 | External contributions to picoTCP are very welcome. We do, however, ask that you sign the Contributor License Agreement. 3 | We don't ask you to sign away your copyright. The CLA simply grants us an additional license on the code you wrote. This allows us to also use picoTCP in commercial projects, which enables us to keep investing time and money in creating a better TCP/IP stack. 4 | 5 | Please read the [Agreement](https://docs.google.com/forms/d/1-z6lsT75l6ZIrgHGEWrWdHylJ6xxpjc7FwGfL2ilDFU/viewform), and if you agree with it, fill in your information. 6 | You will receive a mail with a timestamp. Please modify our [CLA confirmation page](https://github.com/tass-belgium/picotcp/wiki/picoTCP-CLA-Confirmation-Page), adding the timestamp and your github username. This way we can be sure that nobody else filled in your info in the form. 7 | 8 | Pull requests by people who haven't signed the CLA will, unfortunately, have to be rejected. 9 | -------------------------------------------------------------------------------- /modules/pico_igmp.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved. 3 | See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage. 4 | 5 | . 6 | 7 | Authors: Kristof Roelants, Simon Maes, Brecht Van Cauwenberghe 8 | *********************************************************************/ 9 | 10 | #ifndef INCLUDE_PICO_IGMP 11 | #define INCLUDE_PICO_IGMP 12 | 13 | #define PICO_IGMPV1 1 14 | #define PICO_IGMPV2 2 15 | #define PICO_IGMPV3 3 16 | 17 | #define PICO_IGMP_STATE_CREATE 1 18 | #define PICO_IGMP_STATE_UPDATE 2 19 | #define PICO_IGMP_STATE_DELETE 3 20 | 21 | #define PICO_IGMP_QUERY_INTERVAL 125 22 | 23 | extern struct pico_protocol pico_proto_igmp; 24 | 25 | int pico_igmp_state_change(struct pico_ip4 *mcast_link, struct pico_ip4 *mcast_group, uint8_t filter_mode, struct pico_tree *_MCASTFilter, uint8_t state); 26 | #endif /* _INCLUDE_PICO_IGMP */ 27 | -------------------------------------------------------------------------------- /test/examples/natbox.c: -------------------------------------------------------------------------------- 1 | #include "utils.h" 2 | #include 3 | #include 4 | 5 | /*** START NATBOX ***/ 6 | void app_natbox(char *arg) 7 | { 8 | char *dest = NULL; 9 | struct pico_ip4 ipdst, pub_addr, priv_addr; 10 | struct pico_ipv4_link *link; 11 | 12 | cpy_arg(&dest, arg); 13 | if (!dest) { 14 | fprintf(stderr, "natbox needs the following format: natbox:dst_addr\n"); 15 | exit(255); 16 | } 17 | 18 | pico_string_to_ipv4(dest, &ipdst.addr); 19 | link = pico_ipv4_link_get(&ipdst); 20 | if (!link) { 21 | fprintf(stderr, "natbox: Destination not found.\n"); 22 | exit(255); 23 | } 24 | 25 | pico_ipv4_nat_enable(link); 26 | pico_string_to_ipv4("10.50.0.10", &pub_addr.addr); 27 | pico_string_to_ipv4("10.40.0.08", &priv_addr.addr); 28 | pico_ipv4_port_forward(pub_addr, short_be(5555), priv_addr, short_be(6667), PICO_PROTO_UDP, PICO_NAT_PORT_FORWARD_ADD); 29 | fprintf(stderr, "natbox: started.\n"); 30 | } 31 | /*** END NATBOX ***/ 32 | -------------------------------------------------------------------------------- /include/arch/pico_arm9.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved. 3 | See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage. 4 | *********************************************************************/ 5 | #define dbg(...) do {} while(0) 6 | 7 | /******************/ 8 | 9 | /*** MACHINE CONFIGURATION ***/ 10 | /* Temporary (POSIX) stuff. */ 11 | #include 12 | #include 13 | 14 | extern volatile uint32_t __str9_tick; 15 | 16 | #define pico_native_malloc(x) calloc(x, 1) 17 | #define pico_native_free(x) free(x) 18 | 19 | static inline unsigned long PICO_TIME(void) 20 | { 21 | register uint32_t tick = __str9_tick; 22 | return tick / 1000; 23 | } 24 | 25 | static inline unsigned long PICO_TIME_MS(void) 26 | { 27 | return __str9_tick; 28 | } 29 | 30 | static inline void PICO_IDLE(void) 31 | { 32 | unsigned long tick_now = __str9_tick; 33 | while(tick_now == __str9_tick) ; 34 | } 35 | 36 | -------------------------------------------------------------------------------- /include/arch/pico_msp430.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved. 3 | See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage. 4 | 5 | *********************************************************************/ 6 | #ifndef _INCLUDE_PICO_LPC 7 | #define _INCLUDE_PICO_LPC 8 | 9 | #include 10 | #include 11 | #include 12 | #include "pico_constants.h" 13 | 14 | extern pico_time msp430_time_s(void); 15 | extern pico_time msp430_time_ms(void); 16 | extern void *malloc(size_t); 17 | extern void free(void *); 18 | 19 | 20 | #define PICO_TIME() msp430_time_s() 21 | #define PICO_TIME_MS() msp430_time_ms() 22 | #define PICO_IDLE() do {} while(0) 23 | 24 | #define pico_free(x) free(x) 25 | 26 | static inline void *pico_zalloc(size_t size) 27 | { 28 | void *ptr = malloc(size); 29 | 30 | if(ptr) 31 | memset(ptr, 0u, size); 32 | 33 | return ptr; 34 | } 35 | 36 | #define dbg(...) 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /test/python/dhcp.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # dhcp.py 3 | # Butterfly-like topology test for dhcp 4 | # One DHCP server, serving on two interface 5 | # Eigth DHCP clients, four on each network 6 | # 7 | # s1----@ @----r1 8 | # s2-----\__ DHCP __/-----r2 9 | # s3-----/ \-----r3 10 | # s4----@ @----r4 11 | # 12 | 13 | 14 | from topology import * 15 | 16 | T = Topology() 17 | net1 = Network(T, "pyt1") 18 | net2 = Network(T, "pyt2") 19 | 20 | server = Host(T, net1, net2, args="dhcpserver:eth1:172.16.1.2:255.255.255.0:64:128:eth2:172.16.2.2:255.255.255.0:64:128") 21 | 22 | s1 = Host(T, net1, args="dhcpclient:eth1") 23 | s2 = Host(T, net1, args="dhcpclient:eth1") 24 | s3 = Host(T, net1, args="dhcpclient:eth1") 25 | s4 = Host(T, net1, args="dhcpclient:eth1") 26 | r1 = Host(T, net2, args="dhcpclient:eth1") 27 | r2 = Host(T, net2, args="dhcpclient:eth1") 28 | r3 = Host(T, net2, args="dhcpclient:eth1") 29 | r4 = Host(T, net2, args="dhcpclient:eth1") 30 | 31 | raw_input("Press enter to continue ...") 32 | start(T) 33 | 34 | wait(server) 35 | 36 | cleanup() 37 | -------------------------------------------------------------------------------- /modules/pico_olsr.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved. 3 | See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage. 4 | 5 | Authors: Daniele Lacamera 6 | *********************************************************************/ 7 | #ifndef PICO_OLSR_H 8 | #define PICO_OLSR_H 9 | 10 | 11 | /* Objects */ 12 | struct olsr_route_entry 13 | { 14 | struct olsr_route_entry *next; 15 | uint32_t time_left; 16 | struct pico_ip4 destination; 17 | struct olsr_route_entry *gateway; 18 | struct pico_device *iface; 19 | uint16_t metric; 20 | uint8_t link_type; 21 | struct olsr_route_entry *children; 22 | uint16_t ansn; 23 | uint16_t seq; 24 | uint8_t lq, nlq; 25 | uint8_t *advertised_tc; 26 | }; 27 | 28 | 29 | void pico_olsr_init(void); 30 | int pico_olsr_add(struct pico_device *dev); 31 | struct olsr_route_entry *olsr_get_ethentry(struct pico_device *vif); 32 | #endif 33 | -------------------------------------------------------------------------------- /modules/pico_hotplug_detection.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved. 3 | See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage. 4 | 5 | Authors: Frederik Van Slycken 6 | *********************************************************************/ 7 | #ifndef INCLUDE_PICO_SUPPORT_HOTPLUG 8 | #define INCLUDE_PICO_SUPPORT_HOTPLUG 9 | #include "pico_stack.h" 10 | 11 | #define PICO_HOTPLUG_EVENT_UP 1 /* link went up */ 12 | #define PICO_HOTPLUG_EVENT_DOWN 2 /* link went down */ 13 | 14 | #define PICO_HOTPLUG_INTERVAL 100 15 | 16 | /* register your callback to be notified of hotplug events on a certain device. 17 | * Note that each callback will be called at least once, shortly after adding, for initialization. 18 | */ 19 | int pico_hotplug_register(struct pico_device *dev, void (*cb)(struct pico_device *dev, int event)); 20 | int pico_hotplug_deregister(struct pico_device *dev, void (*cb)(struct pico_device *dev, int event)); 21 | 22 | #endif /* _INCLUDE_PICO_SUPPORT_HOTPLUG */ 23 | 24 | -------------------------------------------------------------------------------- /include/arch/pico_avr.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved. 3 | See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage. 4 | 5 | *********************************************************************/ 6 | #define dbg(...) do {} while(0) 7 | /* #define dbg printf */ 8 | 9 | /*************************/ 10 | 11 | /*** MACHINE CONFIGURATION ***/ 12 | /* Temporary (POSIX) stuff. */ 13 | #include 14 | #include 15 | #include 16 | #include "pico_mm.h" 17 | 18 | extern volatile uint32_t __avr_tick; 19 | 20 | #define pico_zalloc(x) calloc(x, 1) 21 | #define pico_free(x) free(x) 22 | 23 | static inline unsigned long PICO_TIME(void) 24 | { 25 | register uint32_t tick = __avr_tick; 26 | return tick / 1000; 27 | } 28 | 29 | static inline unsigned long PICO_TIME_MS(void) 30 | { 31 | return __avr_tick; 32 | } 33 | 34 | static inline void PICO_IDLE(void) 35 | { 36 | unsigned long tick_now = __avr_tick; 37 | while(tick_now == __avr_tick) ; 38 | } 39 | 40 | -------------------------------------------------------------------------------- /modules/pico_ipfilter.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved. 3 | See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage. 4 | 5 | Authors: Simon Maes 6 | *********************************************************************/ 7 | #ifndef INCLUDE_PICO_IPFILTER 8 | #define INCLUDE_PICO_IPFILTER 9 | 10 | #include "pico_device.h" 11 | 12 | enum filter_action { 13 | FILTER_PRIORITY = 0, 14 | FILTER_REJECT, 15 | FILTER_DROP, 16 | FILTER_COUNT 17 | }; 18 | 19 | uint32_t pico_ipv4_filter_add(struct pico_device *dev, uint8_t proto, 20 | struct pico_ip4 *out_addr, struct pico_ip4 *out_addr_netmask, struct pico_ip4 *in_addr, 21 | struct pico_ip4 *in_addr_netmask, uint16_t out_port, uint16_t in_port, 22 | int8_t priority, uint8_t tos, enum filter_action action); 23 | 24 | int pico_ipv4_filter_del(uint32_t filter_id); 25 | 26 | int ipfilter(struct pico_frame *f); 27 | 28 | #endif /* _INCLUDE_PICO_IPFILTER */ 29 | 30 | -------------------------------------------------------------------------------- /test/examples/Makefile: -------------------------------------------------------------------------------- 1 | PREFIX?=../../build 2 | CFLAGS+=-I../../include/ -I../../modules -I../../build/include -I . -ggdb 3 | 4 | 5 | $(PREFIX)/examples/%.o: %.c 6 | @mkdir -p $(PREFIX)/examples 7 | @echo -e "\t[CC] $@" 8 | @$(CC) -c $(CFLAGS) -o $@ $< 9 | 10 | OBJS:= \ 11 | $(PREFIX)/examples/dhcp_client.o \ 12 | $(PREFIX)/examples/dhcp_server.o \ 13 | $(PREFIX)/examples/dns_sd.o \ 14 | $(PREFIX)/examples/dnsclient.o \ 15 | $(PREFIX)/examples/mdns.o \ 16 | $(PREFIX)/examples/multicast_recv.o \ 17 | $(PREFIX)/examples/multicast_ip6_recv.o \ 18 | $(PREFIX)/examples/multicast_send.o \ 19 | $(PREFIX)/examples/multicast_ip6_send.o \ 20 | $(PREFIX)/examples/natbox.o \ 21 | $(PREFIX)/examples/noop.o \ 22 | $(PREFIX)/examples/ping.o \ 23 | $(PREFIX)/examples/slaacv4.o \ 24 | $(PREFIX)/examples/sntp.o \ 25 | $(PREFIX)/examples/tcpbench.o \ 26 | $(PREFIX)/examples/tcpclient.o \ 27 | $(PREFIX)/examples/tcpecho.o \ 28 | $(PREFIX)/examples/tftp.o \ 29 | $(PREFIX)/examples/udp_client.o \ 30 | $(PREFIX)/examples/udp_echo.o \ 31 | $(PREFIX)/examples/udpnat.o \ 32 | $(PREFIX)/examples/udp_sendto_test.o \ 33 | $(PREFIX)/examples/iperfc.o \ 34 | 35 | 36 | all: $(OBJS) 37 | -------------------------------------------------------------------------------- /test/examples/utils.h: -------------------------------------------------------------------------------- 1 | #ifndef PICO_EXAMPLES_UTILS_H 2 | #define PICO_EXAMPLES_UTILS_H 3 | #include 4 | #define TCPSIZ (1024 * 1024 * 5) 5 | extern struct pico_ip4 ZERO_IP4; 6 | extern struct pico_ip_mreq ZERO_MREQ; 7 | extern struct pico_ip_mreq_source ZERO_MREQ_SRC; 8 | extern struct pico_ip6 ZERO_IP6; 9 | extern struct pico_ip_mreq ZERO_MREQ_IP6; 10 | extern struct pico_ip_mreq_source ZERO_MREQ_SRC_IP6; 11 | #define picoapp_dbg(...) do {} while(0) 12 | /* #define picoapp_dbg printf */ 13 | extern int IPV6_MODE; 14 | 15 | 16 | extern struct pico_ip4 inaddr_any; 17 | extern struct pico_ip6 inaddr6_any; 18 | 19 | extern char *cpy_arg(char **dst, char *str); 20 | 21 | extern void deferred_exit(pico_time now, void *arg); 22 | 23 | struct udpclient_pas { 24 | struct pico_socket *s; 25 | uint8_t loops; 26 | uint8_t subloops; 27 | uint16_t datasize; 28 | uint16_t sport; 29 | union pico_address dst; 30 | }; /* per application struct */ 31 | 32 | struct udpecho_pas { 33 | struct pico_socket *s; 34 | uint16_t sendto_port; /* big-endian */ 35 | uint16_t datasize; 36 | }; /* per application struct */ 37 | 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /modules/pico_dev_ppp.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved. 3 | See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage. 4 | 5 | *********************************************************************/ 6 | #ifndef INCLUDE_PICO_PPP 7 | #define INCLUDE_PICO_PPP 8 | 9 | #include "pico_config.h" 10 | #include "pico_device.h" 11 | 12 | void pico_ppp_destroy(struct pico_device *ppp); 13 | struct pico_device *pico_ppp_create(void); 14 | 15 | int pico_ppp_connect(struct pico_device *dev); 16 | int pico_ppp_disconnect(struct pico_device *dev); 17 | 18 | int pico_ppp_set_serial_read(struct pico_device *dev, int (*sread)(struct pico_device *, void *, int)); 19 | int pico_ppp_set_serial_write(struct pico_device *dev, int (*swrite)(struct pico_device *, const void *, int)); 20 | int pico_ppp_set_serial_set_speed(struct pico_device *dev, int (*sspeed)(struct pico_device *, uint32_t)); 21 | 22 | int pico_ppp_set_apn(struct pico_device *dev, const char *apn); 23 | int pico_ppp_set_username(struct pico_device *dev, const char *username); 24 | int pico_ppp_set_password(struct pico_device *dev, const char *password); 25 | 26 | #endif /* INCLUDE_PICO_PPP */ 27 | -------------------------------------------------------------------------------- /test/python/fairness_bottleneck.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # fairness.py 3 | # A complex test for butterly-like topology, 4 | # using 3 TCP connections and 3 ping flows. 5 | # 6 | # Bottleneck of 4 Mbit/300 ms overall delay is added. 7 | # 8 | # s1---. .---r1 9 | # s2----\ / 10 | # s3-----\__.R1---R2.__/__.--r2 11 | # s4-----/ \ 12 | # s5----/ \_.--r3 13 | # s6---^ 14 | # 15 | 16 | from topology import * 17 | 18 | T = Topology() 19 | net1 = Network(T) 20 | net2 = Network(T) 21 | net3 = Network(T) 22 | 23 | router1 = Host(T, net1, net2, delay2="150", bw2="20M") 24 | router2 = Host(T, net2, net3) 25 | 26 | send1 = Host(T, net1, args="tcpbench:t:172.16.3.2:") 27 | send2 = Host(T, net1, args="tcpbench:t:172.16.3.3:") 28 | send3 = Host(T, net1, args="tcpbench:t:172.16.3.4:") 29 | 30 | send4 = Host(T, net1, args="ping:172.16.3.2:") 31 | send5 = Host(T, net1, args="ping:172.16.3.3:") 32 | send6 = Host(T, net1, args="ping:172.16.3.4:") 33 | 34 | 35 | recv1 = Host(T, net3, args="tcpbench:r:") 36 | recv2 = Host(T, net3, args="tcpbench:r:") 37 | recv3 = Host(T, net3, args="tcpbench:r:") 38 | 39 | 40 | sleep(1) 41 | start(T) 42 | 43 | wait(send1) 44 | wait(send2) 45 | wait(send3) 46 | 47 | cleanup() 48 | -------------------------------------------------------------------------------- /test/python/fairness_bottleneck_linux.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # fairness.py 3 | # A complex test for butterly-like topology, 4 | # using 3 TCP connections and 3 ping flows. 5 | # 6 | # Bottleneck of 4 Mbit/300 ms overall delay is added. 7 | # 8 | # s1---. .---r1 9 | # s2----\ / 10 | # s3-----\__.R1---R2.__/__.--r2 11 | # s4-----/ \ 12 | # s5----/ \_.--r3 13 | # s6---^ 14 | # 15 | 16 | from topology import * 17 | 18 | T = Topology() 19 | net1 = Network(T) 20 | net2 = Network(T, "pyt0") 21 | net3 = Network(T) 22 | 23 | router1 = Host(T, net1, net2, delay2="150", bw2="4M") 24 | router2 = Host(T, net2, net3) 25 | 26 | send1 = Host(T, net1, args="tcpbench:t:172.16.3.2:") 27 | send2 = Host(T, net1, args="tcpbench:t:172.16.3.3:") 28 | send3 = Host(T, net1, args="tcpbench:t:172.16.3.4:") 29 | 30 | send4 = Host(T, net1, args="ping:172.16.3.2:") 31 | send5 = Host(T, net1, args="ping:172.16.3.3:") 32 | send6 = Host(T, net1, args="ping:172.16.3.4:") 33 | 34 | 35 | recv1 = Host(T, net3, args="tcpbench:r:") 36 | recv2 = Host(T, net3, args="tcpbench:r:") 37 | recv3 = Host(T, net3, args="tcpbench:r:") 38 | 39 | 40 | sleep(1) 41 | start(T) 42 | 43 | wait(send1) 44 | wait(send2) 45 | wait(send3) 46 | 47 | cleanup() 48 | -------------------------------------------------------------------------------- /stack/pico_md5.c: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | * PicoTCP. Copyright (c) 2015-2017 Altran Intelligent Systems. Some rights reserved. 3 | * See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage. 4 | * 5 | * Authors: Daniele Lacamera 6 | * *********************************************************************/ 7 | 8 | 9 | #include 10 | 11 | #if defined (PICO_SUPPORT_CYASSL) 12 | #include 13 | 14 | void pico_md5sum(uint8_t *dst, const uint8_t *src, size_t len) 15 | { 16 | Md5 md5; 17 | InitMd5(&md5); 18 | Md5Update(&md5, src, len); 19 | Md5Final(&md5, dst); 20 | } 21 | 22 | #elif defined (PICO_SUPPORT_POLARSSL) 23 | #include 24 | 25 | void pico_md5sum(uint8_t *dst, const uint8_t *src, size_t len) 26 | { 27 | md5(src, len, dst); 28 | } 29 | 30 | #else 31 | static void (*do_pico_md5sum)(uint8_t *dst, const uint8_t *src, size_t len); 32 | void pico_md5sum(uint8_t *dst, const uint8_t *src, size_t len) 33 | { 34 | if (do_pico_md5sum) { 35 | do_pico_md5sum(dst, src, len); 36 | } 37 | } 38 | 39 | void pico_register_md5sum(void (*md5)(uint8_t *, const uint8_t *, size_t)) 40 | { 41 | do_pico_md5sum = md5; 42 | } 43 | #endif 44 | -------------------------------------------------------------------------------- /modules/pico_dhcp_client.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved. 3 | See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage. 4 | 5 | . 6 | 7 | *********************************************************************/ 8 | #ifndef INCLUDE_PICO_DHCP_CLIENT 9 | #define INCLUDE_PICO_DHCP_CLIENT 10 | #include "pico_defines.h" 11 | #ifdef PICO_SUPPORT_UDP 12 | #include "pico_dhcp_common.h" 13 | #include "pico_addressing.h" 14 | #include "pico_protocol.h" 15 | 16 | int pico_dhcp_initiate_negotiation(struct pico_device *device, void (*callback)(void*cli, int code), uint32_t *xid); 17 | void *pico_dhcp_get_identifier(uint32_t xid); 18 | struct pico_ip4 pico_dhcp_get_address(void *cli); 19 | struct pico_ip4 pico_dhcp_get_gateway(void *cli); 20 | struct pico_ip4 pico_dhcp_get_netmask(void *cli); 21 | struct pico_ip4 pico_dhcp_get_nameserver(void*cli, int index); 22 | int pico_dhcp_client_abort(uint32_t xid); 23 | char *pico_dhcp_get_hostname(void); 24 | char *pico_dhcp_get_domain(void); 25 | 26 | /* possible codes for the callback */ 27 | #define PICO_DHCP_SUCCESS 0 28 | #define PICO_DHCP_ERROR 1 29 | #define PICO_DHCP_RESET 2 30 | 31 | #endif 32 | #endif 33 | -------------------------------------------------------------------------------- /modules/pico_dhcp_server.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved. 3 | See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage. 4 | 5 | *********************************************************************/ 6 | #ifndef INCLUDE_PICO_DHCP_SERVER 7 | #define INCLUDE_PICO_DHCP_SERVER 8 | #include "pico_defines.h" 9 | #ifdef PICO_SUPPORT_UDP 10 | 11 | #include "pico_dhcp_common.h" 12 | #include "pico_addressing.h" 13 | 14 | struct pico_dhcp_server_setting 15 | { 16 | uint32_t pool_start; 17 | uint32_t pool_next; 18 | uint32_t pool_end; 19 | uint32_t lease_time; 20 | struct pico_device *dev; 21 | struct pico_socket *s; 22 | struct pico_ip4 server_ip; 23 | struct pico_ip4 netmask; 24 | uint8_t flags; /* unused atm */ 25 | }; 26 | 27 | /* required field: IP address of the interface to serve, only IPs of this network will be served. */ 28 | int pico_dhcp_server_initiate(struct pico_dhcp_server_setting *dhcps); 29 | 30 | /* To destroy an existing DHCP server configuration, running on a given interface */ 31 | int pico_dhcp_server_destroy(struct pico_device *dev); 32 | 33 | #endif /* _INCLUDE_PICO_DHCP_SERVER */ 34 | #endif 35 | -------------------------------------------------------------------------------- /modules/pico_ipv6_nd.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved. 3 | See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage. 4 | 5 | *********************************************************************/ 6 | #ifndef _INCLUDE_PICO_ND 7 | #define _INCLUDE_PICO_ND 8 | #include "pico_frame.h" 9 | #include "pico_ipv6.h" 10 | 11 | /* RFC constants */ 12 | #define PICO_ND_REACHABLE_TIME 30000 /* msec */ 13 | #define PICO_ND_RETRANS_TIMER 1000 /* msec */ 14 | 15 | struct pico_nd_hostvars { 16 | uint8_t routing; 17 | uint8_t hoplimit; 18 | pico_time basetime; 19 | pico_time reachabletime; 20 | pico_time retranstime; 21 | #ifdef PICO_SUPPORT_6LOWPAN 22 | uint8_t lowpan_flags; 23 | #endif 24 | }; 25 | 26 | void pico_ipv6_nd_init(void); 27 | struct pico_eth *pico_ipv6_get_neighbor(struct pico_frame *f); 28 | void pico_ipv6_nd_postpone(struct pico_frame *f); 29 | int pico_ipv6_nd_recv(struct pico_frame *f); 30 | 31 | #ifdef PICO_SUPPORT_6LOWPAN 32 | int pico_6lp_nd_start_soliciting(struct pico_ipv6_link *l, struct pico_ipv6_route *gw); 33 | void pico_6lp_nd_register(struct pico_ipv6_link *link); 34 | #endif 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /test/python/fairness.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # fairness.py 3 | # A complex test for butterly-like topology, 4 | # using 3 TCP connections and 3 ping flows. 5 | # 6 | # s1---. .---r1 7 | # s2----\ / 8 | # s3-----\__.R1---R2.__/__.--r2 9 | # s4-----/ \ 10 | # s5----/ \_.--r3 11 | # s6---^ 12 | # 13 | 14 | from topology import * 15 | 16 | T = Topology() 17 | net1 = Network(T) 18 | net2 = Network(T) 19 | net3 = Network(T) 20 | 21 | #router1 = Host(T, net1, net2, "natbox:172.16.2.1:") 22 | #router2 = Host(T, net2, net3, "natbox:172.16.3.1:") 23 | router1 = Host(T, net1, net2) 24 | router2 = Host(T, net2, net3) 25 | 26 | send1 = Host(T, net1, args="tcpbench:t:172.16.3.2:") 27 | send2 = Host(T, net1, args="tcpbench:t:172.16.3.3:") 28 | send3 = Host(T, net1, args="tcpbench:t:172.16.3.4:") 29 | 30 | send4 = Host(T, net1, args="ping:172.16.3.2:") 31 | send5 = Host(T, net1, args="ping:172.16.3.3:") 32 | send6 = Host(T, net1, args="ping:172.16.3.4:") 33 | 34 | 35 | recv1 = Host(T, net3, args="tcpbench:r:") 36 | recv2 = Host(T, net3, args="tcpbench:r:") 37 | recv3 = Host(T, net3, args="tcpbench:r:") 38 | recv4 = Host(T, net3, args="tcpbench:r:") 39 | 40 | 41 | sleep(1) 42 | start(T) 43 | 44 | wait(send1) 45 | wait(send2) 46 | wait(send3) 47 | 48 | cleanup() 49 | -------------------------------------------------------------------------------- /modules/pico_socket_tcp.h: -------------------------------------------------------------------------------- 1 | #ifndef PICO_SOCKET_TCP_H 2 | #define PICO_SOCKET_TCP_H 3 | #include "pico_socket.h" 4 | 5 | #ifdef PICO_SUPPORT_TCP 6 | 7 | /* Functions/macros: conditional! */ 8 | 9 | # define IS_NAGLE_ENABLED(s) (!(!(!(s->opt_flags & (1 << PICO_SOCKET_OPT_TCPNODELAY))))) 10 | int pico_setsockopt_tcp(struct pico_socket *s, int option, void *value); 11 | int pico_getsockopt_tcp(struct pico_socket *s, int option, void *value); 12 | int pico_socket_tcp_deliver(struct pico_sockport *sp, struct pico_frame *f); 13 | void pico_socket_tcp_delete(struct pico_socket *s); 14 | void pico_socket_tcp_cleanup(struct pico_socket *sock); 15 | struct pico_socket *pico_socket_tcp_open(uint16_t family); 16 | int pico_socket_tcp_read(struct pico_socket *s, void *buf, uint32_t len); 17 | void transport_flags_update(struct pico_frame *, struct pico_socket *); 18 | 19 | #else 20 | # define pico_getsockopt_tcp(...) (-1) 21 | # define pico_setsockopt_tcp(...) (-1) 22 | # define pico_socket_tcp_deliver(...) (-1) 23 | # define IS_NAGLE_ENABLED(s) (0) 24 | # define pico_socket_tcp_delete(...) do {} while(0) 25 | # define pico_socket_tcp_cleanup(...) do {} while(0) 26 | # define pico_socket_tcp_open(f) (NULL) 27 | # define pico_socket_tcp_read(...) (-1) 28 | # define transport_flags_update(...) do {} while(0) 29 | 30 | #endif 31 | 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /test/python/traceroute_from_linux.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | from topology import * 3 | 4 | ''' 5 | Add route to 172.16.0.0/16 gw 172.16.1.2 on your host machine. 6 | 7 | Should result in something like: 8 | ~$ traceroute 172.16.8.2 9 | traceroute to 172.16.8.2 (172.16.8.2), 30 hops max, 60 byte packets 10 | 1 172.16.1.2 (172.16.1.2) 0.481 ms 0.473 ms 0.467 ms 11 | 2 172.16.2.2 (172.16.2.2) 4.680 ms 4.702 ms 4.700 ms 12 | 3 172.16.3.2 (172.16.3.2) 8.759 ms 8.768 ms 8.766 ms 13 | 4 172.16.4.2 (172.16.4.2) 10.791 ms 10.789 ms 10.786 ms 14 | 5 172.16.5.2 (172.16.5.2) 12.826 ms 12.825 ms 12.821 ms 15 | 6 172.16.6.2 (172.16.6.2) 14.844 ms 17.858 ms 17.857 ms 16 | 7 172.16.7.2 (172.16.7.2) 17.858 ms 14.000 ms 13.999 ms 17 | 8 172.16.8.2 (172.16.8.2) 18.032 ms 18.029 ms 18.023 ms 18 | 19 | ''' 20 | 21 | 22 | T = Topology() 23 | net1 = Network(T, 'nat0') 24 | net2 = Network(T) 25 | net3 = Network(T) 26 | net4 = Network(T) 27 | net5 = Network(T) 28 | net6 = Network(T) 29 | net7 = Network(T) 30 | net8 = Network(T) 31 | 32 | router1 = Host(T, net1, net2) 33 | router2 = Host(T, net2, net3) 34 | router3 = Host(T, net3, net4) 35 | router4 = Host(T, net4, net5) 36 | router5 = Host(T, net5, net6) 37 | router6 = Host(T, net6, net7) 38 | router7 = Host(T, net7, net8) 39 | 40 | h1 = Host(T, net8) 41 | 42 | sleep(1) 43 | start(T) 44 | loop() 45 | cleanup() 46 | -------------------------------------------------------------------------------- /include/arch/pico_dos.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This is a picoTCP arch file for the DOS 16 bit target using OpenWatcom v1.9 3 | * Copyright (C) 2015 Mateusz Viste 4 | * 5 | * This code is donated to the picoTCP project, and shares the same licensing, 6 | * that is GNU GPLv2. 7 | * 8 | * See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage. 9 | */ 10 | 11 | #include /* provides int86() along with the union REGS type */ 12 | 13 | #ifndef PICO_SUPPORT_DOS_WATCOM 14 | #define PICO_SUPPORT_DOS_WATCOM 15 | 16 | #define dbg(...) 17 | 18 | #define pico_zalloc(x) calloc(x, 1) 19 | #define pico_free(x) free(x) 20 | 21 | static inline unsigned long PICO_TIME_MS(void) 22 | { 23 | union REGS regs; 24 | unsigned long ticks; 25 | regs.h.ah = 0; /* get system time (IBM BIOS call) - INT 1A,0 */ 26 | int86(0x1A, ®s, ®s); 27 | ticks = regs.x.cx; /* number of ticks since midnight (high word) */ 28 | ticks <<= 16; 29 | ticks |= regs.x.dx; /* number of ticks since midnight (low word) */ 30 | return (ticks * 55); /* a tick is 55ms because the i8253 PIT runs at 18.2 Hz */ 31 | } 32 | 33 | static inline unsigned long PICO_TIME(void) 34 | { 35 | return (PICO_TIME_MS() / 1000); 36 | } 37 | 38 | static inline void PICO_IDLE(void) 39 | { 40 | union REGS regs; 41 | int86(0x28, ®s, ®s); /* DOS 2+ IDLE INTERRUPT */ 42 | } 43 | 44 | #endif /* PICO_SUPPORT_DOS_WATCOM */ 45 | -------------------------------------------------------------------------------- /test/unit/unit_timer.c: -------------------------------------------------------------------------------- 1 | #define EXISTING_TIMERS 7 2 | 3 | 4 | START_TEST (test_timers) 5 | { 6 | uint32_t T[128]; 7 | int i; 8 | struct pico_timer_ref *tref; 9 | pico_stack_init(); 10 | for (i = 0; i < 128; i++) { 11 | pico_time expire = (pico_time)(999999 + i); 12 | void (*timer)(pico_time, void *) =(void (*)(pico_time, void *))0xff00 + i; 13 | void *arg = ((void*)0xaa00 + i); 14 | 15 | T[i] = pico_timer_add(expire, timer, arg); 16 | printf("New timer %u\n", T[i]); 17 | } 18 | for (i = 0; i < 128; i++) { 19 | void (*timer)(pico_time, void *) =(void (*)(pico_time, void *))0xff00 + i; 20 | void *arg = ((void*)0xaa00 + i); 21 | 22 | fail_if((uint32_t)(i + 1) > Timers->n); 23 | tref = heap_get_element(Timers, (uint32_t)i + EXISTING_TIMERS); 24 | fail_unless(tref->id == T[i]); 25 | fail_unless(tref->tmr->timer == timer); 26 | fail_unless(tref->tmr->arg == arg); 27 | } 28 | for (i = 127; i >= 0; i--) { 29 | printf("Deleting timer %d \n", i ); 30 | pico_timer_cancel(T[i]); 31 | printf("Deleted timer %d \n", i ); 32 | tref = heap_get_element(Timers, (uint32_t)i + EXISTING_TIMERS); 33 | fail_unless(tref->tmr == NULL); 34 | } 35 | pico_stack_tick(); 36 | pico_stack_tick(); 37 | pico_stack_tick(); 38 | pico_stack_tick(); 39 | } 40 | END_TEST 41 | -------------------------------------------------------------------------------- /modules/pico_udp.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved. 3 | See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage. 4 | 5 | . 6 | 7 | *********************************************************************/ 8 | #ifndef INCLUDE_PICO_UDP 9 | #define INCLUDE_PICO_UDP 10 | #include "pico_addressing.h" 11 | #include "pico_protocol.h" 12 | #include "pico_socket.h" 13 | #define PICO_UDP_MODE_UNICAST 0x01 14 | #define PICO_UDP_MODE_MULTICAST 0x02 15 | #define PICO_UDP_MODE_BROADCAST 0xFF 16 | 17 | struct pico_socket_udp 18 | { 19 | struct pico_socket sock; 20 | int mode; 21 | uint8_t mc_ttl; /* Multicasting TTL */ 22 | }; 23 | 24 | 25 | extern struct pico_protocol pico_proto_udp; 26 | 27 | PACKED_STRUCT_DEF pico_udp_hdr { 28 | struct pico_trans trans; 29 | uint16_t len; 30 | uint16_t crc; 31 | }; 32 | #define PICO_UDPHDR_SIZE 8 33 | 34 | struct pico_socket *pico_udp_open(void); 35 | uint16_t pico_udp_recv(struct pico_socket *s, void *buf, uint16_t len, void *src, uint16_t *port, struct pico_msginfo *msginfo); 36 | uint16_t pico_udp_checksum_ipv4(struct pico_frame *f); 37 | 38 | #ifdef PICO_SUPPORT_IPV6 39 | uint16_t pico_udp_checksum_ipv6(struct pico_frame *f); 40 | #endif 41 | 42 | 43 | int pico_udp_setsockopt(struct pico_socket *s, int option, void *value); 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /include/arch/pico_pic32.h: -------------------------------------------------------------------------------- 1 | 2 | /********************************************************************* 3 | PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved. 4 | See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage. 5 | 6 | *********************************************************************/ 7 | #ifndef _INCLUDE_PICO_PIC32 8 | #define _INCLUDE_PICO_PIC32 9 | 10 | #include 11 | #include 12 | #include 13 | #include "pico_constants.h" 14 | 15 | /* monotonically increasing tick, 16 | * typically incremented every millisecond in a systick interrupt */ 17 | extern volatile unsigned int pico_ms_tick; 18 | 19 | #ifdef PIC32_NO_PRINTF 20 | #define dbg(...) do {} while(0) 21 | #else 22 | #define dbg printf 23 | #endif 24 | 25 | /* Use plain C-lib malloc and free */ 26 | #define pico_free(x) free(x) 27 | 28 | static inline void *pico_zalloc(size_t size) 29 | { 30 | void *ptr = malloc(size); 31 | if(ptr) 32 | memset(ptr, 0u, size); 33 | 34 | return ptr; 35 | } 36 | 37 | static inline pico_time PICO_TIME_MS(void) 38 | { 39 | return (pico_time)pico_ms_tick; 40 | } 41 | 42 | static inline pico_time PICO_TIME(void) 43 | { 44 | return (pico_time)(PICO_TIME_MS() / 1000); 45 | } 46 | 47 | static inline void PICO_IDLE(void) 48 | { 49 | unsigned int now = pico_ms_tick; 50 | while(now == pico_ms_tick) ; 51 | } 52 | 53 | #endif /* PICO_PIC32 */ 54 | 55 | -------------------------------------------------------------------------------- /include/arch/pico_esp8266.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | PicoTCP. Copyright (c) 2014-2017 Altran Intelligent Systems. Some rights reserved. 3 | See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage. 4 | 5 | *********************************************************************/ 6 | #ifndef _INCLUDE_PICO_ESP8266 7 | #define _INCLUDE_PICO_ESP8266 8 | 9 | #include 10 | 11 | #include 12 | #include 13 | #include 14 | #include "pico_constants.h" 15 | 16 | /* -------------- DEBUG ------------- */ 17 | 18 | /* #define dbg(...) */ 19 | #define dbg printf 20 | 21 | /* -------------- MEMORY ------------- */ 22 | extern void *pvPortMalloc( size_t xWantedSize ); 23 | extern void vPortFree( void *pv ); 24 | 25 | #define pico_free vPortFree 26 | 27 | static inline void *pico_zalloc(size_t size) 28 | { 29 | void *ptr = (void *)pvPortMalloc(size); 30 | 31 | if(ptr) 32 | memset(ptr, 0u, size); 33 | 34 | return ptr; 35 | } 36 | 37 | /* -------------- TIME ------------- */ 38 | 39 | extern volatile uint32_t esp_tick; 40 | 41 | static inline pico_time PICO_TIME_MS(void) 42 | { 43 | return (pico_time) esp_tick; 44 | } 45 | 46 | static inline pico_time PICO_TIME(void) 47 | { 48 | return PICO_TIME_MS() / 1000; 49 | } 50 | 51 | static inline void PICO_IDLE(void) 52 | { 53 | uint32_t now = esp_tick; 54 | while (now == esp_tick) 55 | ; 56 | } 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /modules/pico_arp.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved. 3 | See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage. 4 | 5 | *********************************************************************/ 6 | #ifndef INCLUDE_PICO_ARP 7 | #define INCLUDE_PICO_ARP 8 | #include "pico_eth.h" 9 | #include "pico_device.h" 10 | 11 | int pico_arp_receive(struct pico_frame *); 12 | 13 | 14 | struct pico_eth *pico_arp_get(struct pico_frame *f); 15 | int32_t pico_arp_request(struct pico_device *dev, struct pico_ip4 *dst, uint8_t type); 16 | 17 | #define PICO_ARP_STATUS_REACHABLE 0x00 18 | #define PICO_ARP_STATUS_PERMANENT 0x01 19 | #define PICO_ARP_STATUS_STALE 0x02 20 | 21 | #define PICO_ARP_QUERY 0x00 22 | #define PICO_ARP_PROBE 0x01 23 | #define PICO_ARP_ANNOUNCE 0x02 24 | 25 | #define PICO_ARP_CONFLICT_REASON_CONFLICT 0 26 | #define PICO_ARP_CONFLICT_REASON_PROBE 1 27 | 28 | struct pico_eth *pico_arp_lookup(struct pico_ip4 *dst); 29 | struct pico_ip4 *pico_arp_reverse_lookup(struct pico_eth *dst); 30 | int pico_arp_create_entry(uint8_t*hwaddr, struct pico_ip4 ipv4, struct pico_device*dev); 31 | int pico_arp_get_neighbors(struct pico_device *dev, struct pico_ip4 *neighbors, int maxlen); 32 | void pico_arp_register_ipconflict(struct pico_ip4 *ip, struct pico_eth *mac, void (*cb)(int reason)); 33 | void pico_arp_postpone(struct pico_frame *f); 34 | void pico_arp_init(void); 35 | #endif 36 | -------------------------------------------------------------------------------- /modules/pico_802154.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights 3 | reserved. See LICENSE and COPYING for usage. 4 | 5 | Authors: Jelle De Vleeschouwer 6 | *********************************************************************/ 7 | #ifndef INCLUDE_PICO_802154 8 | #define INCLUDE_PICO_802154 9 | 10 | #include "pico_device.h" 11 | #include "pico_config.h" 12 | #include "pico_6lowpan_ll.h" 13 | 14 | /******************************************************************************* 15 | * Size definitions 16 | ******************************************************************************/ 17 | 18 | #define MTU_802154_PHY (128u) 19 | #define MTU_802154_MAC (125u) // 127 - Frame Check Sequence 20 | 21 | #define SIZE_802154_MHR_MIN (5u) 22 | #define SIZE_802154_MHR_MAX (23u) 23 | #define SIZE_802154_FCS (2u) 24 | #define SIZE_802154_LEN (1u) 25 | #define SIZE_802154_PAN (2u) 26 | 27 | /******************************************************************************* 28 | * Structure definitions 29 | ******************************************************************************/ 30 | 31 | PACKED_STRUCT_DEF pico_802154_hdr 32 | { 33 | uint16_t fcf; 34 | uint8_t seq; 35 | uint16_t pan_id; 36 | }; 37 | 38 | extern const struct pico_6lowpan_ll_protocol pico_6lowpan_ll_802154; 39 | 40 | #endif /* INCLUDE_PICO_802154 */ 41 | -------------------------------------------------------------------------------- /modules/pico_6lowpan.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights 3 | reserved. See LICENSE and COPYING for usage. 4 | 5 | Authors: Jelle De Vleeschouwer 6 | *********************************************************************/ 7 | 8 | #ifndef INCLUDE_PICO_6LOWPAN 9 | #define INCLUDE_PICO_6LOWPAN 10 | 11 | #include "pico_protocol.h" 12 | #include "pico_device.h" 13 | #include "pico_config.h" 14 | #include "pico_frame.h" 15 | 16 | #define PICO_6LP_FLAG_LOWPAN (0x01) 17 | #define PICO_6LP_FLAG_NOMAC (0x02) 18 | 19 | #ifdef PICO_SUPPORT_6LOWPAN 20 | #define PICO_DEV_IS_6LOWPAN(dev) ((dev) && ((dev)->hostvars.lowpan_flags & PICO_6LP_FLAG_LOWPAN)) 21 | #define PICO_DEV_IS_NOMAC(dev) ((dev) && ((dev)->hostvars.lowpan_flags & PICO_6LP_FLAG_NOMAC)) 22 | #else 23 | #define PICO_DEV_IS_6LOWPAN(dev) (0) 24 | #define PICO_DEV_IS_NOMAC(dev) (0) 25 | #endif 26 | 27 | /****************************************************************************** 28 | * Public variables 29 | ******************************************************************************/ 30 | 31 | extern struct pico_protocol pico_proto_6lowpan; 32 | 33 | /****************************************************************************** 34 | * Public functions 35 | ******************************************************************************/ 36 | 37 | int32_t pico_6lowpan_pull(struct pico_frame *f); 38 | int pico_6lowpan_init(void); 39 | 40 | #endif /* INCLUDE_PICO_6LOWPAN */ 41 | -------------------------------------------------------------------------------- /test/python/traceroute_nat_from_linux.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | from topology import * 3 | 4 | ''' 5 | Add route to 172.16.0.0/16 gw 172.16.1.2 on your host machine. 6 | 7 | Should result in something like: 8 | ~$ traceroute 172.16.8.2 9 | traceroute to 172.16.8.2 (172.16.8.2), 30 hops max, 60 byte packets 10 | 1 172.16.1.2 (172.16.1.2) 0.481 ms 0.473 ms 0.467 ms 11 | 2 172.16.2.2 (172.16.2.2) 4.680 ms 4.702 ms 4.700 ms 12 | 3 172.16.3.2 (172.16.3.2) 8.759 ms 8.768 ms 8.766 ms 13 | 4 172.16.4.2 (172.16.4.2) 10.791 ms 10.789 ms 10.786 ms 14 | 5 172.16.5.2 (172.16.5.2) 12.826 ms 12.825 ms 12.821 ms 15 | 6 172.16.6.2 (172.16.6.2) 14.844 ms 17.858 ms 17.857 ms 16 | 7 172.16.7.2 (172.16.7.2) 17.858 ms 14.000 ms 13.999 ms 17 | 8 172.16.8.2 (172.16.8.2) 18.032 ms 18.029 ms 18.023 ms 18 | 19 | ''' 20 | 21 | 22 | T = Topology() 23 | net1 = Network(T, 'nat0') 24 | net2 = Network(T) 25 | net3 = Network(T) 26 | net4 = Network(T) 27 | net5 = Network(T) 28 | net6 = Network(T) 29 | net7 = Network(T) 30 | net8 = Network(T) 31 | 32 | router1 = Host(T, net1, net2, args="natbox:172.16.2.1") 33 | router2 = Host(T, net2, net3, args="natbox:172.16.3.1") 34 | router3 = Host(T, net3, net4, args="natbox:172.16.4.1") 35 | router4 = Host(T, net4, net5, args="natbox:172.16.5.1") 36 | router5 = Host(T, net5, net6, args="natbox:172.16.6.1") 37 | router6 = Host(T, net6, net7, args="natbox:172.16.7.1") 38 | router7 = Host(T, net7, net8, args="natbox:172.16.8.1") 39 | 40 | h1 = Host(T, net8) 41 | 42 | sleep(1) 43 | start(T) 44 | loop() 45 | cleanup() 46 | -------------------------------------------------------------------------------- /docs/user_manual/chap_api_aodv.tex: -------------------------------------------------------------------------------- 1 | \section{Ad-hoc On-Demand Distance Vector Routing (AODV)} 2 | 3 | 4 | AODV is a reactive routing protocol for mobile ad-hoc networks 5 | (MANETs). Its best fit are especially ultra-low power radio networks, 6 | or those RF topologies where sporadic traffic between a small specific set 7 | of nodes is foreseen. 8 | In order to create a route, one node must explicitly start the communication 9 | towards a remote node, and the route is created ad-hoc upon the demand 10 | for a specific network path. 11 | AODV guarantees that the traffic generated by each node in order to create 12 | and maintain routes is kept as low as possible. 13 | 14 | \subsection{pico\_aodv\_add} 15 | 16 | \subsubsection*{Description} 17 | This function will add the target device to the AODV mechanism on the machine, 18 | meaning that it will be possible to advertise and collect routing information 19 | using Ad-hoc On-Demand Distance Vector Routing, as described in RFC3561, through the 20 | target device. 21 | 22 | In order to use multiple devices in the AODV system, this function needs to be called 23 | multiple times, once per device. 24 | 25 | \subsubsection*{Function prototype} 26 | \texttt{pico\_aodv\_add(struct pico\_device *dev);} 27 | 28 | \subsubsection*{Parameters} 29 | \begin{itemize}[noitemsep] 30 | \item \texttt{dev} - a pointer to a struct \texttt{pico\_device} specifying the target interface. 31 | \end{itemize} 32 | 33 | \subsubsection*{Return value} 34 | 0 returned if the device is successfully added. 35 | 36 | \subsubsection*{Example} 37 | \begin{verbatim} 38 | 39 | ret = pico_aodv_add(dev); 40 | 41 | \end{verbatim} 42 | 43 | -------------------------------------------------------------------------------- /include/arch/pico_atsamd21j18.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved. 3 | See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage. 4 | *********************************************************************/ 5 | 6 | /*** MACHINE CONFIGURATION ***/ 7 | /* Temporary (POSIX) stuff. */ 8 | #include 9 | #include 10 | 11 | /* Temporary debugging stuff. */ 12 | #include 13 | #include "halUart.h" 14 | #include 15 | 16 | static void print_uart(char *str) 17 | { 18 | int i, len; 19 | len = (int)strlen(str); 20 | for (i = 0; i < len; i++) { 21 | HAL_UartWriteByte(str[i]); 22 | if (HAL_UartTxFull()) 23 | HAL_UartFlush(); 24 | } 25 | } 26 | 27 | static inline void sam_dbg(const char *format, ...) 28 | { 29 | char msg[128] = { 0 }; 30 | va_list args; 31 | va_start(args, format); 32 | vsnprintf(msg, 256, format, args); 33 | va_end(args); 34 | print_uart(msg); 35 | } 36 | 37 | //#define dbg sam_dbg 38 | #define dbg(...) do { } while(0) 39 | 40 | extern volatile uint32_t sam_tick; 41 | 42 | #define pico_zalloc(x) calloc(x, 1) 43 | #define pico_free(x) free(x) 44 | 45 | static inline unsigned long PICO_TIME(void) 46 | { 47 | register uint32_t tick = sam_tick; 48 | return tick / 1000; 49 | } 50 | 51 | static inline unsigned long PICO_TIME_MS(void) 52 | { 53 | return sam_tick; 54 | } 55 | 56 | static inline void PICO_IDLE(void) 57 | { 58 | unsigned long tick_now = sam_tick; 59 | while(tick_now == sam_tick) ; 60 | } 61 | 62 | -------------------------------------------------------------------------------- /modules/pico_dev_loop.c: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved. 3 | See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage. 4 | 5 | Authors: Daniele Lacamera 6 | *********************************************************************/ 7 | 8 | 9 | #include "pico_device.h" 10 | #include "pico_dev_loop.h" 11 | #include "pico_stack.h" 12 | 13 | 14 | #define LOOP_MTU 1500 15 | static uint8_t l_buf[LOOP_MTU]; 16 | static int l_bufsize = 0; 17 | 18 | 19 | static int pico_loop_send(struct pico_device *dev, void *buf, int len) 20 | { 21 | IGNORE_PARAMETER(dev); 22 | if (len > LOOP_MTU) 23 | return 0; 24 | 25 | if (l_bufsize == 0) { 26 | memcpy(l_buf, buf, (size_t)len); 27 | l_bufsize += len; 28 | return len; 29 | } 30 | 31 | return 0; 32 | } 33 | 34 | static int pico_loop_poll(struct pico_device *dev, int loop_score) 35 | { 36 | if (loop_score <= 0) 37 | return 0; 38 | 39 | if (l_bufsize > 0) { 40 | pico_stack_recv(dev, l_buf, (uint32_t)l_bufsize); 41 | l_bufsize = 0; 42 | loop_score--; 43 | } 44 | 45 | return loop_score; 46 | } 47 | 48 | 49 | struct pico_device *pico_loop_create(void) 50 | { 51 | struct pico_device *loop = PICO_ZALLOC(sizeof(struct pico_device)); 52 | if (!loop) 53 | return NULL; 54 | 55 | if( 0 != pico_device_init(loop, "loop", NULL)) { 56 | dbg ("Loop init failed.\n"); 57 | pico_device_destroy(loop); 58 | return NULL; 59 | } 60 | 61 | loop->send = pico_loop_send; 62 | loop->poll = pico_loop_poll; 63 | dbg("Device %s created.\n", loop->name); 64 | return loop; 65 | } 66 | 67 | -------------------------------------------------------------------------------- /test/python/multicast_send.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # 3 | # multicast_send.py 4 | # 5 | # Multicast test with PicoTCP sending and Linux receiving 6 | # 7 | # (sender) (Receiver) 8 | # PicoTCP ------------------------ Linux 9 | # mcast to 224.7.7.7 10 | # 11 | 12 | from topology import * 13 | import socket, random, string, struct 14 | 15 | IF_ADDR = '172.16.1.1' 16 | LINK_ADDR = '172.16.1.2' 17 | MCAST_ADDR = '224.7.7.7' 18 | LISTEN_PORT = 6667 19 | SENDTO_PORT = 6667 20 | MCASTSEND = "mcastsend:" + str(LINK_ADDR) + ":" + str(MCAST_ADDR) + ":" + str(SENDTO_PORT) + ":" + str(LISTEN_PORT) 21 | 22 | print MCASTSEND 23 | 24 | T = Topology() 25 | net1 = Network(T, "pyt0") 26 | h1 = Host(T, net1, args=MCASTSEND) 27 | 28 | s_udp = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 29 | s_udp.bind((MCAST_ADDR, LISTEN_PORT)) 30 | s_udp.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 31 | s_udp.settimeout(5); 32 | 33 | mreq = struct.pack("=4s4s", socket.inet_aton(str(MCAST_ADDR)), socket.inet_aton(str(IF_ADDR))) 34 | s_udp.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq) 35 | 36 | raw_input("Press enter to continue ...") 37 | start(T) 38 | sleep(1) 39 | 40 | while True: 41 | data = s_udp.recv(4096) 42 | #print data 43 | if 'end' in data: 44 | print '\n\n' 45 | print '+++++++++++++++++++++++++++++++++++++++++++++' 46 | print '+++++ multicast_send test IS successful +++++' 47 | print '+++++++++++++++++++++++++++++++++++++++++++++' 48 | print '\n\n' 49 | cleanup() 50 | exit(0) 51 | 52 | print '\n\n' 53 | print '+++++++++++++++++++++++++++++++++++++++++++++' 54 | print '+++++ multicast_send test NOT successful ++++' 55 | print '+++++++++++++++++++++++++++++++++++++++++++++' 56 | print '\n\n' 57 | cleanup() 58 | exit(1) 59 | -------------------------------------------------------------------------------- /docs/user_manual/chap_api_slaacv4.tex: -------------------------------------------------------------------------------- 1 | \section{SLAACV4 Module} 2 | 3 | % Short description/overview of module functions 4 | 5 | 6 | \subsection{pico\_slaacv4\_claimip} 7 | 8 | \subsubsection*{Description} 9 | This function starts the ip claiming process for a device. It will generate first the local link ip using 10 | as seed the mac address of the device. Then it will start the claim procedure described in RFC3927. 11 | In case of success the IP is registered to the IP layer and returned using the callback function. 12 | In case of error, code SLAACV4\_ERROR is returned. Errors occur when the maximum number of conflicts is reached. 13 | Use the IP returned only if the return code is SLAACV4\_SUCCESS. 14 | 15 | \subsubsection*{Function prototype} 16 | \texttt{pico\_slaacv4\_claimip(struct pico\_device *dev, void (*cb)(struct pico\_ip4 *ip, uint8\_t code));} 17 | 18 | \subsubsection*{Parameters} 19 | \begin{itemize}[noitemsep] 20 | \item \texttt{dev} - a pointer to a struct \texttt{pico\_device} 21 | \item \texttt{*cb} - a callback function returning the ip claimed and a return code (SLAACV4\_ERROR | SLAACV4\_SUCCESS) 22 | \end{itemize} 23 | 24 | \subsubsection*{Return value} 25 | 0 returned if the claiming has started successfully 26 | 27 | \subsubsection*{Example} 28 | \begin{verbatim} 29 | 30 | dev = pico_get_device(sdev); 31 | 32 | ret = pico_slaacv4_claimip(dev, slaacv4_cb); 33 | 34 | \end{verbatim} 35 | 36 | \subsection{pico\_slaacv4\_unregisterip} 37 | 38 | \subsubsection*{Description} 39 | This function allows to unregister the local link ip in usage. The function will remove from the route table 40 | the local link ip and will reset the internal state of the SLAACV4 module 41 | 42 | \subsubsection*{Function prototype} 43 | \texttt{void pico\_slaacv4\_unregisterip(void);} 44 | 45 | -------------------------------------------------------------------------------- /test/python/fragmentation.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # 3 | # fragmentation.py 4 | # 5 | # Fragmentation test with PicoTCP sending and Linux receiving 6 | # 7 | # (sender) (Receiver) 8 | # PicoTCP ------------------------ Linux 9 | # 10 | # An udpclient is started which will give DATASIZE bytes in one go 11 | # to the socket. This data will be fragmented and send over to the 12 | # Linux, where it is reassembled and received in one piece. 13 | # 14 | 15 | from topology import * 16 | import socket, random, string 17 | 18 | SRC_ADDR = '' 19 | DST_ADDR = '172.16.1.1' 20 | SRC_PORT = 6667 21 | SENDTO_PORT = 6667 22 | LISTEN_PORT = 6667 23 | DATASIZE = 4000 24 | LOOPS = 4 25 | SUBLOOPS = 1 26 | UDPCLIENT = "udpclient:" + str(DST_ADDR) + ":" + str(SENDTO_PORT) + ":" + str(LISTEN_PORT) + ":" + str(DATASIZE) + ":" + str(LOOPS) + ":" + str(SUBLOOPS) 27 | 28 | print UDPCLIENT 29 | 30 | T = Topology() 31 | net1 = Network(T, "pyt0") 32 | h1 = Host(T, net1, args=UDPCLIENT) 33 | 34 | s_udp = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 35 | s_udp.bind((SRC_ADDR, SRC_PORT)) 36 | s_udp.settimeout(5); 37 | 38 | raw_input("Press enter to continue ...") 39 | start(T) 40 | 41 | while True: 42 | data, addr = s_udp.recvfrom(DATASIZE) 43 | #print data 44 | if len(data) == DATASIZE: 45 | print '\n\n' 46 | print '+++++++++++++++++++++++++++++++++++++++++++++' 47 | print '+++++ fragmentation test IS successful +++++' 48 | print '+++++++++++++++++++++++++++++++++++++++++++++' 49 | print '\n\n' 50 | cleanup() 51 | exit(0) 52 | 53 | print '\n\n' 54 | print '+++++++++++++++++++++++++++++++++++++++++++++' 55 | print '+++++ fragmentation test NOT successful ++++' 56 | print '+++++++++++++++++++++++++++++++++++++++++++++' 57 | print '\n\n' 58 | cleanup() 59 | exit(1) 60 | 61 | -------------------------------------------------------------------------------- /modules/pico_dns_client.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved. 3 | See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage. 4 | 5 | . 6 | 7 | Authors: Kristof Roelants 8 | *********************************************************************/ 9 | 10 | #ifndef INCLUDE_PICO_DNS_CLIENT 11 | #define INCLUDE_PICO_DNS_CLIENT 12 | 13 | #define PICO_DNS_NS_DEL 0 14 | #define PICO_DNS_NS_ADD 1 15 | #include "pico_config.h" 16 | 17 | /* Compression values */ 18 | #define PICO_DNS_LABEL 0 19 | #define PICO_DNS_POINTER 3 20 | 21 | /* Label len */ 22 | #define PICO_DNS_LABEL_INITIAL 1u 23 | #define PICO_DNS_LABEL_ROOT 1 24 | 25 | /* TTL values */ 26 | #define PICO_DNS_MAX_TTL 604800 /* one week */ 27 | 28 | /* Len of an IPv4 address string */ 29 | #define PICO_DNS_IPV4_ADDR_LEN 16 30 | #define PICO_DNS_IPV6_ADDR_LEN 54 31 | 32 | /* Default nameservers + port */ 33 | #define PICO_DNS_NS_DEFAULT "208.67.222.222" 34 | #define PICO_DNS_NS_PORT 53 35 | 36 | /* RDLENGTH for A and AAAA RR's */ 37 | #define PICO_DNS_RR_A_RDLENGTH 4 38 | #define PICO_DNS_RR_AAAA_RDLENGTH 16 39 | 40 | int pico_dns_client_init(void); 41 | /* flag is PICO_DNS_NS_DEL or PICO_DNS_NS_ADD */ 42 | int pico_dns_client_nameserver(struct pico_ip4 *ns, uint8_t flag); 43 | int pico_dns_client_getaddr(const char *url, void (*callback)(char *ip, void *arg), void *arg); 44 | int pico_dns_client_getname(const char *ip, void (*callback)(char *url, void *arg), void *arg); 45 | #ifdef PICO_SUPPORT_IPV6 46 | int pico_dns_client_getaddr6(const char *url, void (*callback)(char *, void *), void *arg); 47 | int pico_dns_client_getname6(const char *url, void (*callback)(char *, void *), void *arg); 48 | #endif 49 | 50 | #endif /* _INCLUDE_PICO_DNS_CLIENT */ 51 | -------------------------------------------------------------------------------- /modules/pico_dev_null.c: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved. 3 | See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage. 4 | 5 | Authors: Daniele Lacamera 6 | *********************************************************************/ 7 | 8 | 9 | #include "pico_device.h" 10 | #include "pico_dev_null.h" 11 | #include "pico_stack.h" 12 | 13 | struct pico_device_null { 14 | struct pico_device dev; 15 | int statistics_frames_out; 16 | }; 17 | 18 | #define NULL_MTU 0 19 | 20 | static int pico_null_send(struct pico_device *dev, void *buf, int len) 21 | { 22 | struct pico_device_null *null = (struct pico_device_null *) dev; 23 | IGNORE_PARAMETER(buf); 24 | 25 | /* Increase the statistic count */ 26 | null->statistics_frames_out++; 27 | 28 | /* Discard the frame content silently. */ 29 | return len; 30 | } 31 | 32 | static int pico_null_poll(struct pico_device *dev, int loop_score) 33 | { 34 | /* We never have packet to receive, no score is used. */ 35 | IGNORE_PARAMETER(dev); 36 | return loop_score; 37 | } 38 | 39 | /* Public interface: create/destroy. */ 40 | 41 | 42 | struct pico_device *pico_null_create(const char *name) 43 | { 44 | struct pico_device_null *null = PICO_ZALLOC(sizeof(struct pico_device_null)); 45 | 46 | if (!null) 47 | return NULL; 48 | 49 | if( 0 != pico_device_init((struct pico_device *)null, name, NULL)) { 50 | return NULL; 51 | } 52 | 53 | null->dev.overhead = 0; 54 | null->statistics_frames_out = 0; 55 | null->dev.send = pico_null_send; 56 | null->dev.poll = pico_null_poll; 57 | dbg("Device %s created.\n", null->dev.name); 58 | return (struct pico_device *)null; 59 | } 60 | 61 | -------------------------------------------------------------------------------- /modules/pico_mcast.h: -------------------------------------------------------------------------------- 1 | #ifndef INCLUDE_PICO_MCAST 2 | #define INCLUDE_PICO_MCAST 3 | 4 | #define MCAST_MODE_IS_INCLUDE (1) 5 | #define MCAST_MODE_IS_EXCLUDE (2) 6 | #define MCAST_CHANGE_TO_INCLUDE_MODE (3) 7 | #define MCAST_CHANGE_TO_EXCLUDE_MODE (4) 8 | #define MCAST_ALLOW_NEW_SOURCES (5) 9 | #define MCAST_BLOCK_OLD_SOURCES (6) 10 | #define MCAST_EVENT_DELETE_GROUP (0x0) 11 | #define MCAST_EVENT_CREATE_GROUP (0x1) 12 | #define MCAST_EVENT_UPDATE_GROUP (0x2) 13 | #define MCAST_EVENT_QUERY_RECV (0x3) 14 | #define MCAST_EVENT_REPORT_RECV (0x4) 15 | #define MCAST_EVENT_TIMER_EXPIRED (0x5) 16 | #define MCAST_NO_REPORT (1) 17 | 18 | PACKED_STRUCT_DEF mcast_parameters { 19 | uint8_t event; 20 | uint8_t state; 21 | uint8_t general_query; 22 | uint8_t filter_mode; 23 | uint8_t last_host; 24 | uint16_t max_resp_time; 25 | union pico_address mcast_link; 26 | union pico_address mcast_group; 27 | struct pico_tree *MCASTFilter; 28 | struct pico_frame *f; 29 | }; 30 | 31 | PACKED_STRUCT_DEF pico_mcast_group { 32 | uint8_t filter_mode; 33 | uint16_t reference_count; 34 | union pico_address mcast_addr; 35 | struct pico_tree MCASTSources; 36 | }; 37 | 38 | PACKED_STRUCT_DEF mcast_filter_parameters { 39 | struct mcast_parameters *p; 40 | struct pico_tree *allow; 41 | struct pico_tree *block; 42 | struct pico_tree *filter; 43 | uint16_t sources; 44 | uint8_t proto; 45 | uint8_t record_type; 46 | struct pico_mcast_group *g; 47 | union pico_link *link; 48 | }; 49 | 50 | 51 | extern int8_t pico_mcast_generate_filter(struct mcast_filter_parameters *filter, struct mcast_parameters *p); 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /test/unit/modunit_seq.c: -------------------------------------------------------------------------------- 1 | #include "pico_tcp.c" 2 | #include 3 | 4 | Suite *pico_suite(void); 5 | 6 | START_TEST(tc_seq_compare) 7 | { 8 | uint32_t big_a = 0xFFFFFF0alu; 9 | uint32_t big_b = 0xFFFFFF0blu; 10 | uint32_t small_a = 0xalu; 11 | uint32_t small_b = 0xblu; 12 | uint32_t under_thresh = 0x7ffffffflu; 13 | uint32_t over_thresh = 0x80000000lu; 14 | uint32_t zero = 0lu; 15 | 16 | fail_if(pico_seq_compare(small_a, small_b) >= 0); 17 | fail_if(pico_seq_compare(small_b, small_a) <= 0); 18 | 19 | fail_if(pico_seq_compare(over_thresh, under_thresh) <= 0); 20 | fail_if(pico_seq_compare(under_thresh, over_thresh) >= 0); 21 | 22 | fail_if(pico_seq_compare(small_a, big_b) <= 0); 23 | fail_if(pico_seq_compare(big_b, small_a) >= 0); 24 | 25 | fail_if(pico_seq_compare(small_a, zero) <= 0); 26 | fail_if(pico_seq_compare(zero, small_a) >= 0); 27 | 28 | fail_if(pico_seq_compare(big_a, zero) >= 0); 29 | fail_if(pico_seq_compare(zero, big_a) <= 0); 30 | 31 | fail_if(pico_seq_compare(big_a, big_b) >= 0); 32 | fail_if(pico_seq_compare(big_b, big_a) <= 0); 33 | 34 | fail_if(pico_seq_compare(big_a, big_a) != 0); 35 | fail_if(pico_seq_compare(zero, zero) != 0); 36 | 37 | } 38 | END_TEST 39 | 40 | Suite *pico_suite(void) 41 | { 42 | Suite *s = suite_create("pico tcp sequence numbers"); 43 | TCase *TCase_seq_compare = tcase_create("Unit test for pico_seq_compare"); 44 | tcase_add_test(TCase_seq_compare, tc_seq_compare); 45 | suite_add_tcase(s, TCase_seq_compare); 46 | return s; 47 | } 48 | 49 | int main(void) 50 | { 51 | int fails; 52 | Suite *s = pico_suite(); 53 | SRunner *sr = srunner_create(s); 54 | srunner_run_all(sr, CK_NORMAL); 55 | fails = srunner_ntests_failed(sr); 56 | srunner_free(sr); 57 | return fails; 58 | } 59 | 60 | -------------------------------------------------------------------------------- /test/python/reassembly.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # 3 | # reassemby.py 4 | # 5 | # Reassemly test with PicoTCP receiving and Linux sending 6 | # 7 | # (receiver) (Sender) 8 | # PicoTCP ------------------------ Linux 9 | # 10 | # An udpecho is started which will receive DATASIZE bytes in one go 11 | # from the socket. The Linux will send DATASIZE bytes in one go to the 12 | # udpecho, this data will be sent fragmented. The udpecho is to reassemble 13 | # this data and echo it back. 14 | # 15 | 16 | from topology import * 17 | import socket, random, string 18 | 19 | SRC_ADDR = '' 20 | LINK_ADDR = '172.16.1.2' 21 | SRC_PORT = 5555 22 | LISTEN_PORT = 6667 23 | SENDTO_PORT = 5555 24 | DATASIZE = 3400 25 | UDPECHO = "udpecho:" + str(LINK_ADDR) + ":" + str(LISTEN_PORT) + ":" + str(SENDTO_PORT) + ":" + str(DATASIZE) 26 | 27 | print UDPECHO 28 | 29 | T = Topology() 30 | net1 = Network(T, "pyt0") 31 | h1 = Host(T, net1, args=UDPECHO) 32 | 33 | str_send = ''.join(random.choice(string.ascii_lowercase) for x in range(DATASIZE)) 34 | #print str_send 35 | s_udp = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 36 | s_udp.bind((SRC_ADDR, SRC_PORT)) 37 | s_udp.settimeout(5); 38 | 39 | raw_input("Press enter to continue ...") 40 | start(T) 41 | 42 | while True: 43 | s_udp.sendto(str_send, (LINK_ADDR, LISTEN_PORT)) 44 | data = s_udp.recv(DATASIZE) 45 | #print len(data) 46 | if len(data) == DATASIZE: 47 | print '\n\n' 48 | print '+++++++++++++++++++++++++++++++++++++++++++++' 49 | print '+++++ reassembly test IS successful +++++' 50 | print '+++++++++++++++++++++++++++++++++++++++++++++' 51 | print '\n\n' 52 | cleanup() 53 | exit(0) 54 | 55 | print '\n\n' 56 | print '+++++++++++++++++++++++++++++++++++++++++++++' 57 | print '+++++ reassembly test NOT successful ++++' 58 | print '+++++++++++++++++++++++++++++++++++++++++++++' 59 | print '\n\n' 60 | cleanup() 61 | exit(1) 62 | 63 | -------------------------------------------------------------------------------- /test/examples/slaacv4.c: -------------------------------------------------------------------------------- 1 | #include "utils.h" 2 | #include 3 | #include 4 | /*** START SLAACV4 ***/ 5 | 6 | void ping_callback_slaacv4(struct pico_icmp4_stats *s) 7 | { 8 | char host[30] = { }; 9 | 10 | pico_ipv4_to_string(host, s->dst.addr); 11 | if (s->err == 0) { 12 | dbg("SLAACV4: %lu bytes from %s: icmp_req=%lu ttl=64 time=%lu ms\n", s->size, host, 13 | s->seq, (long unsigned int)s->time); 14 | if (s->seq >= 3) { 15 | dbg("SLAACV4: TEST SUCCESS!\n"); 16 | pico_slaacv4_unregisterip(); 17 | exit(0); 18 | } 19 | } else { 20 | dbg("SLAACV4: ping %lu to %s error %d\n", s->seq, host, s->err); 21 | dbg("SLAACV4: TEST FAILED!\n"); 22 | exit(1); 23 | } 24 | } 25 | 26 | void slaacv4_cb(struct pico_ip4 *ip, uint8_t code) 27 | { 28 | char dst[16] = "169.254.22.5"; 29 | printf("SLAACV4 CALLBACK ip:0x%X code:%d \n", ip->addr, code); 30 | if (code == 0) 31 | { 32 | #ifdef PICO_SUPPORT_PING 33 | pico_icmp4_ping(dst, 3, 1000, 5000, 32, ping_callback_slaacv4); 34 | #else 35 | exit(0); 36 | #endif 37 | } 38 | else 39 | { 40 | exit(255); 41 | } 42 | 43 | } 44 | 45 | 46 | void app_slaacv4(char *arg) 47 | { 48 | char *sdev = NULL; 49 | char *nxt = arg; 50 | struct pico_device *dev = NULL; 51 | 52 | if (!nxt) 53 | exit(255); 54 | 55 | while (nxt) { 56 | if (nxt) { 57 | nxt = cpy_arg(&sdev, nxt); 58 | if(!sdev) { 59 | exit(255); 60 | } 61 | } 62 | } 63 | dev = pico_get_device(sdev); 64 | free(sdev); 65 | if(dev == NULL) { 66 | printf("%s: error getting device %s: %s\n", __FUNCTION__, dev->name, strerror(pico_err)); 67 | exit(255); 68 | } 69 | 70 | pico_slaacv4_claimip(dev, slaacv4_cb); 71 | } 72 | /*** END SLAACv4 ***/ 73 | -------------------------------------------------------------------------------- /test/olsr_test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | sudo vde_switch -t pic0 -s /tmp/pic0.ctl -d 4 | sudo vde_switch -s /tmp/pic1.ctl -d 5 | sudo vde_switch -s /tmp/pic2.ctl -d 6 | sudo vde_switch -s /tmp/pic3.ctl -d 7 | 8 | sudo ifconfig pic0 10.40.0.254/16 up 9 | 10 | ./build/test/picoapp.elf \ 11 | --vde pic0:/tmp/pic0.ctl:10.40.0.8:255.255.0.0: \ 12 | -a olsr: & 13 | 14 | ./build/test/picoapp.elf \ 15 | --vde pic0:/tmp/pic0.ctl:10.40.0.9:255.255.0.0: \ 16 | --vde pic1:/tmp/pic1.ctl:10.41.0.9:255.255.0.0: \ 17 | -a olsr: & 18 | 19 | ./build/test/picoapp.elf \ 20 | --vde pic0:/tmp/pic1.ctl:10.41.0.1:255.255.0.0: \ 21 | -a olsr: & 22 | 23 | ./build/test/picoapp.elf \ 24 | --vde pic0:/tmp/pic1.ctl:10.41.0.2:255.255.0.0: \ 25 | -a olsr: & 26 | 27 | ./build/test/picoapp.elf \ 28 | --vde pic0:/tmp/pic1.ctl:10.41.0.3:255.255.0.0: \ 29 | -a olsr: & 30 | 31 | ./build/test/picoapp.elf \ 32 | --vde pic0:/tmp/pic1.ctl:10.41.0.10:255.255.0.0: \ 33 | --vde pic1:/tmp/pic2.ctl:10.42.0.10:255.255.0.0: \ 34 | -a olsr: & 35 | 36 | ./build/test/picoapp.elf \ 37 | --vde pic0:/tmp/pic2.ctl:10.42.0.1:255.255.0.0: \ 38 | -a olsr: & 39 | 40 | ./build/test/picoapp.elf \ 41 | --vde pic0:/tmp/pic2.ctl:10.42.0.2:255.255.0.0: \ 42 | -a olsr: & 43 | 44 | ./build/test/picoapp.elf \ 45 | --vde pic0:/tmp/pic1.ctl:10.42.0.3:255.255.0.0: \ 46 | -a olsr: & 47 | 48 | ./build/test/picoapp.elf \ 49 | --vde pic0:/tmp/pic2.ctl:10.42.0.11:255.255.0.0: \ 50 | --vde pic1:/tmp/pic3.ctl:10.43.0.11:255.255.0.0: \ 51 | -a olsr: & 52 | 53 | ./build/test/picoapp.elf \ 54 | --vde pic0:/tmp/pic3.ctl:10.43.0.1:255.255.0.0: \ 55 | -a olsr: & 56 | 57 | ./build/test/picoapp.elf \ 58 | --vde pic0:/tmp/pic3.ctl:10.43.0.2:255.255.0.0: \ 59 | -a olsr: & 60 | 61 | ./build/test/picoapp.elf \ 62 | --vde pic0:/tmp/pic3.ctl:10.43.0.3:255.255.0.0: \ 63 | -a olsr: & 64 | 65 | sleep 5 66 | sudo killall olsrd 67 | sudo olsrd -i pic0 68 | 69 | -------------------------------------------------------------------------------- /include/pico_constants.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved. 3 | See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage. 4 | 5 | *********************************************************************/ 6 | #ifndef INCLUDE_PICO_CONST 7 | #define INCLUDE_PICO_CONST 8 | /* Included from pico_config.h */ 9 | 10 | /** Non-endian dependant constants */ 11 | #define PICO_SIZE_IP4 4 12 | #define PICO_SIZE_IP6 16 13 | #define PICO_SIZE_ETH 6 14 | #define PICO_SIZE_TRANS 8 15 | #define PICO_SIZE_IEEE802154_EXT (8u) 16 | #define PICO_SIZE_IEEE802154_SHORT (2u) 17 | 18 | /** Endian-dependant constants **/ 19 | typedef uint64_t pico_time; 20 | extern volatile uint64_t pico_tick; 21 | 22 | 23 | /*** *** *** *** *** *** *** 24 | *** ARP CONFIG *** 25 | *** *** *** *** *** *** ***/ 26 | 27 | #include "pico_addressing.h" 28 | 29 | /* Maximum amount of accepted ARP requests per burst interval */ 30 | #define PICO_ARP_MAX_RATE 1 31 | /* Duration of the burst interval in milliseconds */ 32 | #define PICO_ARP_INTERVAL 1000 33 | 34 | /* Add well-known host numbers here. (bigendian constants only beyond this point) */ 35 | #define PICO_IP4_ANY (0x00000000U) 36 | #define PICO_IP4_BCAST (0xffffffffU) 37 | 38 | #define PICO_IEEE802154_BCAST (0xffffu) 39 | 40 | /* defined in modules/pico_ipv6.c */ 41 | #ifdef PICO_SUPPORT_IPV6 42 | extern const uint8_t PICO_IPV6_ANY[PICO_SIZE_IP6]; 43 | #endif 44 | 45 | static inline uint32_t pico_hash(const void *buf, uint32_t size) 46 | { 47 | uint32_t hash = 5381; 48 | uint32_t i; 49 | const uint8_t *ptr = (const uint8_t *)buf; 50 | for(i = 0; i < size; i++) 51 | hash = ((hash << 5) + hash) + ptr[i]; /* hash * 33 + char */ 52 | return hash; 53 | } 54 | 55 | /* Debug */ 56 | /* #define PICO_SUPPORT_DEBUG_MEMORY */ 57 | /* #define PICO_SUPPORT_DEBUG_TOOLS */ 58 | #endif 59 | -------------------------------------------------------------------------------- /docs/user_manual/chap_api_olsr.tex: -------------------------------------------------------------------------------- 1 | \section{Optimized Link State Routing (OLSR) Module} 2 | 3 | 4 | OLSR is a proactive routing protocol for mobile ad-hoc networks 5 | (MANETs). It is well suited to large and dense mobile 6 | networks, as the optimization achieved using the MPRs works well in 7 | this context. The larger and more dense a network, the more 8 | optimization can be achieved as compared to the classic link state 9 | algorithm. OLSR uses hop-by-hop routing, i.e., each node uses its 10 | local information to route packets. 11 | 12 | OLSR is well suited for networks, where the traffic is random and 13 | sporadic between a larger set of nodes rather than being almost 14 | exclusively between a small specific set of nodes. As a proactive 15 | protocol, OLSR is also suitable for scenarios where the communicating 16 | pairs change over time: no additional control traffic is generated in 17 | this situation since routes are maintained for all known destinations 18 | at all times. -- cfr. RFC3626 19 | 20 | 21 | \subsection{pico\_olsr\_add} 22 | 23 | \subsubsection*{Description} 24 | This function will add the target device to the OLSR mechanism on the machine, 25 | meaning that it will be possible to advertise and collect routing information 26 | using Optimized Link State Routing protocol, as described in RFC3626, through the 27 | target device. 28 | 29 | In order to use multiple devices in the OLSR system, this function needs to be called 30 | multiple times, once per device. 31 | 32 | \subsubsection*{Function prototype} 33 | \texttt{pico\_olsr\_add(struct pico\_device *dev);} 34 | 35 | \subsubsection*{Parameters} 36 | \begin{itemize}[noitemsep] 37 | \item \texttt{dev} - a pointer to a struct \texttt{pico\_device} specifying the target interface. 38 | \end{itemize} 39 | 40 | \subsubsection*{Return value} 41 | 0 returned if the device is successfully added. 42 | 43 | \subsubsection*{Example} 44 | \begin{verbatim} 45 | 46 | ret = pico_olsr_add(dev); 47 | 48 | \end{verbatim} 49 | 50 | -------------------------------------------------------------------------------- /modules/pico_dev_mock.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved. 3 | See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage. 4 | 5 | *********************************************************************/ 6 | #ifndef INCLUDE_PICO_MOCK 7 | #define INCLUDE_PICO_MOCK 8 | #include "pico_config.h" 9 | #include "pico_device.h" 10 | 11 | 12 | struct mock_frame { 13 | uint8_t*buffer; 14 | int len; 15 | int read; 16 | 17 | struct mock_frame*next; 18 | }; 19 | 20 | struct mock_device { 21 | struct pico_device*dev; 22 | struct mock_frame*in_head; 23 | struct mock_frame*in_tail; 24 | struct mock_frame*out_head; 25 | struct mock_frame*out_tail; 26 | 27 | uint8_t*mac; 28 | 29 | }; 30 | 31 | struct mock_device; 32 | /* A mockup-device for the purpose of testing. It provides a couple of extra "network"-functions, which represent the network-side of the device. A network_send will result in mock_poll reading something, a network_read will see if the stack has sent anything through our mock-device. */ 33 | void pico_mock_destroy(struct pico_device *dev); 34 | struct mock_device *pico_mock_create(uint8_t*mac); 35 | 36 | int pico_mock_network_read(struct mock_device*mock, void *buf, int len); 37 | int pico_mock_network_write(struct mock_device*mock, const void *buf, int len); 38 | 39 | /* TODO */ 40 | /* we could use a few checking functions, e.g. one to see if it's a valid IP packet, if it's TCP, if the IP-address matches,... */ 41 | /* That would be useful to avoid having to manually create buffers of what you expect, probably with masks for things that are random,... */ 42 | uint32_t mock_get_sender_ip4(struct mock_device*mock, void*buf, int len); 43 | 44 | int mock_ip_protocol(struct mock_device*mock, void*buf, int len); 45 | int mock_icmp_type(struct mock_device*mock, void*buf, int len); 46 | int mock_icmp_code(struct mock_device*mock, void*buf, int len); 47 | #endif 48 | -------------------------------------------------------------------------------- /test/unit/modunit_pico_strings.c: -------------------------------------------------------------------------------- 1 | #include "modules/pico_strings.c" 2 | #include "check.h" 3 | 4 | Suite *pico_suite(void); 5 | 6 | START_TEST(tc_get_string_terminator_position) 7 | { 8 | char buf[6] = "unit"; 9 | get_string_terminator_position(NULL,0); 10 | fail_if(get_string_terminator_position(buf,2) != 0); 11 | fail_if(get_string_terminator_position(buf,6) != &buf[4]); 12 | } 13 | END_TEST 14 | START_TEST(tc_pico_strncasecmp) 15 | { 16 | fail_if(pico_strncasecmp("unit","UNIT",4) != 0); 17 | fail_if(pico_strncasecmp("unit1","UNIT2",5) != -1); 18 | fail_if(pico_strncasecmp("unit2","UNIT1",5) != 1); 19 | } 20 | END_TEST 21 | START_TEST(tc_num2string) 22 | { 23 | char buf[20]; 24 | fail_if(num2string(-1,NULL,1) != -1); 25 | fail_if(num2string(1,NULL,1) != -1); 26 | fail_if(num2string(1,buf,1) != -1); 27 | fail_if(num2string(1,buf,3) != 2); 28 | fail_if(num2string(11,buf,3) != 3); 29 | fail_if(num2string(112,buf,4) != 4); 30 | } 31 | END_TEST 32 | 33 | Suite *pico_suite(void) 34 | { 35 | Suite *s = suite_create("PicoTCP"); 36 | 37 | TCase *TCase_get_string_terminator_position = tcase_create("Unit test for get_string_terminator_position"); 38 | TCase *TCase_num2string = tcase_create("Unit test for num2string"); 39 | TCase *TCase_pico_strncasecmp = tcase_create("Unit test for pico_strncasecmp"); 40 | 41 | tcase_add_test(TCase_get_string_terminator_position, tc_get_string_terminator_position); 42 | suite_add_tcase(s, TCase_get_string_terminator_position); 43 | tcase_add_test(TCase_num2string,tc_num2string); 44 | suite_add_tcase(s, TCase_num2string); 45 | tcase_add_test(TCase_pico_strncasecmp,tc_pico_strncasecmp); 46 | suite_add_tcase(s, TCase_pico_strncasecmp); 47 | 48 | return s; 49 | } 50 | int main(void) 51 | { 52 | int fails; 53 | Suite *s = pico_suite(); 54 | SRunner *sr = srunner_create(s); 55 | srunner_run_all(sr, CK_NORMAL); 56 | fails = srunner_ntests_failed(sr); 57 | srunner_free(sr); 58 | return fails; 59 | } 60 | -------------------------------------------------------------------------------- /docs/user_manual/chap_api_mld.tex: -------------------------------------------------------------------------------- 1 | \section{MLD} 2 | 3 | % Short description/overview of module functions 4 | This module allows the user to join and leave ipv6 multicast groups. The module is based on the MLD version 2 protocol and it's backwards compatible with version 1. 5 | The MLD module is completly driven from socket calls (\ref{socket:setoption}) and non of the MLD application interface functions should be called by the user. If however, by any reason, it's necessary for the user to do this, the following function call is provided: 6 | 7 | \subsection{pico\_mld\_state\_change} 8 | 9 | \subsubsection*{Description} 10 | Change the state of the host to Non-listener, Idle listener or Delaying listener. 11 | 12 | \subsubsection*{Function prototype} 13 | \begin{verbatim} 14 | int pico_mld_state_change(struct pico_ip6 *mcast_link, struct pico_ip6 *mcast_group, 15 | uint8_t filter_mode, struct pico_tree *_MCASTFilter, uint8_t state) 16 | \end{verbatim} 17 | 18 | \subsubsection*{Parameters} 19 | \begin{itemize}[noitemsep] 20 | \item \texttt{mcast\_link} - the link on which that multicast group should be joined. 21 | \item \texttt{mcast\_group} - the address of the multicast group you want to join. 22 | \item \texttt{filter\_mode} - the kind of source filtering, if applied. 23 | \item \texttt{\_MCASTFilter} - list of multicast sources on which source filtering might be applied. 24 | \item \texttt{state} - the prefered new state. 25 | \end{itemize} 26 | 27 | \subsubsection*{Errors} 28 | In case of failure, -1 is returned, and the value of pico$\_$err 29 | is set as follows: 30 | 31 | \begin{itemize}[noitemsep] 32 | \item \texttt{PICO$\_$ERR$\_$EINVAL} - Invalid argument provided 33 | \item \texttt{PICO$\_$ERR$\_$ENOMEM} - Not enough space 34 | \item \texttt{PICO$\_$ERR$\_$EPROTONOSUPPORT} - Invalid protocol (or protocol version) found on the link 35 | \item \texttt{PICO$\_$ERR$\_$EFAULT} - Internal error 36 | \end{itemize} 37 | 38 | %\subsubsection*{Example} 39 | 40 | %\subsubsection*{Errors} 41 | 42 | %\subsubsection*{Example} 43 | -------------------------------------------------------------------------------- /test/examples/sntp.c: -------------------------------------------------------------------------------- 1 | #include "utils.h" 2 | #include 3 | /*** START SNTP ***/ 4 | 5 | #ifdef PICO_SUPPORT_SNTP_CLIENT 6 | 7 | void sntp_timeout(pico_time __attribute__((unused)) now, void *arg) 8 | { 9 | struct pico_timeval ptv; 10 | struct timeval tv; 11 | pico_sntp_gettimeofday(&ptv); 12 | gettimeofday(&tv, NULL); 13 | printf("Linux sec: %u, msec: %u\n", (unsigned int)tv.tv_sec, (unsigned int)tv.tv_usec / 1000); 14 | printf("Picotcp sec: %u, msec: %u\n", (unsigned int)ptv.tv_sec, (unsigned int)ptv.tv_msec); 15 | printf("SNTP test succesfull!\n"); 16 | exit(0); 17 | } 18 | 19 | void cb_synced(pico_err_t status) 20 | { 21 | if(status == PICO_ERR_ENETDOWN) { 22 | printf("SNTP: Cannot resolve ntp server name\n"); 23 | exit(1); 24 | } else if (status == PICO_ERR_ETIMEDOUT) { 25 | printf("SNTP: Timed out, did not receive ntp packet from server\n"); 26 | exit(1); 27 | } else if (status == PICO_ERR_EINVAL) { 28 | printf("SNTP: Conversion error\n"); 29 | exit(1); 30 | } else if (status == PICO_ERR_ENOTCONN) { 31 | printf("SNTP: Socket error\n"); 32 | exit(1); 33 | } else if (status == PICO_ERR_NOERR) { 34 | if (!pico_timer_add(2000, sntp_timeout, NULL)) { 35 | printf("SNTP: Failed to start timeout timer, exiting program \n"); 36 | exit(1); 37 | } 38 | } else { 39 | printf("SNTP: Invalid status received in cb_synced\n"); 40 | exit(1); 41 | } 42 | } 43 | 44 | void app_sntp(char *servername) 45 | { 46 | struct pico_timeval tv; 47 | printf("Starting SNTP query towards %s\n", servername); 48 | if(pico_sntp_gettimeofday(&tv) == 0) 49 | printf("Wrongly succesfull gettimeofday\n"); 50 | else 51 | printf("Unsuccesfull gettimeofday (not synced)\n"); 52 | 53 | if(pico_sntp_sync(servername, &cb_synced) == 0) 54 | printf("Succesfull sync call!\n"); 55 | else 56 | printf("Error in sync\n"); 57 | } 58 | #endif 59 | /*** END SNTP ***/ 60 | -------------------------------------------------------------------------------- /docs/user_manual/chap_api_igmp.tex: -------------------------------------------------------------------------------- 1 | \section{IGMP} 2 | 3 | % Short description/overview of module functions 4 | This module allows the user to join and leave ipv4 multicast groups. The module is based on the IGMP version 3 protocol and it's backwards compatible with version 2. Version 1 is not supported. 5 | The IGMP module is completly driven from socket calls (\ref{socket:setoption}) and non of the IGMP application interface functions should be called by the user. If however, by any reason, it's necessary for the user to do this, the following function call is provided: 6 | 7 | \subsection{pico\_igmp\_state\_change} 8 | 9 | \subsubsection*{Description} 10 | Change the state of the host to Non-member, Idle member or Delaying member. 11 | 12 | \subsubsection*{Function prototype} 13 | \begin{verbatim} 14 | int pico_igmp_state_change(struct pico_ip4 *mcast_link, struct pico_ip4 *mcast_group, 15 | uint8_t filter_mode, struct pico_tree *_MCASTFilter, uint8_t state) 16 | \end{verbatim} 17 | 18 | \subsubsection*{Parameters} 19 | \begin{itemize}[noitemsep] 20 | \item \texttt{mcast\_link} - the link on which that multicast group should be joined. 21 | \item \texttt{mcast\_group} - the address of the multicast group you want to join. 22 | \item \texttt{filter\_mode} - the kind of source filtering, if applied. 23 | \item \texttt{\_MCASTFilter} - list of multicast sources on which source filtering might be applied. 24 | \item \texttt{state} - the prefered new state. 25 | \end{itemize} 26 | 27 | \subsubsection*{Errors} 28 | In case of failure, -1 is returned, and the value of pico$\_$err 29 | is set as follows: 30 | 31 | \begin{itemize}[noitemsep] 32 | \item \texttt{PICO$\_$ERR$\_$EINVAL} - Invalid argument provided 33 | \item \texttt{PICO$\_$ERR$\_$ENOMEM} - Not enough space 34 | \item \texttt{PICO$\_$ERR$\_$EPROTONOSUPPORT} - Invalid protocol (or protocol version) found on the link 35 | \item \texttt{PICO$\_$ERR$\_$EFAULT} - Internal error 36 | \end{itemize} 37 | 38 | %\subsubsection*{Example} 39 | 40 | %\subsubsection*{Errors} 41 | 42 | %\subsubsection*{Example} 43 | -------------------------------------------------------------------------------- /test/python/multicast_recv.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # multicast_recv.py 3 | # 4 | # Multicast test with PicoTCP receiving and Linux sending 5 | # 6 | # (sender) (Receiver) 7 | # Linux ------------------------ PicoTCP 8 | # mcast to 224.7.7.7 9 | # 10 | from topology import * 11 | import socket, random, string 12 | 13 | IF_ADDR = '172.16.1.1' 14 | LINK_ADDR = '172.16.1.2' 15 | MCAST_ADDR = '224.7.7.7' 16 | SRC_PORT = 5555 17 | LISTEN_PORT = 6667 18 | SENDTO_PORT = 6667 19 | MCASTRECV = "mcastreceive:" + str(LINK_ADDR) + ":" + str(MCAST_ADDR) + ":" + str(LISTEN_PORT) + ":" + str(SENDTO_PORT) 20 | 21 | print MCASTRECV 22 | 23 | T = Topology() 24 | net1 = Network(T, "pyt0") 25 | h1 = Host(T, net1, args=MCASTRECV) 26 | 27 | # sending socket 28 | s_udp = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 29 | s_udp.bind((IF_ADDR, SRC_PORT)) 30 | s_udp.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 31 | s_udp.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2) 32 | s_udp.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_IF, socket.inet_aton(str(IF_ADDR))) 33 | 34 | # receiving socket 35 | s_udp_recv = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 36 | s_udp_recv.bind((IF_ADDR, LISTEN_PORT)) 37 | s_udp_recv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 38 | s_udp_recv.settimeout(5); 39 | 40 | raw_input("Press enter to continue ...") 41 | start(T) 42 | sleep(1) 43 | 44 | while True: 45 | s_udp.sendto("multicast test succeeded", (str(MCAST_ADDR), LISTEN_PORT)) 46 | data = s_udp_recv.recv(4096) 47 | #print data 48 | if 'succeeded' in data: 49 | print '\n\n' 50 | print '+++++++++++++++++++++++++++++++++++++++++++++' 51 | print '+++++ multicast_recv test IS successful +++++' 52 | print '+++++++++++++++++++++++++++++++++++++++++++++' 53 | print '\n\n' 54 | cleanup() 55 | exit(0) 56 | 57 | print '\n\n' 58 | print '+++++++++++++++++++++++++++++++++++++++++++++' 59 | print '+++++ multicast_recv test NOT successful ++++' 60 | print '+++++++++++++++++++++++++++++++++++++++++++++' 61 | print '\n\n' 62 | cleanup() 63 | exit(1) 64 | 65 | -------------------------------------------------------------------------------- /include/pico_device.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved. 3 | See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage. 4 | 5 | *********************************************************************/ 6 | #ifndef INCLUDE_PICO_DEVICE 7 | #define INCLUDE_PICO_DEVICE 8 | #include "pico_queue.h" 9 | #include "pico_frame.h" 10 | #include "pico_addressing.h" 11 | #include "pico_tree.h" 12 | extern struct pico_tree Device_tree; 13 | #include "pico_ipv6_nd.h" 14 | #define MAX_DEVICE_NAME 16 15 | 16 | 17 | struct pico_ethdev { 18 | struct pico_eth mac; 19 | }; 20 | 21 | struct pico_device { 22 | char name[MAX_DEVICE_NAME]; 23 | uint32_t hash; 24 | uint32_t overhead; 25 | uint32_t mtu; 26 | struct pico_ethdev *eth; /* Null if non-ethernet */ 27 | enum pico_ll_mode mode; 28 | struct pico_queue *q_in; 29 | struct pico_queue *q_out; 30 | int (*link_state)(struct pico_device *self); 31 | int (*send)(struct pico_device *self, void *buf, int len); /* Send function. Return 0 if busy */ 32 | int (*poll)(struct pico_device *self, int loop_score); 33 | void (*destroy)(struct pico_device *self); 34 | int (*dsr)(struct pico_device *self, int loop_score); 35 | int __serving_interrupt; 36 | /* used to signal the upper layer the number of events arrived since the last processing */ 37 | volatile int eventCnt; 38 | #ifdef PICO_SUPPORT_IPV6 39 | struct pico_nd_hostvars hostvars; 40 | #endif 41 | }; 42 | 43 | 44 | int pico_device_init(struct pico_device *dev, const char *name, const uint8_t *mac); 45 | void pico_device_destroy(struct pico_device *dev); 46 | int pico_devices_loop(int loop_score, int direction); 47 | struct pico_device*pico_get_device(const char*name); 48 | int32_t pico_device_broadcast(struct pico_frame *f); 49 | int pico_device_link_state(struct pico_device *dev); 50 | int pico_device_ipv6_random_ll(struct pico_device *dev); 51 | #ifdef PICO_SUPPORT_IPV6 52 | struct pico_ipv6_link *pico_ipv6_link_add_local(struct pico_device *dev, const struct pico_ip6 *prefix); 53 | #endif 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /test/unit/unit_mocks.c: -------------------------------------------------------------------------------- 1 | #define BUFLEN (576 + 14 + 20 + 8) 2 | 3 | int mock_print_protocol(uint8_t *buf); 4 | int printbuf(uint8_t *buf, uint32_t len, const char *str, uint8_t printbufactive); 5 | int tick_it(uint32_t nticks); 6 | 7 | int mock_print_protocol(uint8_t *buf) 8 | { 9 | uint8_t pnr = buf[0x17]; /* protocol number */ 10 | 11 | printf("transport protocol: %s\n", 12 | (pnr == PICO_PROTO_ICMP4 ? "icmp4" : 13 | (pnr == PICO_PROTO_IGMP ? "igmp" : 14 | (pnr == PICO_PROTO_TCP ? "tcp" : 15 | (pnr == PICO_PROTO_UDP ? "udp" : 16 | (pnr == PICO_PROTO_ICMP6 ? "icmp6" : 17 | "unknown proto")))))); 18 | return 0; 19 | } 20 | 21 | int printbuf(uint8_t *buf, uint32_t len, const char *str, uint8_t printbufactive) 22 | { 23 | uint8_t printMethod = 0; 24 | uint32_t cntr = 0; 25 | uint32_t cntr2 = 0; 26 | if((printbufactive) && (printMethod == 0)) { 27 | printf("\n%s:\n", str); 28 | for(cntr = 0; cntr < len; cntr++) { 29 | if((cntr % 8) == 0 && cntr != 0) 30 | printf(" "); 31 | 32 | if((cntr % 16) == 0 && cntr != 0) 33 | printf("\n"); 34 | 35 | if((cntr % 16) == 0) 36 | printf("%03x0 ", cntr2++); 37 | 38 | printf("%02x ", buf[cntr]); 39 | } 40 | printf("\n"); 41 | }else if((printbufactive) && (printMethod == 1)) { 42 | printf("\n%s:\n", str); 43 | printf("Buf = {"); 44 | for(cntr = 0; cntr < len; cntr++) { 45 | if(cntr != 0) 46 | printf(","); 47 | 48 | if((cntr % 16 == 0) && (cntr != 0)) 49 | printf("\n"); 50 | 51 | printf("0x%02x", buf[cntr]); 52 | } 53 | printf("}\n"); 54 | } 55 | 56 | return 0; 57 | } 58 | 59 | #define BUFLEN (576 + 14 + 20 + 8) 60 | #define DHCP_MSG_TYPE_DISCOVER (1) 61 | #define DHCP_MSG_TYPE_OFFER (2) 62 | #define DHCP_MSG_TYPE_REQUEST (3) 63 | #define DHCP_MSG_TYPE_ACK (4) 64 | int tick_it(uint32_t nticks) 65 | { 66 | uint32_t i = 0; 67 | for (i = 0; i < nticks; i++) { 68 | pico_stack_tick(); 69 | } 70 | return 0; 71 | } 72 | -------------------------------------------------------------------------------- /test/units.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | rm -f /tmp/pico-mem-report-* 3 | 4 | ASAN_OPTIONS="detect_leaks=0" ./build/test/units || exit 1 5 | ASAN_OPTIONS="detect_leaks=0" ./build/test/modunit_fragments.elf || exit 1 6 | ASAN_OPTIONS="detect_leaks=0" ./build/test/modunit_pico_stack.elf || exit 1 7 | ASAN_OPTIONS="detect_leaks=0" ./build/test/modunit_802154.elf || exit 1 8 | ASAN_OPTIONS="detect_leaks=0" ./build/test/modunit_6lowpan.elf || exit 1 9 | ASAN_OPTIONS="detect_leaks=0" ./build/test/modunit_ethernet.elf || exit 1 10 | ASAN_OPTIONS="detect_leaks=0" ./build/test/modunit_pico_protocol.elf || exit 1 11 | ASAN_OPTIONS="detect_leaks=0" ./build/test/modunit_pico_frame.elf || exit 1 12 | ASAN_OPTIONS="detect_leaks=0" ./build/test/modunit_seq.elf || exit 1 13 | ASAN_OPTIONS="detect_leaks=0" ./build/test/modunit_tcp.elf || exit 1 14 | ASAN_OPTIONS="detect_leaks=0" ./build/test/modunit_dev_loop.elf || exit 1 15 | ASAN_OPTIONS="detect_leaks=0" ./build/test/modunit_dns_client.elf || exit 1 16 | ASAN_OPTIONS="detect_leaks=0" ./build/test/modunit_dns_common.elf || exit 1 17 | ASAN_OPTIONS="detect_leaks=0" ./build/test/modunit_sntp_client.elf || exit 1 18 | ASAN_OPTIONS="detect_leaks=0" ./build/test/modunit_ipv6_nd.elf || exit 1 19 | ASAN_OPTIONS="detect_leaks=0" ./build/test/modunit_mdns.elf || exit 1 20 | ASAN_OPTIONS="detect_leaks=0" ./build/test/modunit_dns_sd.elf || exit 1 21 | ASAN_OPTIONS="detect_leaks=0" ./build/test/modunit_ipfilter.elf || exit 1 22 | ASAN_OPTIONS="detect_leaks=0" ./build/test/modunit_queue.elf || exit 1 23 | ASAN_OPTIONS="detect_leaks=0" ./build/test/modunit_tftp.elf || exit 1 24 | ASAN_OPTIONS="detect_leaks=0" ./build/test/modunit_aodv.elf || exit 1 25 | ASAN_OPTIONS="detect_leaks=0" ./build/test/modunit_dev_ppp.elf || exit 1 26 | ASAN_OPTIONS="detect_leaks=0" ./build/test/modunit_mld.elf || exit 1 27 | ASAN_OPTIONS="detect_leaks=0" ./build/test/modunit_igmp.elf || exit 1 28 | ASAN_OPTIONS="detect_leaks=0" ./build/test/modunit_hotplug_detection.elf || exit 1 29 | ASAN_OPTIONS="detect_leaks=0" ./build/test/modunit_strings.elf || exit 1 30 | 31 | MAXMEM=`cat /tmp/pico-mem-report-* | sort -r -n |head -1` 32 | echo 33 | echo 34 | echo 35 | echo "MAX memory used: $MAXMEM" 36 | rm -f /tmp/pico-mem-report-* 37 | 38 | echo "SUCCESS!" && exit 0 39 | -------------------------------------------------------------------------------- /docs/user_manual/layout.tex: -------------------------------------------------------------------------------- 1 | %Thesistemplate LaTeX De Nayer 2008-2009 2 | %Stefan Bouwens, Dave Geeradyn & Toon Goedem\'e 3 | 4 | %PACKAGES 5 | %\usepackage{times} 6 | %\usepackage[dvips]{graphicx} 7 | \usepackage{url} 8 | \usepackage[english,dutch]{babel} 9 | \usepackage[T1]{fontenc} 10 | \usepackage[all]{xy} 11 | \usepackage{amssymb} 12 | %\usepackage[breaklinks=true, bookmarksopen=true]{hyperref} 13 | \usepackage[small,bf,hang]{caption} 14 | \renewcommand{\captionfont}{\small\itshape} 15 | \usepackage{natbib} 16 | \bibpunct{(}{)}{;}{a}{,}{,} 17 | 18 | \usepackage{listings} 19 | \lstloadlanguages{[visual]c++} 20 | \lstset{ basicstyle=\small, 21 | basicstyle=\ttfamily, 22 | numbers=left, numberstyle=\tiny, stepnumber=1, numbersep=5pt, 23 | tabsize=3, 24 | keywordstyle=\color{black}\bfseries, 25 | commentstyle=\color{gray}\itshape, 26 | frame=single, 27 | breaklines=true 28 | } 29 | 30 | 31 | %LAYOUT 32 | %\bibliographystyle{agsm} 33 | 34 | \setcounter{secnumdepth}{3} 35 | \setcounter{tocdepth}{3} 36 | 37 | \setlength{\textheight}{237mm} 38 | \setlength{\textwidth}{160mm} 39 | %\setlength{\columnsep}{0.3125in} 40 | \setlength{\topmargin}{-0.54cm} 41 | \setlength{\headheight}{15pt} 42 | %\setlength{\headsep}{0in} 43 | %\setlength{\parindent}{1pc} 44 | \setlength{\oddsidemargin}{0.46cm} % Centers text. 45 | \setlength{\evensidemargin}{-.54cm} 46 | % 47 | %Linkermarge 30 mm, rechtermarge 20 mm, bovenmarge 20 mm, ondermarge 20 mm. 48 | %2,54 49 | 50 | \usepackage{fancyhdr} 51 | \pagestyle{fancy} 52 | % with this we ensure that the chapter and section 53 | % headings are in lowercase. 54 | \renewcommand{\chaptermark}[1]{% 55 | \markboth{#1}{}} 56 | \renewcommand{\sectionmark}[1]{% 57 | \markright{\thesection\ #1}} 58 | \fancyhf{} % delete current header and footer 59 | \fancyhead[LE,RO]{\bfseries\thepage} 60 | \fancyhead[LO]{\bfseries\rightmark} 61 | \fancyhead[RE]{\bfseries\leftmark} 62 | \renewcommand{\headrulewidth}{0.5pt} 63 | \renewcommand{\footrulewidth}{0pt} 64 | \addtolength{\headheight}{0.5pt} % space for the rule 65 | \fancypagestyle{plain}{% 66 | \fancyhead{} % get rid of headers on plain pages 67 | \renewcommand{\headrulewidth}{0pt} % and the line 68 | } 69 | 70 | \parskip 6pt % sets spacing between paragraphs 71 | \parindent 0pt % sets leading space for paragraphs -------------------------------------------------------------------------------- /rules/6lowpan.mk: -------------------------------------------------------------------------------- 1 | OPTIONS+=-DPICO_SUPPORT_6LOWPAN -DPICO_SUPPORT_IPV6 2 | 3 | ################################################################################ 4 | # DEFAULTS 5 | ################################################################################ 6 | 7 | # Enable the 6LoWPAN IPHC compression scheme by default 8 | 6LOWPAN_IPHC?=1 9 | 10 | # Disable MAC framing for mac-enabled radios, disabled by default 11 | 6LOWPAN_NOMAC?=0 12 | 13 | # Enable IEEE802.15.4 device support by default 14 | IEEE802154?=1 15 | 16 | # Enable radiotest packet dump 17 | RADIOTEST_PCAP?=0 18 | 19 | ################################################################################ 20 | # 6LOWPAN OPTIONS 21 | ################################################################################ 22 | 23 | ifeq ($(6LOWPAN_IPHC), 1) 24 | EXTRA_CFLAGS+=-DPICO_6LOWPAN_IPHC_ENABLED 25 | endif 26 | 27 | ifeq ($(6LOWPAN_NOMAC), 1) 28 | EXTRA_CFLAGS+=-DPICO_6LOWPAN_NOMAC 29 | endif 30 | 31 | ################################################################################ 32 | # 6LOWPAN LINK LAYER OPTIONS 33 | ################################################################################ 34 | 35 | # IEEE802.15.4 with or without mac layer 36 | ifeq ($(IEEE802154), 1) 37 | 6LOWPAN_OPTIONS+=-DPICO_SUPPORT_802154 38 | POSIX_OBJ+=modules/pico_dev_radiotest.o \ 39 | modules/pico_dev_radio_mgr.o 40 | endif 41 | 42 | OPTIONS+=$(6LOWPAN_OPTIONS) 43 | 44 | # Append module objects 45 | MOD_OBJ+=$(LIBBASE)modules/pico_6lowpan_ll.o 46 | MOD_OBJ+=$(LIBBASE)modules/pico_6lowpan.o 47 | MOD_OBJ+=$(LIBBASE)modules/pico_802154.o 48 | 49 | # Count the amount of supported 6LoWPAN Link Layer protocols based on the amount of words in 50 | # $6LOWPAN_OPTIONS. This allows us to define a static array that can be initialized with the 6LoWPAN 51 | # link layer protocol definitions for the supported link layer protocols. This happens upon 52 | # initialization of the 6LoWPAN_LL-layer. 53 | EXTRA_CFLAGS+=-DPICO_6LOWPAN_LLS=$(words $(6LOWPAN_OPTIONS)) 54 | 55 | ################################################################################ 56 | # RADIOTEST 57 | ################################################################################ 58 | 59 | ifeq ($(RADIOTEST_PCAP), 1) 60 | EXTRA_CFLAGS+=-DRADIO_PCAP 61 | TEST_LDFLAGS+=-lpcap 62 | endif 63 | -------------------------------------------------------------------------------- /test/examples/mdns.c: -------------------------------------------------------------------------------- 1 | #include "utils.h" 2 | #include "pico_dns_common.h" 3 | #include "pico_mdns.h" 4 | #include "pico_ipv4.h" 5 | #include "pico_addressing.h" 6 | 7 | /*** START MDNS ***/ 8 | 9 | #ifdef PICO_SUPPORT_MDNS 10 | 11 | #define SECONDS 10 12 | 13 | static int fully_initialized = 0; 14 | 15 | void mdns_init_callback( pico_mdns_rtree *rtree, 16 | char *str, 17 | void *arg ) 18 | { 19 | printf("\nInitialised with hostname: %s\n\n", str); 20 | 21 | fully_initialized = 1; 22 | } 23 | 24 | void app_mdns(char *arg, struct pico_ip4 address) 25 | { 26 | char *hostname, *peername; 27 | char *nxt = arg; 28 | uint64_t starttime = 0; 29 | int once = 0; 30 | 31 | if (!nxt) 32 | exit(255); 33 | 34 | nxt = cpy_arg(&hostname, nxt); 35 | if(!hostname) { 36 | exit(255); 37 | } 38 | 39 | if(!nxt) { 40 | printf("Not enough args supplied!\n"); 41 | exit(255); 42 | } 43 | 44 | nxt = cpy_arg(&peername, nxt); 45 | if(!peername) { 46 | exit(255); 47 | } 48 | 49 | printf("\nStarting mDNS module...\n"); 50 | if (pico_mdns_init(hostname, address, &mdns_init_callback, NULL)) { 51 | printf("Initialisation returned with Error!\n"); 52 | exit(255); 53 | } 54 | 55 | printf("\nTry reinitialising mDNS\n"); 56 | if (pico_mdns_init(hostname, address, &mdns_init_callback, NULL)) { 57 | printf("Initialisation returned with Error!\n"); 58 | exit(255); 59 | } 60 | 61 | printf("DONE - Re-initialising mDNS module.\n"); 62 | 63 | starttime = PICO_TIME_MS(); 64 | printf("Starting time: %d\n", starttime); 65 | 66 | while(1) { 67 | pico_stack_tick(); 68 | usleep(2000); 69 | 70 | if (((PICO_TIME_MS() - starttime) > SECONDS * 1000) && fully_initialized && !once) { 71 | printf("\nTry reinitialising mDNS (a second time)\n"); 72 | if (pico_mdns_init(hostname, address, &mdns_init_callback, NULL)) { 73 | printf("Initialisation returned with Error!\n"); 74 | exit(255); 75 | } 76 | once = 1; 77 | printf("DONE - Re-initialising mDNS module. (a second time)\n"); 78 | } 79 | 80 | } 81 | } 82 | #endif 83 | /*** END MDNS ***/ 84 | -------------------------------------------------------------------------------- /modcheck.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | import os,sys 3 | import subprocess 4 | 5 | 6 | print "Scroll down for summary" 7 | print "" 8 | print "" 9 | 10 | f = open('MODTREE') 11 | mods = {} 12 | commands = [] 13 | 14 | def get_deps(mod): 15 | if not mod in mods.keys(): 16 | return [] 17 | deps = mods[mod] 18 | retlist = [mod] 19 | for i in deps.split(' '): 20 | retlist.append(i) 21 | for j in get_deps(i): 22 | retlist.append(j) 23 | return retlist 24 | 25 | 26 | while(True): 27 | r = f.readline() 28 | if r == '': 29 | break 30 | if r != '\n': 31 | strings = r.split(':') 32 | mod = strings[0] 33 | deps = strings[1].rstrip('\n') 34 | mods[mod] = deps.strip(' ') 35 | 36 | for k,v in mods.iteritems(): 37 | command = 'make dummy ' 38 | deps = get_deps(k) 39 | for i in mods.keys(): 40 | if i in deps: 41 | command += i + "=1 " 42 | else: 43 | command += i + "=0 " 44 | commands.append(command) 45 | 46 | endResult = [] 47 | failed = 0 48 | 49 | for i in commands: 50 | print 'Checking config:\n\t%s' % i 51 | 52 | subprocess.call(['make','clean']) 53 | sys.stdout.flush() 54 | sys.stderr.flush() 55 | 56 | args = i.split(' ') 57 | 58 | # Remove the last item (which is a blank) 59 | ret = subprocess.call(args[:-1]) 60 | sys.stdout.flush() 61 | sys.stderr.flush() 62 | 63 | if ret == 0: 64 | print "**********************************************************" 65 | print "******************* CONFIG PASSED! *******************" 66 | endResult.append({"test": i, "result": "PASS"}) 67 | else: 68 | failed += 1 69 | print "**********************************************************" 70 | print "******************* CONFIG FAILED! *******************" 71 | endResult.append({"test": i, "result": "FAIL"}) 72 | print "**********************************************************" 73 | 74 | print "" 75 | print "***************************************************************************" 76 | print " Executive Summary" 77 | print "***************************************************************************" 78 | print "" 79 | 80 | for r in endResult: 81 | print "Test:", r["test"] 82 | print "Status:", r["result"] 83 | print "" 84 | 85 | print "***********************" 86 | print "%d out of %d Failed" % (failed, len(endResult)) 87 | print "***********************" 88 | 89 | if failed: 90 | sys.exit(1) 91 | else: 92 | sys.exit(0) 93 | -------------------------------------------------------------------------------- /modules/pico_strings.c: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | PicoTCP. Copyright (c) 2015-2017 Altran ISY BeNeLux. Some rights reserved. 3 | See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage. 4 | 5 | 6 | 7 | Author: Michele Di Pede 8 | *********************************************************************/ 9 | 10 | #include 11 | #include 12 | #include "pico_strings.h" 13 | 14 | char *get_string_terminator_position(char *const block, size_t len) 15 | { 16 | size_t length = pico_strnlen(block, len); 17 | 18 | return (len != length) ? (block + length) : 0; 19 | } 20 | 21 | int pico_strncasecmp(const char *const str1, const char *const str2, size_t n) 22 | { 23 | int ch1; 24 | int ch2; 25 | size_t i; 26 | 27 | for (i = 0; i < n; ++i) { 28 | ch1 = toupper(*(str1 + i)); 29 | ch2 = toupper(*(str2 + i)); 30 | if (ch1 < ch2) 31 | return -1; 32 | 33 | if (ch1 > ch2) 34 | return 1; 35 | 36 | if ((!ch1) && (!ch2)) 37 | return 0; 38 | } 39 | return 0; 40 | } 41 | 42 | size_t pico_strnlen(const char *str, size_t n) 43 | { 44 | size_t len = 0; 45 | 46 | if (!str) 47 | return 0; 48 | 49 | for (; len < n && *(str + len); ++len) 50 | ; /* TICS require this empty statement here */ 51 | 52 | return len; 53 | } 54 | 55 | static inline int num2string_validate(int32_t num, char *buf, int len) 56 | { 57 | if (num < 0) 58 | return -1; 59 | 60 | if (!buf) 61 | return -2; 62 | 63 | if (len < 2) 64 | return -3; 65 | 66 | return 0; 67 | } 68 | 69 | static inline int revert_and_shift(char *buf, int len, int pos) 70 | { 71 | int i; 72 | 73 | len -= pos; 74 | for (i = 0; i < len; ++i) 75 | buf[i] = buf[i + pos]; 76 | return len; 77 | } 78 | 79 | int num2string(int32_t num, char *buf, int len) 80 | { 81 | ldiv_t res; 82 | int pos = 0; 83 | 84 | if (num2string_validate(num, buf, len)) 85 | return -1; 86 | 87 | pos = len; 88 | buf[--pos] = '\0'; 89 | 90 | res.quot = (long)num; 91 | 92 | do { 93 | if (!pos) 94 | return -3; 95 | 96 | res = ldiv(res.quot, 10); 97 | buf[--pos] = (char)((res.rem + '0') & 0xFF); 98 | } while (res.quot); 99 | 100 | return revert_and_shift(buf, len, pos); 101 | } 102 | -------------------------------------------------------------------------------- /test/unit/modunit_queue.c: -------------------------------------------------------------------------------- 1 | #include "pico_frame.h" 2 | #include "pico_queue.h" 3 | #include "stack/pico_frame.c" 4 | #include "pico_stack.h" 5 | #include "check.h" 6 | 7 | 8 | Suite *pico_suite(void); 9 | 10 | struct pico_queue q1 = { 11 | 0 12 | }, q2 = { 13 | 0 14 | }; 15 | 16 | START_TEST(tc_q) 17 | { 18 | struct pico_frame *f0 = pico_frame_alloc(100); 19 | struct pico_frame *f1 = pico_frame_alloc(100); 20 | struct pico_frame *f2 = pico_frame_alloc(100); 21 | struct pico_frame *f3 = pico_frame_alloc(100); 22 | struct pico_frame *f4 = pico_frame_alloc(100); 23 | 24 | pico_queue_protect(&q1); 25 | 26 | q1.max_frames = 4; 27 | q2.max_size = 4 * 100; 28 | 29 | fail_if (pico_enqueue(&q1, pico_frame_copy(f0)) < 0); 30 | fail_if (pico_enqueue(&q1, pico_frame_copy(f1)) < 0); 31 | fail_if (pico_enqueue(&q1, pico_frame_copy(f2)) < 0); 32 | fail_if (pico_enqueue(&q1, pico_frame_copy(f3)) < 0); 33 | fail_if (pico_enqueue(&q1, pico_frame_copy(f4)) >= 0); 34 | 35 | fail_if (pico_enqueue(&q2, pico_frame_copy(f0)) < 0); 36 | fail_if (pico_enqueue(&q2, pico_frame_copy(f1)) < 0); 37 | fail_if (pico_enqueue(&q2, pico_frame_copy(f2)) < 0); 38 | fail_if (pico_enqueue(&q2, pico_frame_copy(f3)) < 0); 39 | fail_if (pico_enqueue(&q2, pico_frame_copy(f4)) >= 0); 40 | 41 | fail_if((pico_dequeue(&q1))->buffer != f0->buffer); 42 | fail_if((pico_dequeue(&q1))->buffer != f1->buffer); 43 | fail_if((pico_dequeue(&q1))->buffer != f2->buffer); 44 | fail_if((pico_dequeue(&q1))->buffer != f3->buffer); 45 | fail_if(pico_queue_peek(&q1) != NULL); 46 | fail_if(pico_dequeue(&q1) != NULL); 47 | fail_if(q1.size != 0); 48 | fail_if(q1.frames != 0); 49 | 50 | 51 | pico_queue_empty(&q2); 52 | fail_if(q2.size != 0); 53 | fail_if(q2.frames != 0); 54 | fail_if(pico_queue_peek(&q2) != NULL); 55 | fail_if(pico_dequeue(&q2) != NULL); 56 | 57 | pico_queue_deinit(&q1); 58 | pico_queue_deinit(&q2); 59 | 60 | 61 | } 62 | END_TEST 63 | 64 | 65 | Suite *pico_suite(void) 66 | { 67 | Suite *s = suite_create("Packet Queues"); 68 | 69 | TCase *TCase_q = tcase_create("Unit test for pico_queue.c"); 70 | tcase_add_test(TCase_q, tc_q); 71 | suite_add_tcase(s, TCase_q); 72 | return s; 73 | } 74 | 75 | int main(void) 76 | { 77 | int fails; 78 | Suite *s = pico_suite(); 79 | SRunner *sr = srunner_create(s); 80 | srunner_run_all(sr, CK_NORMAL); 81 | fails = srunner_ntests_failed(sr); 82 | srunner_free(sr); 83 | return fails; 84 | } 85 | -------------------------------------------------------------------------------- /modules/pico_posix.c: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved. 3 | See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage. 4 | 5 | Authors: Andrei Carp, Maarten Vandersteegen 6 | *********************************************************************/ 7 | 8 | #ifdef PICO_SUPPORT_THREADING 9 | 10 | #include 11 | #include 12 | #include "pico_config.h" 13 | 14 | /* POSIX mutex implementation */ 15 | void *pico_mutex_init(void) 16 | { 17 | pthread_mutex_t *m; 18 | m = (pthread_mutex_t *)PICO_ZALLOC(sizeof(pthread_mutex_t)); 19 | pthread_mutex_init(m, NULL); 20 | return m; 21 | } 22 | 23 | void pico_mutex_destroy(void *mux) 24 | { 25 | PICO_FREE(mux); 26 | mux = NULL; 27 | } 28 | 29 | void pico_mutex_lock(void *mux) 30 | { 31 | if (mux == NULL) return; 32 | 33 | pthread_mutex_t *m = (pthread_mutex_t *)mux; 34 | pthread_mutex_lock(m); 35 | } 36 | 37 | void pico_mutex_unlock(void *mux) 38 | { 39 | if (mux == NULL) return; 40 | 41 | pthread_mutex_t *m = (pthread_mutex_t *)mux; 42 | pthread_mutex_unlock(m); 43 | } 44 | 45 | /* POSIX semaphore implementation */ 46 | void *pico_sem_init(void) 47 | { 48 | sem_t *s; 49 | s = (sem_t *)PICO_ZALLOC(sizeof(sem_t)); 50 | sem_init(s, 0, 0); 51 | return s; 52 | } 53 | 54 | void pico_sem_destroy(void *sem) 55 | { 56 | PICO_FREE(sem); 57 | sem = NULL; 58 | } 59 | 60 | void pico_sem_post(void *sem) 61 | { 62 | if (sem == NULL) return; 63 | 64 | sem_t *s = (sem_t *)sem; 65 | sem_post(s); 66 | } 67 | 68 | int pico_sem_wait(void *sem, int timeout) 69 | { 70 | struct timespec t; 71 | if (sem == NULL) return 0; 72 | 73 | sem_t *s = (sem_t *)sem; 74 | 75 | if (timeout < 0) { 76 | sem_wait(s); 77 | } else { 78 | clock_gettime(CLOCK_REALTIME, &t); 79 | t.tv_sec += timeout / 1000; 80 | t.tv_nsec += (timeout % 1000) * 1000000; 81 | if (sem_timedwait(s, &t) == -1) 82 | return -1; 83 | } 84 | 85 | return 0; 86 | } 87 | 88 | /* POSIX thread implementation */ 89 | void *pico_thread_create(void *(*routine)(void *), void *arg) 90 | { 91 | pthread_t *thread; 92 | thread = (pthread_t *)PICO_ZALLOC(sizeof(pthread_t)); 93 | 94 | if (pthread_create(thread, NULL, routine, arg) == -1) 95 | return NULL; 96 | 97 | return thread; 98 | } 99 | #endif /* PICO_SUPPORT_THREADING */ 100 | -------------------------------------------------------------------------------- /docs/user_manual/chap_api_dhcp_d.tex: -------------------------------------------------------------------------------- 1 | \section{DHCP server} 2 | 3 | % Short description/overview of module functions 4 | 5 | 6 | \subsection{pico\_dhcp\_server\_initiate} 7 | 8 | \subsubsection*{Description} 9 | This function starts a simple DHCP server. 10 | 11 | \subsubsection*{Function prototype} 12 | \texttt{int pico\_dhcp\_server\_initiate(struct pico\_dhcpd\_settings *settings);} 13 | 14 | \subsubsection*{Parameters} 15 | \begin{itemize}[noitemsep] 16 | \item \texttt{settings} - a pointer to a struct \texttt{pico\_dhcpd\_settings}, in which the following members matter to the user : 17 | \begin{itemize}[noitemsep] 18 | \item \texttt{struct pico\_ip4 my\_ip} - the IP address of the device performing DHCP. Only IPs of this network will be served. 19 | \item \texttt{uint32\_t pool\_start} - the lowest host number that may be assigned, defaults to 100 if not provided. 20 | \item \texttt{uint32\_t pool\_end} - the highest host number that may be assigned, defaults to 254 if not provided. 21 | \item \texttt{uint32\_t lease\_time} - the advertised lease time in seconds, defaults to 120 if not provided. 22 | \end{itemize} 23 | \end{itemize} 24 | 25 | \subsubsection*{Return value} 26 | On successful startup of the dhcp server, 0 is returned. 27 | On error, -1 is returned, and \texttt{pico$\_$err} is set appropriately. 28 | 29 | \subsubsection*{Errors} 30 | \begin{itemize}[noitemsep] 31 | %everything from : 32 | %pico_socket_open 33 | \item PICO$\_$ERR$\_$EPROTONOSUPPORT - protocol not supported 34 | \item PICO$\_$ERR$\_$ENETUNREACH - network unreachable 35 | %pico_socket_bind 36 | \item PICO$\_$ERR$\_$EINVAL - invalid argument 37 | \item PICO$\_$ERR$\_$ENXIO - no such device or address 38 | \end{itemize} 39 | 40 | \subsection{pico\_dhcp\_server\_destroy} 41 | 42 | \subsubsection*{Description} 43 | This function stops a previously started DHCP server on the given device. 44 | 45 | \subsubsection*{Function prototype} 46 | \texttt{int pico\_dhcp\_server\_destroy(struct pico\_device *dev);} 47 | 48 | \subsubsection*{Parameters} 49 | \begin{itemize}[noitemsep] 50 | \item \texttt{dev} - a pointer to a struct \texttt{pico\_device}, to identify a previously started DHCP server that must be terminated. 51 | \end{itemize} 52 | 53 | \subsubsection*{Return value} 54 | On success, 0 is returned. 55 | On error, -1 is returned, and \texttt{pico$\_$err} is set appropriately. 56 | 57 | \subsubsection*{Errors} 58 | \begin{itemize}[noitemsep] 59 | \item PICO$\_$ERR$\_$ENOENT - there was no DHCP server running on the given device. 60 | \end{itemize} 61 | 62 | \subsubsection*{Example} 63 | \begin{verbatim} 64 | struct pico_dhcpd_settings s = { }; 65 | 66 | s.my_ip.addr = long_be(0x0a280001); /* 10.40.0.1 */ 67 | 68 | pico_dhcp_server_initiate(&s); 69 | \end{verbatim} 70 | 71 | 72 | -------------------------------------------------------------------------------- /test/unit/modunit_pico_dev_loop.c: -------------------------------------------------------------------------------- 1 | #include "modules/pico_dev_loop.c" 2 | #include "check.h" 3 | static int called = 0; 4 | static int fail = 0; 5 | 6 | Suite *pico_suite(void); 7 | 8 | int pico_device_init(struct pico_device __attribute__((unused)) *dev, const char __attribute__((unused)) *name, const uint8_t __attribute__((unused)) *mac) 9 | { 10 | if (fail) 11 | return -1; 12 | 13 | return 0; 14 | } 15 | 16 | void pico_device_destroy(struct pico_device *dev) 17 | { 18 | dev = dev; 19 | } 20 | 21 | int32_t pico_stack_recv(struct pico_device __attribute__((unused)) *dev, uint8_t __attribute__((unused)) *buffer, uint32_t __attribute__((unused)) len) 22 | { 23 | called = 1; 24 | return 1; 25 | } 26 | 27 | START_TEST(tc_pico_loop_send) 28 | { 29 | uint8_t buf[LOOP_MTU + 1] = {}; 30 | fail_if(pico_loop_send(NULL, buf, LOOP_MTU + 1) != 0); 31 | 32 | /* First send: OK */ 33 | fail_if(pico_loop_send(NULL, buf, LOOP_MTU) != LOOP_MTU); 34 | 35 | /* Second: buffer busy */ 36 | fail_if(pico_loop_send(NULL, buf, LOOP_MTU) != 0); 37 | 38 | } 39 | END_TEST 40 | 41 | START_TEST(tc_pico_loop_poll) 42 | { 43 | uint8_t buf[LOOP_MTU + 1] = {}; 44 | fail_if(pico_loop_poll(NULL, 0) != 0); 45 | called = 0; 46 | /* First send: OK */ 47 | fail_if(pico_loop_send(NULL, buf, LOOP_MTU) != LOOP_MTU); 48 | fail_if(pico_loop_poll(NULL, 1) != 0); 49 | fail_if(called == 0); 50 | } 51 | END_TEST 52 | 53 | START_TEST(tc_pico_loop_create) 54 | { 55 | 56 | #ifdef PICO_FAULTY 57 | printf("Testing with faulty memory in pico_loop_create (1)\n"); 58 | pico_set_mm_failure(1); 59 | fail_if(pico_loop_create() != NULL); 60 | #endif 61 | fail = 1; 62 | fail_if(pico_loop_create() != NULL); 63 | fail = 0; 64 | fail_if(pico_loop_create() == NULL); 65 | 66 | } 67 | END_TEST 68 | 69 | 70 | Suite *pico_suite(void) 71 | { 72 | Suite *s = suite_create("PicoTCP"); 73 | 74 | TCase *TCase_pico_loop_send = tcase_create("Unit test for pico_loop_send"); 75 | TCase *TCase_pico_loop_poll = tcase_create("Unit test for pico_loop_poll"); 76 | TCase *TCase_pico_loop_create = tcase_create("Unit test for pico_loop_create"); 77 | 78 | 79 | tcase_add_test(TCase_pico_loop_send, tc_pico_loop_send); 80 | suite_add_tcase(s, TCase_pico_loop_send); 81 | tcase_add_test(TCase_pico_loop_poll, tc_pico_loop_poll); 82 | suite_add_tcase(s, TCase_pico_loop_poll); 83 | tcase_add_test(TCase_pico_loop_create, tc_pico_loop_create); 84 | suite_add_tcase(s, TCase_pico_loop_create); 85 | return s; 86 | } 87 | 88 | int main(void) 89 | { 90 | int fails; 91 | Suite *s = pico_suite(); 92 | SRunner *sr = srunner_create(s); 93 | srunner_run_all(sr, CK_NORMAL); 94 | fails = srunner_ntests_failed(sr); 95 | srunner_free(sr); 96 | return fails; 97 | } 98 | -------------------------------------------------------------------------------- /include/arch/pico_pic24.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved. 3 | See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage. 4 | *********************************************************************/ 5 | #ifndef PICO_SUPPORT_PIC24 6 | #define PICO_SUPPORT_PIC24 7 | #define dbg printf 8 | /* #define dbg(...) */ 9 | 10 | /*************************/ 11 | 12 | /*** MACHINE CONFIGURATION ***/ 13 | #include 14 | #include 15 | 16 | /* #include "phalox_development_board.h" */ 17 | 18 | #ifndef __PIC24F__ 19 | #define __PIC24F__ 20 | #endif 21 | 22 | /* 23 | #ifndef __PIC24FJ256GA106__ 24 | #define __PIC24FJ256GA106__ 25 | #endif 26 | */ 27 | 28 | #ifndef PICO_MAX_SOCKET_FRAMES 29 | #define PICO_MAX_SOCKET_FRAMES 16 30 | #endif 31 | 32 | /* Device header file */ 33 | 34 | #if defined(__PIC24E__) 35 | # include 36 | #elif defined(__PIC24F__) 37 | # include 38 | #elif defined(__PIC24H__) 39 | # include 40 | #endif 41 | 42 | 43 | #define TIMBASE_INT_E IEC0bits.T2IE 44 | 45 | #ifdef PICO_SUPPORT_DEBUG_MEMORY 46 | static inline void *pico_zalloc(int len) 47 | { 48 | /* dbg("%s: Alloc object of len %d, caller: %p\n", __FUNCTION__, len, __builtin_return_address(0)); */ 49 | return calloc(len, 1); 50 | } 51 | 52 | static inline void pico_free(void *tgt) 53 | { 54 | /* dbg("%s: Discarded object @%p, caller: %p\n", __FUNCTION__, tgt, __builtin_return_address(0)); */ 55 | free(tgt); 56 | } 57 | #else 58 | # define pico_zalloc(x) calloc(x, 1) 59 | # define pico_free(x) free(x) 60 | #endif 61 | 62 | extern void *pvPortMalloc( size_t xWantedSize ); 63 | extern volatile pico_time __pic24_tick; 64 | 65 | static inline unsigned long PICO_TIME(void) 66 | { 67 | unsigned long tick; 68 | /* Disable timer interrupts */ 69 | TIMBASE_INT_E = 0; 70 | tick = __pic24_tick; 71 | /* Enable timer interrupts */ 72 | TIMBASE_INT_E = 1; 73 | return tick / 1000; 74 | } 75 | 76 | static inline unsigned long PICO_TIME_MS(void) 77 | { 78 | unsigned long tick; 79 | /* Disable timer interrupts */ 80 | TIMBASE_INT_E = 0; 81 | tick = __pic24_tick; 82 | /* Enable timer interrupts */ 83 | TIMBASE_INT_E = 1; 84 | return tick; 85 | } 86 | 87 | static inline void PICO_IDLE(void) 88 | { 89 | unsigned long tick_now; 90 | /* Disable timer interrupts */ 91 | TIMBASE_INT_E = 0; 92 | tick_now = (unsigned long)pico_tick; 93 | /* Enable timer interrupts */ 94 | TIMBASE_INT_E = 1; 95 | /* Doesn't matter that this call isn't interrupt safe, */ 96 | /* we just check for the value to change */ 97 | while(tick_now == __pic24_tick) ; 98 | } 99 | 100 | #endif 101 | -------------------------------------------------------------------------------- /modules/pico_nat.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved. 3 | See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage. 4 | 5 | . 6 | 7 | Authors: Kristof Roelants, Simon Maes, Brecht Van Cauwenberghe 8 | *********************************************************************/ 9 | 10 | #ifndef INCLUDE_PICO_NAT 11 | #define INCLUDE_PICO_NAT 12 | #include "pico_frame.h" 13 | 14 | #define PICO_NAT_PORT_FORWARD_DEL 0 15 | #define PICO_NAT_PORT_FORWARD_ADD 1 16 | 17 | #ifdef PICO_SUPPORT_NAT 18 | void pico_ipv4_nat_print_table(void); 19 | int pico_ipv4_nat_find(uint16_t nat_port, struct pico_ip4 *src_addr, uint16_t src_port, uint8_t proto); 20 | int pico_ipv4_port_forward(struct pico_ip4 nat_addr, uint16_t nat_port, struct pico_ip4 src_addr, uint16_t src_port, uint8_t proto, uint8_t flag); 21 | 22 | int pico_ipv4_nat_inbound(struct pico_frame *f, struct pico_ip4 *link_addr); 23 | int pico_ipv4_nat_outbound(struct pico_frame *f, struct pico_ip4 *link_addr); 24 | int pico_ipv4_nat_enable(struct pico_ipv4_link *link); 25 | int pico_ipv4_nat_disable(void); 26 | int pico_ipv4_nat_is_enabled(struct pico_ip4 *link_addr); 27 | #else 28 | 29 | #define pico_ipv4_nat_print_table() do {} while(0) 30 | static inline int pico_ipv4_nat_inbound(struct pico_frame *f, struct pico_ip4 *link_addr) 31 | { 32 | (void)f; 33 | (void)link_addr; 34 | pico_err = PICO_ERR_EPROTONOSUPPORT; 35 | return -1; 36 | } 37 | 38 | static inline int pico_ipv4_nat_outbound(struct pico_frame *f, struct pico_ip4 *link_addr) 39 | { 40 | (void)f; 41 | (void)link_addr; 42 | pico_err = PICO_ERR_EPROTONOSUPPORT; 43 | return -1; 44 | } 45 | 46 | static inline int pico_ipv4_nat_enable(struct pico_ipv4_link *link) 47 | { 48 | (void)link; 49 | pico_err = PICO_ERR_EPROTONOSUPPORT; 50 | return -1; 51 | } 52 | 53 | static inline int pico_ipv4_nat_disable(void) 54 | { 55 | pico_err = PICO_ERR_EPROTONOSUPPORT; 56 | return -1; 57 | } 58 | 59 | static inline int pico_ipv4_nat_is_enabled(struct pico_ip4 *link_addr) 60 | { 61 | (void)link_addr; 62 | pico_err = PICO_ERR_EPROTONOSUPPORT; 63 | return -1; 64 | } 65 | 66 | static inline int pico_ipv4_nat_find(uint16_t nat_port, struct pico_ip4 *src_addr, uint16_t src_port, uint8_t proto) 67 | { 68 | (void)nat_port; 69 | (void)src_addr; 70 | (void)src_port; 71 | (void)proto; 72 | pico_err = PICO_ERR_EPROTONOSUPPORT; 73 | return -1; 74 | } 75 | 76 | static inline int pico_ipv4_port_forward(struct pico_ip4 nat_addr, uint16_t nat_port, struct pico_ip4 src_addr, uint16_t src_port, uint8_t proto, uint8_t flag) 77 | { 78 | (void)nat_addr; 79 | (void)nat_port; 80 | (void)src_addr; 81 | (void)src_port; 82 | (void)proto; 83 | (void)flag; 84 | pico_err = PICO_ERR_EPROTONOSUPPORT; 85 | return -1; 86 | } 87 | #endif 88 | 89 | #endif /* _INCLUDE_PICO_NAT */ 90 | 91 | -------------------------------------------------------------------------------- /docs/user_manual/user_doc.tex: -------------------------------------------------------------------------------- 1 | % Altran NV 2 | % 3 | % PicoTCP User Documentation main file 4 | % ==================================== 5 | 6 | %\documentclass[11pt, a4paper, openright]{paper} 7 | 8 | 9 | \input{layout1} 10 | 11 | % TEMPS 12 | 13 | %\usepackage{tikz} 14 | %\usepackage[latin1]{inputenc} 15 | %\usepackage{graphicx} 16 | %\usepackage[hang,flushmargin]{footmisc} 17 | %\usepackage{pdfpages} 18 | %\usepackage{tabularx} 19 | %\usepackage{lscape} 20 | %\usepackage{longtable} 21 | %\usepackage{verbatim} 22 | %\usepackage{moreverb} 23 | %\usepackage{listings} 24 | %\usepackage{draftcopy} 25 | %\usepackage{hyperref} 26 | \usepackage{longtable} 27 | 28 | %% to print watermark 29 | % \usepackage{draftwatermark} 30 | % \SetWatermarkText{Altran ISY Confidential} 31 | % \SetWatermarkScale{3} 32 | % \SetWatermarkLightness{0.9} 33 | 34 | % to adjust the space between titles and text 35 | \usepackage[compact]{titlesec} 36 | \titlespacing{\section}{0pt}{*5}{*2} 37 | \titlespacing{\subsection}{0pt}{*4}{*1} 38 | \titlespacing{\subsubsection}{0pt}{*1}{*0} 39 | 40 | % to minimize space between list items 41 | \usepackage{enumitem} 42 | 43 | % To use hyperlinks 44 | \usepackage{hyperref} 45 | % limit toc depth until sections 46 | \setcounter{tocdepth}{1} 47 | 48 | 49 | \begin{document} 50 | 51 | \title{picoTCP User Documentation} 52 | \author{Copyright \copyright 2017 Altran Belgium NV. All right reserved.} 53 | \maketitle 54 | \date{\today} 55 | \maketitle 56 | 57 | \thispagestyle{empty} 58 | 59 | Disclaimer 60 | This document is distributed under the terms of Creative Commons CC BY-ND 3.0. 61 | You are free to share unmodified copies of this document, as long as the copyright 62 | statement is kept. Click \href{http://creativecommons.org/licenses/by-nd/3.0/} {here} to view the full license text. 63 | 64 | 65 | \pagenumbering{arabic} 66 | 67 | \selectlanguage{english} 68 | 69 | \tableofcontents 70 | 71 | %\chapter{Introduction} 72 | %\label{chap:intro} 73 | %\input{chap_intro} 74 | 75 | \chapter{Overview} 76 | \label{chap:overview} 77 | \input{chap_overview} 78 | 79 | 80 | \chapter{API Documentation} 81 | \label{chap:api_doc} 82 | The following sections will describe the API for picoTCP. 83 | \input{chap_api_ipv4} 84 | \input{chap_api_ipv6} 85 | \input{chap_api_sock} 86 | \input{chap_api_dhcp_c} 87 | \input{chap_api_dhcp_d} 88 | \input{chap_api_dns_c} 89 | \input{chap_api_mdns} 90 | \input{chap_api_dns_sd} 91 | \input{chap_api_sntp_c} 92 | \input{chap_api_igmp} 93 | \input{chap_api_mld} 94 | \input{chap_api_ipfilter} 95 | \input{chap_api_slaacv4} 96 | \input{chap_api_tftp} 97 | \input{chap_api_ppp} 98 | \input{chap_api_olsr} 99 | \input{chap_api_aodv} 100 | 101 | 102 | \appendix 103 | 104 | % Do not include license 105 | %\chapter{License} 106 | %\label{chap:license} 107 | %\input{chap_license} 108 | 109 | \chapter{Supported RFCs} 110 | \label{chap:rfcs} 111 | \input{chap_rfcs} 112 | 113 | \end{document} 114 | -------------------------------------------------------------------------------- /test/examples/udp_sendto_test.c: -------------------------------------------------------------------------------- 1 | #include "utils.h" 2 | #include 3 | #include 4 | 5 | /**** START UDP ECHO ****/ 6 | /* 7 | * udpecho expects the following format: udpecho:bind_addr:listen_port[:sendto_port:datasize] 8 | * bind_addr: IP address to bind to 9 | * listen_port: port number on which the udpecho listens 10 | * sendto_port [OPTIONAL]: port number to echo datagrams to (echo to originating IP address) 11 | * datasize [OPTIONAL]: max size of the data red from the socket in one go 12 | * 13 | * REMARK: once an optional parameter is given, all optional parameters need a value! 14 | * 15 | * f.e.: ./build/test/picoapp.elf --vde pic0:/tmp/pic0.ctl:10.40.0.3:255.255.255.0: -a udpecho:10.40.0.3:6667:6667:1400 16 | */ 17 | 18 | void dummy_cb(uint16_t __attribute__((unused)) ev, struct pico_socket __attribute__((unused)) *s) 19 | { 20 | 21 | } 22 | 23 | void app_sendto_test(char *arg) 24 | { 25 | char *nxt = arg; 26 | char *dstaddr = NULL; 27 | char *dstport = NULL; 28 | struct pico_ip4 inaddr_dst = {}; 29 | struct pico_ip6 inaddr_dst6 = {}; 30 | uint16_t dport; 31 | struct pico_socket *sock; 32 | int ret; 33 | 34 | /* start of argument parsing */ 35 | if (nxt) { 36 | nxt = cpy_arg(&dstaddr, nxt); 37 | if (dstaddr) { 38 | if (!IPV6_MODE) 39 | pico_string_to_ipv4(dstaddr, &inaddr_dst.addr); 40 | 41 | #ifdef PICO_SUPPORT_IPV6 42 | else 43 | pico_string_to_ipv6(dstaddr, inaddr_dst6.addr); 44 | #endif 45 | } else { 46 | goto out; 47 | } 48 | } else { 49 | /* missing bind_addr */ 50 | goto out; 51 | } 52 | 53 | if (nxt) { 54 | nxt = cpy_arg(&dstport, nxt); 55 | if (dstport && atoi(dstport)) { 56 | dport = short_be(atoi(dstport)); 57 | } else { 58 | dport = short_be(5555); 59 | } 60 | } else { 61 | /* missing listen_port */ 62 | goto out; 63 | } 64 | 65 | if (!IPV6_MODE) 66 | sock = pico_socket_open(PICO_PROTO_IPV4, PICO_PROTO_UDP, &dummy_cb); 67 | else 68 | sock = pico_socket_open(PICO_PROTO_IPV6, PICO_PROTO_UDP, &dummy_cb); 69 | 70 | ret = pico_socket_sendto(sock, "Testing", 7u, ((IPV6_MODE) ? (void *)(&inaddr_dst6) : (void *)(&inaddr_dst)), dport); 71 | if (ret < 0) 72 | printf("Failure in first pico_socket_send\n"); 73 | 74 | ret = pico_socket_sendto(sock, "Testing", 7u, ((IPV6_MODE) ? (void *)(&inaddr_dst6) : (void *)(&inaddr_dst)), dport); 75 | if (ret < 0) 76 | printf("Failure in second pico_socket_send\n"); 77 | 78 | ret = pico_socket_close(sock); 79 | if (ret) 80 | printf("Failure in pico_socket_close\n"); 81 | 82 | printf("\n%s: UDP sendto test launched. Sending packets to ip %s port %u\n\n", __FUNCTION__, dstaddr, short_be(dport)); 83 | return; 84 | 85 | out: 86 | fprintf(stderr, "udp_sendto_test expects the following format: udp_sendto_test:dest_addr:[dest_por]t\n"); 87 | exit(255); 88 | } 89 | -------------------------------------------------------------------------------- /test/unit/unit_rbtree.c: -------------------------------------------------------------------------------- 1 | /* RB tree unit test */ 2 | typedef struct 3 | { 4 | int value; 5 | }elem; 6 | 7 | int compare(void *a, void *b); 8 | 9 | int compare(void *a, void *b) 10 | { 11 | return ((elem *)a)->value - ((elem *)b)->value; 12 | } 13 | 14 | static PICO_TREE_DECLARE(test_tree, compare); 15 | static PICO_TREE_DECLARE(test_tree2, compare); 16 | #define RBTEST_SIZE 20000 17 | 18 | START_TEST (test_rbtree2) 19 | { 20 | struct pico_tree_node *s; 21 | elem *e; 22 | int i, last; 23 | struct timeval start, end; 24 | gettimeofday(&start, 0); 25 | 26 | srand48(RBTEST_SIZE); /* use test-size as salt */ 27 | for (i = 0; i < (RBTEST_SIZE >> 1); i++) 28 | { 29 | e = malloc(sizeof(elem)); 30 | e->value = (int)lrand48() % RBTEST_SIZE; 31 | if (pico_tree_findKey(&test_tree2, e)) { 32 | free(e); 33 | } else { 34 | pico_tree_insert(&test_tree2, e); 35 | } 36 | } 37 | gettimeofday(&end, 0); 38 | printf("Rbtree test 2 inserted %d entries in %d milliseconds\n", RBTEST_SIZE, 39 | (int)((end.tv_sec - start.tv_sec) * 1000 + (end.tv_usec - start.tv_usec) / 1000)); 40 | last = 0; 41 | pico_tree_foreach(s, &test_tree2){ 42 | fail_if (last > ((elem *)(s->keyValue))->value, "error"); 43 | last = ((elem *)(s->keyValue))->value; 44 | } 45 | 46 | gettimeofday(&end, 0); 47 | printf("Rbtree test 2 duration with %d entries: %d milliseconds\n", RBTEST_SIZE, 48 | (int)((end.tv_sec - start.tv_sec) * 1000 + (end.tv_usec - start.tv_usec) / 1000)); 49 | printf("Test finished.\n"); 50 | } 51 | END_TEST 52 | 53 | START_TEST (test_rbtree) 54 | { 55 | struct pico_tree_node *s, *tmp; 56 | elem t, *e; 57 | int i; 58 | struct timeval start, end; 59 | printf("Started test...\n"); 60 | gettimeofday(&start, 0); 61 | 62 | for (i = 0; i < (RBTEST_SIZE >> 1); i++) { 63 | e = malloc(sizeof(elem)); 64 | e->value = i; 65 | pico_tree_insert(&test_tree, e); 66 | /* RB_INSERT(rbtree, &RBTREE, e); */ 67 | e = malloc(sizeof(elem)); 68 | e->value = (RBTEST_SIZE - 1) - i; 69 | pico_tree_insert(&test_tree, e); 70 | } 71 | i = 0; 72 | pico_tree_foreach(s, &test_tree){ 73 | fail_if (i++ != ((elem *)(s->keyValue))->value, "error"); 74 | } 75 | t.value = RBTEST_SIZE >> 2; 76 | 77 | e = pico_tree_findKey(&test_tree, &t); 78 | fail_if(!e, "Search failed..."); 79 | fail_if(e->value != t.value, "Wrong element returned..."); 80 | 81 | pico_tree_foreach_reverse_safe(s, &test_tree, tmp){ 82 | fail_if(!s, "Reverse safe returned null"); 83 | e = (elem *)pico_tree_delete(&test_tree, s->keyValue); 84 | free(e); 85 | } 86 | 87 | fail_if(!pico_tree_empty(&test_tree), "Not empty"); 88 | gettimeofday(&end, 0); 89 | printf("Rbtree test duration with %d entries: %d milliseconds\n", RBTEST_SIZE, 90 | (int)((end.tv_sec - start.tv_sec) * 1000 + (end.tv_usec - start.tv_usec) / 1000)); 91 | printf("Test finished...\n"); 92 | } 93 | END_TEST 94 | -------------------------------------------------------------------------------- /include/arch/pico_generic_gcc.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved. 3 | See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage. 4 | 5 | *********************************************************************/ 6 | #ifndef _INCLUDE_PICO_GCC 7 | #define _INCLUDE_PICO_GCC 8 | 9 | #include 10 | #include 11 | #include 12 | #include "pico_constants.h" 13 | 14 | /* #define TIME_PRESCALE */ 15 | 16 | /* monotonically increasing tick, 17 | * typically incremented every millisecond in a systick interrupt */ 18 | extern volatile unsigned int pico_ms_tick; 19 | 20 | #define dbg(...) 21 | 22 | #ifdef PICO_SUPPORT_PTHREAD 23 | #define PICO_SUPPORT_MUTEX 24 | #endif 25 | 26 | #ifdef PICO_SUPPORT_RTOS 27 | #define PICO_SUPPORT_MUTEX 28 | 29 | extern void *pico_mutex_init(void); 30 | extern void pico_mutex_lock(void*); 31 | extern void pico_mutex_unlock(void*); 32 | extern void *pvPortMalloc( size_t xSize ); 33 | extern void vPortFree( void *pv ); 34 | 35 | #define pico_free(x) vPortFree(x) 36 | #define free(x) vPortFree(x) 37 | 38 | static inline void *pico_zalloc(size_t size) 39 | { 40 | void *ptr = pvPortMalloc(size); 41 | 42 | if(ptr) 43 | memset(ptr, 0u, size); 44 | 45 | return ptr; 46 | } 47 | 48 | /* time prescaler */ 49 | #ifdef TIME_PRESCALE 50 | extern int32_t prescale_time; 51 | #endif 52 | 53 | static inline pico_time PICO_TIME_MS() 54 | { 55 | #ifdef TIME_PRESCALE 56 | return pico_ms_tick << prescale_time; 57 | #else 58 | return pico_ms_tick; 59 | #endif 60 | } 61 | 62 | static inline pico_time PICO_TIME() 63 | { 64 | #ifdef TIME_PRESCALE 65 | return (pico_ms_tick / 1000) << prescale_time; 66 | #else 67 | return (pico_ms_tick / 1000); 68 | #endif 69 | } 70 | 71 | static inline void PICO_IDLE(void) 72 | { 73 | pico_time now = PICO_TIME_MS(); 74 | while(now == PICO_TIME_MS()) ; 75 | } 76 | 77 | #else /* NO RTOS SUPPORT */ 78 | 79 | #ifdef MEM_MEAS 80 | /* These functions should be implemented elsewhere */ 81 | extern void *memmeas_zalloc(size_t size); 82 | extern void memmeas_free(void *); 83 | #define pico_free(x) memmeas_free(x) 84 | #define pico_zalloc(x) memmeas_zalloc(x) 85 | #else 86 | /* Use plain C-lib malloc and free */ 87 | #define pico_free(x) free(x) 88 | static inline void *pico_zalloc(size_t size) 89 | { 90 | void *ptr = malloc(size); 91 | if(ptr) 92 | memset(ptr, 0u, size); 93 | 94 | return ptr; 95 | } 96 | #endif 97 | 98 | static inline pico_time PICO_TIME_MS(void) 99 | { 100 | return (pico_time)pico_ms_tick; 101 | } 102 | 103 | static inline pico_time PICO_TIME(void) 104 | { 105 | return (pico_time)(PICO_TIME_MS() / 1000); 106 | } 107 | 108 | static inline void PICO_IDLE(void) 109 | { 110 | unsigned int now = pico_ms_tick; 111 | while(now == pico_ms_tick) ; 112 | } 113 | 114 | #endif /* IFNDEF RTOS */ 115 | 116 | #endif /* PICO_GCC */ 117 | 118 | -------------------------------------------------------------------------------- /test/examples/dhcp_server.c: -------------------------------------------------------------------------------- 1 | #include "utils.h" 2 | #include 3 | #include 4 | #include 5 | 6 | /*** START DHCP Server ***/ 7 | #ifdef PICO_SUPPORT_DHCPD 8 | /* ./build/test/picoapp.elf --vde pic0:/tmp/pic0.ctl:10.40.0.1:255.255.0.0: -a dhcpserver:pic0:10.40.0.1:255.255.255.0:64:128 9 | * ./build/test/picoapp.elf --vde pic0:/tmp/pic0.ctl:10.40.0.10:255.255.255.0: --vde pic1:/tmp/pic1.ctl:10.50.0.10:255.255.255.0: \ 10 | * -a dhcpserver:pic0:10.40.0.10:255.255.255.0:64:128:pic1:10.50.0.10:255.255.255.0:64:128 11 | */ 12 | void app_dhcp_server(char *arg) 13 | { 14 | struct pico_device *dev = NULL; 15 | struct pico_dhcp_server_setting s = { 16 | 0 17 | }; 18 | int pool_start = 0, pool_end = 0; 19 | char *s_name = NULL, *s_addr = NULL, *s_netm = NULL, *s_pool_start = NULL, *s_pool_end = NULL; 20 | char *nxt = arg; 21 | 22 | if (!nxt) 23 | goto out; 24 | 25 | while (nxt) { 26 | if (nxt) { 27 | nxt = cpy_arg(&s_name, nxt); 28 | if (!s_name) { 29 | goto out; 30 | } 31 | } else { 32 | goto out; 33 | } 34 | 35 | if (nxt) { 36 | nxt = cpy_arg(&s_addr, nxt); 37 | if (s_addr) { 38 | pico_string_to_ipv4(s_addr, &s.server_ip.addr); 39 | } else { 40 | goto out; 41 | } 42 | } else { 43 | goto out; 44 | } 45 | 46 | if (nxt) { 47 | nxt = cpy_arg(&s_netm, nxt); 48 | if (s_netm) { 49 | pico_string_to_ipv4(s_netm, &s.netmask.addr); 50 | } else { 51 | goto out; 52 | } 53 | } else { 54 | goto out; 55 | } 56 | 57 | if (nxt) { 58 | nxt = cpy_arg(&s_pool_start, nxt); 59 | if (s_pool_start && atoi(s_pool_start)) { 60 | pool_start = atoi(s_pool_start); 61 | } else { 62 | goto out; 63 | } 64 | } else { 65 | goto out; 66 | } 67 | 68 | if (nxt) { 69 | nxt = cpy_arg(&s_pool_end, nxt); 70 | if (s_pool_end && atoi(s_pool_end)) { 71 | pool_end = atoi(s_pool_end); 72 | } else { 73 | goto out; 74 | } 75 | } else { 76 | goto out; 77 | } 78 | 79 | dev = (struct pico_device *)pico_get_device(s_name); 80 | if (dev == NULL) { 81 | fprintf(stderr, "No device with name %s found\n", s_name); 82 | exit(255); 83 | } 84 | 85 | s.dev = dev; 86 | s.pool_start = (s.server_ip.addr & s.netmask.addr) | long_be(pool_start); 87 | s.pool_end = (s.server_ip.addr & s.netmask.addr) | long_be(pool_end); 88 | 89 | pico_dhcp_server_initiate(&s); 90 | } 91 | return; 92 | 93 | out: 94 | fprintf(stderr, "dhcpserver expects the following format: dhcpserver:dev_name:dev_addr:dev_netm:pool_start:pool_end\n"); 95 | exit(255); 96 | 97 | } 98 | #endif 99 | /*** END DHCP Server ***/ 100 | -------------------------------------------------------------------------------- /modules/pico_dev_tun.c: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved. 3 | See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage. 4 | 5 | Authors: Daniele Lacamera 6 | *********************************************************************/ 7 | 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include "pico_device.h" 14 | #include "pico_dev_tun.h" 15 | #include "pico_stack.h" 16 | 17 | #include 18 | 19 | struct pico_device_tun { 20 | struct pico_device dev; 21 | int fd; 22 | }; 23 | 24 | #define TUN_MTU 2048 25 | 26 | static int pico_tun_send(struct pico_device *dev, void *buf, int len) 27 | { 28 | struct pico_device_tun *tun = (struct pico_device_tun *) dev; 29 | return (int)write(tun->fd, buf, (uint32_t)len); 30 | } 31 | 32 | static int pico_tun_poll(struct pico_device *dev, int loop_score) 33 | { 34 | struct pico_device_tun *tun = (struct pico_device_tun *) dev; 35 | struct pollfd pfd; 36 | unsigned char buf[TUN_MTU]; 37 | int len; 38 | pfd.fd = tun->fd; 39 | pfd.events = POLLIN; 40 | do { 41 | if (poll(&pfd, 1, 0) <= 0) 42 | return loop_score; 43 | 44 | len = (int)read(tun->fd, buf, TUN_MTU); 45 | if (len > 0) { 46 | loop_score--; 47 | pico_stack_recv(dev, buf, (uint32_t)len); 48 | } 49 | } while(loop_score > 0); 50 | return 0; 51 | } 52 | 53 | /* Public interface: create/destroy. */ 54 | 55 | void pico_tun_destroy(struct pico_device *dev) 56 | { 57 | struct pico_device_tun *tun = (struct pico_device_tun *) dev; 58 | if(tun->fd > 0) 59 | close(tun->fd); 60 | } 61 | 62 | 63 | static int tun_open(char *name) 64 | { 65 | struct ifreq ifr; 66 | int tun_fd; 67 | if((tun_fd = open("/dev/net/tun", O_RDWR)) < 0) { 68 | return(-1); 69 | } 70 | 71 | memset(&ifr, 0, sizeof(ifr)); 72 | ifr.ifr_flags = IFF_TUN | IFF_NO_PI; 73 | strncpy(ifr.ifr_name, name, IFNAMSIZ); 74 | if(ioctl(tun_fd, TUNSETIFF, &ifr) < 0) { 75 | return(-1); 76 | } 77 | 78 | return tun_fd; 79 | } 80 | 81 | 82 | 83 | struct pico_device *pico_tun_create(char *name) 84 | { 85 | struct pico_device_tun *tun = PICO_ZALLOC(sizeof(struct pico_device_tun)); 86 | 87 | if (!tun) 88 | return NULL; 89 | 90 | if( 0 != pico_device_init((struct pico_device *)tun, name, NULL)) { 91 | dbg("Tun init failed.\n"); 92 | pico_tun_destroy((struct pico_device *)tun); 93 | return NULL; 94 | } 95 | 96 | tun->dev.overhead = 0; 97 | tun->fd = tun_open(name); 98 | if (tun->fd < 0) { 99 | dbg("Tun creation failed.\n"); 100 | pico_tun_destroy((struct pico_device *)tun); 101 | return NULL; 102 | } 103 | 104 | tun->dev.send = pico_tun_send; 105 | tun->dev.poll = pico_tun_poll; 106 | tun->dev.destroy = pico_tun_destroy; 107 | dbg("Device %s created.\n", tun->dev.name); 108 | return (struct pico_device *)tun; 109 | } 110 | 111 | -------------------------------------------------------------------------------- /modules/pico_dev_pcap.c: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved. 3 | See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage. 4 | 5 | Authors: Daniele Lacamera 6 | *********************************************************************/ 7 | 8 | 9 | #include 10 | #include "pico_device.h" 11 | #include "pico_dev_pcap.h" 12 | #include "pico_stack.h" 13 | 14 | #include 15 | 16 | struct pico_device_pcap { 17 | struct pico_device dev; 18 | pcap_t *conn; 19 | }; 20 | 21 | #define VDE_MTU 2048 22 | 23 | static int pico_pcap_send(struct pico_device *dev, void *buf, int len) 24 | { 25 | struct pico_device_pcap *pcap = (struct pico_device_pcap *) dev; 26 | /* dbg("[%s] send %d bytes.\n", dev->name, len); */ 27 | return pcap_inject(pcap->conn, buf, (uint32_t)len); 28 | } 29 | 30 | static void pico_dev_pcap_cb(u_char *u, const struct pcap_pkthdr *h, const u_char *data) 31 | { 32 | struct pico_device *dev = (struct pico_device *)u; 33 | const uint8_t *buf = (const uint8_t *)data; 34 | pico_stack_recv(dev, buf, (uint32_t)h->len); 35 | } 36 | 37 | 38 | static int pico_pcap_poll(struct pico_device *dev, int loop_score) 39 | { 40 | struct pico_device_pcap *pcap = (struct pico_device_pcap *) dev; 41 | loop_score -= pcap_dispatch(pcap->conn, loop_score, pico_dev_pcap_cb, (u_char *) pcap); 42 | return loop_score; 43 | } 44 | 45 | /* Public interface: create/destroy. */ 46 | 47 | void pico_pcap_destroy(struct pico_device *dev) 48 | { 49 | struct pico_device_pcap *pcap = (struct pico_device_pcap *) dev; 50 | pcap_close(pcap->conn); 51 | } 52 | 53 | #define PICO_PCAP_MODE_LIVE 0 54 | #define PICO_PCAP_MODE_STORED 1 55 | 56 | static struct pico_device *pico_pcap_create(char *if_file_name, char *name, uint8_t *mac, int mode) 57 | { 58 | struct pico_device_pcap *pcap = PICO_ZALLOC(sizeof(struct pico_device_pcap)); 59 | char errbuf[2000]; 60 | if (!pcap) 61 | return NULL; 62 | 63 | if( 0 != pico_device_init((struct pico_device *)pcap, name, mac)) { 64 | dbg ("Pcap init failed.\n"); 65 | pico_pcap_destroy((struct pico_device *)pcap); 66 | return NULL; 67 | } 68 | 69 | pcap->dev.overhead = 0; 70 | 71 | if (mode == PICO_PCAP_MODE_LIVE) 72 | pcap->conn = pcap_open_live(if_file_name, 2000, 100, 10, errbuf); 73 | else 74 | pcap->conn = pcap_open_offline(if_file_name, errbuf); 75 | 76 | if (!pcap->conn) { 77 | pico_pcap_destroy((struct pico_device *)pcap); 78 | return NULL; 79 | } 80 | 81 | pcap->dev.send = pico_pcap_send; 82 | pcap->dev.poll = pico_pcap_poll; 83 | pcap->dev.destroy = pico_pcap_destroy; 84 | dbg("Device %s created.\n", pcap->dev.name); 85 | return (struct pico_device *)pcap; 86 | } 87 | 88 | struct pico_device *pico_pcap_create_fromfile(char *filename, char *name, uint8_t *mac) 89 | { 90 | return pico_pcap_create(filename, name, mac, PICO_PCAP_MODE_STORED); 91 | } 92 | 93 | struct pico_device *pico_pcap_create_live(char *ifname, char *name, uint8_t *mac) 94 | { 95 | return pico_pcap_create(ifname, name, mac, PICO_PCAP_MODE_LIVE); 96 | } 97 | -------------------------------------------------------------------------------- /include/pico_tree.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved. 3 | See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage. 4 | 5 | Author: Andrei Carp 6 | *********************************************************************/ 7 | 8 | #ifndef PICO_RBTREE_H 9 | #define PICO_RBTREE_H 10 | 11 | #include "pico_config.h" 12 | 13 | /* This is used to declare a new tree, leaf root by default */ 14 | #define PICO_TREE_DECLARE(name, compareFunction) \ 15 | struct pico_tree name = \ 16 | { \ 17 | &LEAF, \ 18 | compareFunction \ 19 | } 20 | 21 | #define USE_PICO_PAGE0_ZALLOC (1) 22 | #define USE_PICO_ZALLOC (2) 23 | 24 | struct pico_tree_node 25 | { 26 | void*keyValue; /* generic key */ 27 | struct pico_tree_node*parent; 28 | struct pico_tree_node*leftChild; 29 | struct pico_tree_node*rightChild; 30 | uint8_t color; 31 | }; 32 | 33 | struct pico_tree 34 | { 35 | struct pico_tree_node *root; /* root of the tree */ 36 | 37 | /* this function directly provides the keys as parameters not the nodes. */ 38 | int (*compare)(void*keyA, void*keyB); 39 | }; 40 | 41 | extern struct pico_tree_node LEAF; /* generic leaf node */ 42 | 43 | #ifdef PICO_SUPPORT_MM 44 | void *pico_tree_insert_implementation(struct pico_tree *tree, void *key, uint8_t allocator); 45 | void *pico_tree_delete_implementation(struct pico_tree *tree, void *key, uint8_t allocator); 46 | #endif 47 | 48 | 49 | /* 50 | * Manipulation functions 51 | */ 52 | void *pico_tree_insert(struct pico_tree *tree, void *key); 53 | void *pico_tree_delete(struct pico_tree *tree, void *key); 54 | void *pico_tree_findKey(struct pico_tree *tree, void *key); 55 | void pico_tree_drop(struct pico_tree *tree); 56 | int pico_tree_empty(struct pico_tree *tree); 57 | struct pico_tree_node *pico_tree_findNode(struct pico_tree *tree, void *key); 58 | 59 | void *pico_tree_first(struct pico_tree *tree); 60 | void *pico_tree_last(struct pico_tree *tree); 61 | /* 62 | * Traverse functions 63 | */ 64 | struct pico_tree_node *pico_tree_lastNode(struct pico_tree_node *node); 65 | struct pico_tree_node *pico_tree_firstNode(struct pico_tree_node *node); 66 | struct pico_tree_node *pico_tree_next(struct pico_tree_node *node); 67 | struct pico_tree_node *pico_tree_prev(struct pico_tree_node *node); 68 | 69 | /* 70 | * For each macros 71 | */ 72 | 73 | #define pico_tree_foreach(idx, tree) \ 74 | for ((idx) = pico_tree_firstNode((tree)->root); \ 75 | (idx) != &LEAF; \ 76 | (idx) = pico_tree_next(idx)) 77 | 78 | #define pico_tree_foreach_reverse(idx, tree) \ 79 | for ((idx) = pico_tree_lastNode((tree)->root); \ 80 | (idx) != &LEAF; \ 81 | (idx) = pico_tree_prev(idx)) 82 | 83 | #define pico_tree_foreach_safe(idx, tree, idx2) \ 84 | for ((idx) = pico_tree_firstNode((tree)->root); \ 85 | ((idx) != &LEAF) && ((idx2) = pico_tree_next(idx), 1); \ 86 | (idx) = (idx2)) 87 | 88 | #define pico_tree_foreach_reverse_safe(idx, tree, idx2) \ 89 | for ((idx) = pico_tree_lastNode((tree)->root); \ 90 | ((idx) != &LEAF) && ((idx2) = pico_tree_prev(idx), 1); \ 91 | (idx) = (idx2)) 92 | 93 | #endif 94 | -------------------------------------------------------------------------------- /modules/pico_dev_tap_windows_private.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | PicoTCP. Copyright (c) 2014-2017 Altran Intelligent Systems. Some rights reserved. 3 | See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage. 4 | 5 | Authors: Maxime Vincent 6 | Based on the OpenVPN tun.c driver, under GPL 7 | 8 | NOTES: This is the Windows-only driver, a Linux-equivalent is available, too 9 | You need to have an OpenVPN TUN/TAP network adapter installed, first 10 | This driver is barely working: 11 | * Only TAP-mode is supported (TUN is not) 12 | * it will simply open the first TAP device it can find 13 | * there is memory being allocated that's never freed 14 | * there is no destroy function, yet 15 | * it has only been tested on a Windows 7 machine 16 | *********************************************************************/ 17 | 18 | #ifndef __PICO_DEV_TAP_WINDOWS_PRIVATE_H 19 | #define __PICO_DEV_TAP_WINDOWS_PRIVATE_H 20 | 21 | /* Extra defines (vnz) */ 22 | #define TAP_WIN_COMPONENT_ID "tap0901" 23 | #define TAP_WIN_MIN_MAJOR 9 24 | #define TAP_WIN_MIN_MINOR 9 25 | #define PACKAGE_NAME "PicoTCP WinTAP" 26 | 27 | /* Extra structs */ 28 | struct tap_reg 29 | { 30 | const char *guid; 31 | struct tap_reg *next; 32 | }; 33 | 34 | struct panel_reg 35 | { 36 | const char *name; 37 | const char *guid; 38 | struct panel_reg *next; 39 | }; 40 | 41 | 42 | /* 43 | * ============= 44 | * TAP IOCTLs 45 | * ============= 46 | */ 47 | 48 | #define TAP_WIN_CONTROL_CODE(request, method) \ 49 | CTL_CODE (FILE_DEVICE_UNKNOWN, request, method, FILE_ANY_ACCESS) 50 | 51 | /* Present in 8.1 */ 52 | 53 | #define TAP_WIN_IOCTL_GET_MAC TAP_WIN_CONTROL_CODE (1, METHOD_BUFFERED) 54 | #define TAP_WIN_IOCTL_GET_VERSION TAP_WIN_CONTROL_CODE (2, METHOD_BUFFERED) 55 | #define TAP_WIN_IOCTL_GET_MTU TAP_WIN_CONTROL_CODE (3, METHOD_BUFFERED) 56 | #define TAP_WIN_IOCTL_GET_INFO TAP_WIN_CONTROL_CODE (4, METHOD_BUFFERED) 57 | #define TAP_WIN_IOCTL_CONFIG_POINT_TO_POINT TAP_WIN_CONTROL_CODE (5, METHOD_BUFFERED) 58 | #define TAP_WIN_IOCTL_SET_MEDIA_STATUS TAP_WIN_CONTROL_CODE (6, METHOD_BUFFERED) 59 | #define TAP_WIN_IOCTL_CONFIG_DHCP_MASQ TAP_WIN_CONTROL_CODE (7, METHOD_BUFFERED) 60 | #define TAP_WIN_IOCTL_GET_LOG_LINE TAP_WIN_CONTROL_CODE (8, METHOD_BUFFERED) 61 | #define TAP_WIN_IOCTL_CONFIG_DHCP_SET_OPT TAP_WIN_CONTROL_CODE (9, METHOD_BUFFERED) 62 | 63 | /* Added in 8.2 */ 64 | 65 | /* obsoletes TAP_WIN_IOCTL_CONFIG_POINT_TO_POINT */ 66 | #define TAP_WIN_IOCTL_CONFIG_TUN TAP_WIN_CONTROL_CODE (10, METHOD_BUFFERED) 67 | 68 | /* 69 | * ================= 70 | * Registry keys 71 | * ================= 72 | */ 73 | 74 | #define ADAPTER_KEY "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}" 75 | 76 | #define NETWORK_CONNECTIONS_KEY "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}" 77 | 78 | /* 79 | * ====================== 80 | * Filesystem prefixes 81 | * ====================== 82 | */ 83 | 84 | #define USERMODEDEVICEDIR "\\\\.\\Global\\" 85 | #define SYSDEVICEDIR "\\Device\\" 86 | #define USERDEVICEDIR "\\DosDevices\\Global\\" 87 | #define TAP_WIN_SUFFIX ".tap" 88 | 89 | #endif 90 | -------------------------------------------------------------------------------- /test/unit/unit_dns.c: -------------------------------------------------------------------------------- 1 | void cb_dns(char *ip, void *arg); 2 | 3 | void cb_dns(char *ip, void *arg) 4 | { 5 | if (!ip) { 6 | /* Error occured */ 7 | printf("DNS error getaddr\n"); 8 | return; 9 | } 10 | 11 | /* Do something */ 12 | printf("DNS -> %s\n", ip); 13 | PICO_FREE(ip); 14 | if (arg) 15 | PICO_FREE(arg); 16 | } 17 | 18 | 19 | START_TEST (test_dns) 20 | { 21 | int ret; 22 | char url[] = "www.google.com"; 23 | char ip[] = "8.8.4.4"; 24 | struct pico_ip4 ns; 25 | 26 | ns.addr = long_be(0x0a00280a); /* 10.40.0.10 */ 27 | 28 | pico_stack_init(); 29 | 30 | printf("START DNS TEST\n"); 31 | 32 | /* testing nameserver API */ 33 | ret = pico_dns_client_nameserver(NULL, PICO_DNS_NS_ADD); 34 | fail_if(ret == 0, "dns> dns_client_nameserver add error"); 35 | 36 | ret = pico_dns_client_nameserver(NULL, PICO_DNS_NS_DEL); 37 | fail_if(ret == 0, "dns> dns_client_nameserver del error"); 38 | 39 | ret = pico_dns_client_nameserver(NULL, 99); 40 | fail_if(ret == 0, "dns> dns_client_nameserver wrong code"); 41 | 42 | ret = pico_dns_client_nameserver(NULL, 0xFF); 43 | fail_if(ret == 0, "dns> dns_client_nameserver wrong code"); 44 | 45 | ret = pico_dns_client_nameserver(&ns, PICO_DNS_NS_DEL); /* delete non added ns */ 46 | fail_if(ret == 0, "dns> dns_client_nameserver del error"); 47 | 48 | ret = pico_dns_client_nameserver(&ns, 99); 49 | fail_if(ret == 0, "dns> dns_client_nameserver wrong code"); 50 | 51 | ret = pico_dns_client_nameserver(&ns, PICO_DNS_NS_ADD); /* add correct one */ 52 | fail_if(ret < 0, "dns> dns_client_nameserver add error: %s", strerror(pico_err)); 53 | 54 | ret = pico_dns_client_nameserver(&ns, 99); 55 | fail_if(ret == 0, "dns> dns_client_nameserver wrong code"); 56 | 57 | ret = pico_dns_client_nameserver(&ns, PICO_DNS_NS_DEL); 58 | fail_if(ret < 0, "dns> dns_client_nameserver del error: %s", strerror(pico_err)); 59 | 60 | ret = pico_dns_client_nameserver(&ns, PICO_DNS_NS_ADD); /* add correct one */ 61 | fail_if(ret < 0, "dns> dns_client_nameserver add error: %s", strerror(pico_err)); 62 | 63 | ret = pico_dns_client_nameserver(&ns, PICO_DNS_NS_ADD); /* add correct one again */ 64 | fail_if(ret < 0, "dns> dns_client_nameserver add double failed"); 65 | 66 | /* testing getaddr API */ 67 | /* not testable since we do not have a stub for the pico_socket_send */ 68 | /* ret = pico_dns_client_getaddr(url, cb_dns, NULL); / * ask correct one * / */ 69 | /* fail_if(ret < 0, "dns> dns_client_getaddr: %s",strerror(pico_err)); */ 70 | 71 | ret = pico_dns_client_getaddr(NULL, cb_dns, NULL); 72 | fail_if(ret == 0, "dns> dns_client_getaddr: no url"); 73 | 74 | ret = pico_dns_client_getaddr(url, NULL, NULL); 75 | fail_if(ret == 0, "dns> dns_client_getaddr: no cb"); 76 | 77 | /* testing getname API */ 78 | /* not testable since we do not have a stub for the pico_socket_send */ 79 | /* ret = pico_dns_client_getname(ip, cb_dns, NULL); / * ask correct one * / */ 80 | /* fail_if(ret < 0, "dns> dns_client_getname: %s",strerror(pico_err)); */ 81 | 82 | ret = pico_dns_client_getname(NULL, cb_dns, NULL); 83 | fail_if(ret == 0, "dns> dns_client_getname: no ip"); 84 | 85 | ret = pico_dns_client_getname(ip, NULL, NULL); 86 | fail_if(ret == 0, "dns> dns_client_getname: no cb"); 87 | } 88 | END_TEST 89 | -------------------------------------------------------------------------------- /modules/pico_dev_ipc.c: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved. 3 | See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage. 4 | 5 | Authors: Michiel Kustermans 6 | *********************************************************************/ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #include "pico_device.h" 13 | #include "pico_dev_ipc.h" 14 | #include "pico_stack.h" 15 | 16 | struct pico_device_ipc { 17 | struct pico_device dev; 18 | int fd; 19 | }; 20 | 21 | #define IPC_MTU 2048 22 | 23 | static int pico_ipc_send(struct pico_device *dev, void *buf, int len) 24 | { 25 | struct pico_device_ipc *ipc = (struct pico_device_ipc *) dev; 26 | return (int)write(ipc->fd, buf, (uint32_t)len); 27 | } 28 | 29 | static int pico_ipc_poll(struct pico_device *dev, int loop_score) 30 | { 31 | struct pico_device_ipc *ipc = (struct pico_device_ipc *) dev; 32 | struct pollfd pfd; 33 | unsigned char buf[IPC_MTU]; 34 | int len; 35 | pfd.fd = ipc->fd; 36 | pfd.events = POLLIN; 37 | do { 38 | if (poll(&pfd, 1, 0) <= 0) 39 | return loop_score; 40 | 41 | len = (int)read(ipc->fd, buf, IPC_MTU); 42 | if (len > 0) { 43 | loop_score--; 44 | pico_stack_recv(dev, buf, (uint32_t)len); 45 | } 46 | } while(loop_score > 0); 47 | return 0; 48 | } 49 | 50 | /* Public interface: create/destroy. */ 51 | 52 | void pico_ipc_destroy(struct pico_device *dev) 53 | { 54 | struct pico_device_ipc *ipc = (struct pico_device_ipc *) dev; 55 | if(ipc->fd > 0) { 56 | close(ipc->fd); 57 | } 58 | } 59 | 60 | static int ipc_connect(const char *sock_path) 61 | { 62 | struct sockaddr_un addr; 63 | int ipc_fd; 64 | 65 | if((ipc_fd = socket(AF_UNIX, SOCK_SEQPACKET, 0)) < 0) { 66 | return(-1); 67 | } 68 | 69 | memset(&addr, 0, sizeof(addr)); 70 | addr.sun_family = AF_UNIX; 71 | strncpy(addr.sun_path, sock_path, sizeof(addr.sun_path) - 1); 72 | addr.sun_path[sizeof(addr.sun_path) - 1] = '\0'; 73 | 74 | if(connect(ipc_fd, (struct sockaddr *) &addr, sizeof(struct sockaddr_un)) < 0) { 75 | return(-1); 76 | } 77 | 78 | return ipc_fd; 79 | } 80 | 81 | struct pico_device *pico_ipc_create(const char *sock_path, const char *name, const uint8_t *mac) 82 | { 83 | struct pico_device_ipc *ipc = PICO_ZALLOC(sizeof(struct pico_device_ipc)); 84 | 85 | if (!ipc) 86 | return NULL; 87 | 88 | ipc->dev.mtu = IPC_MTU; 89 | 90 | if( 0 != pico_device_init((struct pico_device *)ipc, name, mac)) { 91 | dbg("Ipc init failed.\n"); 92 | pico_ipc_destroy((struct pico_device *)ipc); 93 | return NULL; 94 | } 95 | 96 | ipc->dev.overhead = 0; 97 | ipc->fd = ipc_connect(sock_path); 98 | if (ipc->fd < 0) { 99 | dbg("Ipc creation failed.\n"); 100 | pico_ipc_destroy((struct pico_device *)ipc); 101 | return NULL; 102 | } 103 | 104 | ipc->dev.send = pico_ipc_send; 105 | ipc->dev.poll = pico_ipc_poll; 106 | ipc->dev.destroy = pico_ipc_destroy; 107 | dbg("Device %s created.\n", ipc->dev.name); 108 | return (struct pico_device *)ipc; 109 | } 110 | -------------------------------------------------------------------------------- /test/examples/dns_sd.c: -------------------------------------------------------------------------------- 1 | #include "utils.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | /*** START DNS_SD ***/ 9 | #ifdef PICO_SUPPORT_DNS_SD 10 | 11 | #define TTL 30 12 | #define SECONDS 10 13 | 14 | static int fully_initialized = 0; 15 | static char *service_name = NULL; 16 | 17 | void dns_sd_claimed_callback( pico_mdns_rtree *tree, 18 | char *str, 19 | void *arg ) 20 | { 21 | printf("DONE - Registering DNS-SD Service\n"); 22 | 23 | IGNORE_PARAMETER(tree); 24 | IGNORE_PARAMETER(str); 25 | IGNORE_PARAMETER(arg); 26 | } 27 | 28 | void dns_sd_init_callback( pico_mdns_rtree *tree, 29 | char *str, 30 | void *arg ) 31 | { 32 | PICO_DNS_SD_KV_VECTOR_DECLARE(key_value_pair_vector); 33 | 34 | IGNORE_PARAMETER(str); 35 | IGNORE_PARAMETER(arg); 36 | IGNORE_PARAMETER(tree); 37 | 38 | pico_dns_sd_kv_vector_add(&key_value_pair_vector, "key", "value"); 39 | 40 | printf("DONE - Initialising DNS Service Discovery module.\n"); 41 | 42 | if (pico_dns_sd_register_service(service_name, 43 | "_http._tcp", 80, 44 | &key_value_pair_vector, 45 | TTL, dns_sd_claimed_callback, NULL) < 0) { 46 | printf("Registering service failed!\n"); 47 | } 48 | 49 | fully_initialized = 1; 50 | } 51 | 52 | void app_dns_sd(char *arg, struct pico_ip4 address) 53 | { 54 | char *hostname; 55 | char *nxt = arg; 56 | uint64_t starttime = 0; 57 | int once = 0; 58 | 59 | if (!nxt) { 60 | exit(255); 61 | } 62 | 63 | nxt = cpy_arg(&hostname, nxt); 64 | if(!hostname) { 65 | exit(255); 66 | } 67 | 68 | if(!nxt) { 69 | printf("Not enough args supplied!\n"); 70 | exit(255); 71 | } 72 | 73 | nxt = cpy_arg(&service_name, nxt); 74 | if(!service_name) { 75 | exit(255); 76 | } 77 | 78 | printf("\nStarting DNS Service Discovery module...\n"); 79 | if (pico_dns_sd_init(hostname, address, &dns_sd_init_callback, NULL) != 0) { 80 | printf("Initialisation returned with Error!\n"); 81 | exit(255); 82 | } 83 | 84 | printf("\nTry reinitialising DNS-SD\n"); 85 | if (pico_dns_sd_init(hostname, address, &dns_sd_init_callback, NULL)) { 86 | printf("Initialisation returned with Error!\n"); 87 | exit(255); 88 | } 89 | 90 | printf("DONE - Re-initialising DNS-SD module.\n"); 91 | 92 | starttime = PICO_TIME_MS(); 93 | printf("Starting time: %d\n", starttime); 94 | 95 | while(1) { 96 | pico_stack_tick(); 97 | usleep(2000); 98 | 99 | if (((PICO_TIME_MS() - starttime) > SECONDS * 1000) && fully_initialized && !once) { 100 | printf("\nTry reinitialising DNS-SD (a second time)\n"); 101 | if (pico_dns_sd_init(hostname, address, &dns_sd_init_callback, NULL)) { 102 | printf("Initialisation returned with Error!\n"); 103 | exit(255); 104 | } 105 | once = 1; 106 | printf("DONE - Re-initialising mDNS module. (a second time)\n"); 107 | } 108 | } 109 | } 110 | 111 | #endif 112 | /*** END DNS_SD ***/ 113 | -------------------------------------------------------------------------------- /include/pico_protocol.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved. 3 | See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage. 4 | 5 | *********************************************************************/ 6 | #ifndef INCLUDE_PICO_PROTOCOL 7 | #define INCLUDE_PICO_PROTOCOL 8 | #include "pico_config.h" 9 | #include "pico_queue.h" 10 | 11 | #define PICO_LOOP_DIR_IN 1 12 | #define PICO_LOOP_DIR_OUT 2 13 | 14 | enum pico_layer { 15 | PICO_LAYER_DATALINK = 2, /* Ethernet only. */ 16 | PICO_LAYER_NETWORK = 3, /* IPv4, IPv6, ARP. Arp is there because it communicates with L2 */ 17 | PICO_LAYER_TRANSPORT = 4, /* UDP, TCP, ICMP */ 18 | PICO_LAYER_SOCKET = 5 /* Socket management */ 19 | }; 20 | 21 | enum pico_err_e { 22 | PICO_ERR_NOERR = 0, 23 | PICO_ERR_EPERM = 1, 24 | PICO_ERR_ENOENT = 2, 25 | /* ... */ 26 | PICO_ERR_EINTR = 4, 27 | PICO_ERR_EIO = 5, 28 | PICO_ERR_ENXIO = 6, 29 | /* ... */ 30 | PICO_ERR_EAGAIN = 11, 31 | PICO_ERR_ENOMEM = 12, 32 | PICO_ERR_EACCESS = 13, 33 | PICO_ERR_EFAULT = 14, 34 | /* ... */ 35 | PICO_ERR_EBUSY = 16, 36 | PICO_ERR_EEXIST = 17, 37 | /* ... */ 38 | PICO_ERR_EINVAL = 22, 39 | /* ... */ 40 | PICO_ERR_ENONET = 64, 41 | /* ... */ 42 | PICO_ERR_EPROTO = 71, 43 | /* ... */ 44 | PICO_ERR_ENOPROTOOPT = 92, 45 | PICO_ERR_EPROTONOSUPPORT = 93, 46 | /* ... */ 47 | PICO_ERR_EOPNOTSUPP = 95, 48 | PICO_ERR_EADDRINUSE = 98, 49 | PICO_ERR_EADDRNOTAVAIL = 99, 50 | PICO_ERR_ENETDOWN = 100, 51 | PICO_ERR_ENETUNREACH = 101, 52 | /* ... */ 53 | PICO_ERR_ECONNRESET = 104, 54 | /* ... */ 55 | PICO_ERR_EISCONN = 106, 56 | PICO_ERR_ENOTCONN = 107, 57 | PICO_ERR_ESHUTDOWN = 108, 58 | /* ... */ 59 | PICO_ERR_ETIMEDOUT = 110, 60 | PICO_ERR_ECONNREFUSED = 111, 61 | PICO_ERR_EHOSTDOWN = 112, 62 | PICO_ERR_EHOSTUNREACH = 113, 63 | /* ... */ 64 | PICO_ERR_EINPROGRESS = 115, 65 | }; 66 | 67 | typedef enum pico_err_e pico_err_t; 68 | extern volatile pico_err_t pico_err; 69 | 70 | #define IS_IPV6(f) (f && f->net_hdr && ((((uint8_t *)(f->net_hdr))[0] & 0xf0) == 0x60)) 71 | #define IS_IPV4(f) (f && f->net_hdr && ((((uint8_t *)(f->net_hdr))[0] & 0xf0) == 0x40)) 72 | 73 | #define MAX_PROTOCOL_NAME 16 74 | 75 | struct pico_protocol { 76 | char name[MAX_PROTOCOL_NAME]; 77 | uint32_t hash; 78 | enum pico_layer layer; 79 | uint16_t proto_number; 80 | struct pico_queue *q_in; 81 | struct pico_queue *q_out; 82 | struct pico_frame *(*alloc)(struct pico_protocol *self, struct pico_device *dev, uint16_t size); /* Frame allocation. */ 83 | int (*push)(struct pico_protocol *self, struct pico_frame *p); /* Push function, for active outgoing pkts from above */ 84 | int (*process_out)(struct pico_protocol *self, struct pico_frame *p); /* Send loop. */ 85 | int (*process_in)(struct pico_protocol *self, struct pico_frame *p); /* Recv loop. */ 86 | uint16_t (*get_mtu)(struct pico_protocol *self); 87 | }; 88 | 89 | int pico_protocols_loop(int loop_score); 90 | void pico_protocol_init(struct pico_protocol *p); 91 | 92 | int pico_protocol_datalink_loop(int loop_score, int direction); 93 | int pico_protocol_network_loop(int loop_score, int direction); 94 | int pico_protocol_transport_loop(int loop_score, int direction); 95 | int pico_protocol_socket_loop(int loop_score, int direction); 96 | 97 | #endif 98 | -------------------------------------------------------------------------------- /modules/pico_tftp.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved. 3 | See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage. 4 | 5 | . 6 | *********************************************************************/ 7 | #ifndef PICO_TFTP_H 8 | #define PICO_TFTP_H 9 | 10 | #include 11 | #include 12 | 13 | #define PICO_TFTP_PORT (69) 14 | #define PICO_TFTP_PAYLOAD_SIZE (512) 15 | 16 | #define PICO_TFTP_NONE 0 17 | #define PICO_TFTP_RRQ 1 18 | #define PICO_TFTP_WRQ 2 19 | #define PICO_TFTP_DATA 3 20 | #define PICO_TFTP_ACK 4 21 | #define PICO_TFTP_ERROR 5 22 | #define PICO_TFTP_OACK 6 23 | 24 | /* Callback user events */ 25 | #define PICO_TFTP_EV_OK 0 26 | #define PICO_TFTP_EV_OPT 1 27 | #define PICO_TFTP_EV_ERR_PEER 2 28 | #define PICO_TFTP_EV_ERR_LOCAL 3 29 | 30 | /* TFTP ERROR CODES */ 31 | #define TFTP_ERR_UNDEF 0 32 | #define TFTP_ERR_ENOENT 1 33 | #define TFTP_ERR_EACC 2 34 | #define TFTP_ERR_EXCEEDED 3 35 | #define TFTP_ERR_EILL 4 36 | #define TFTP_ERR_ETID 5 37 | #define TFTP_ERR_EEXIST 6 38 | #define TFTP_ERR_EUSR 7 39 | #define TFTP_ERR_EOPT 8 40 | 41 | /* Session options */ 42 | #define PICO_TFTP_OPTION_FILE 1 43 | 44 | /* timeout: 0 -> adaptative, 1-255 -> fixed */ 45 | #define PICO_TFTP_OPTION_TIME 2 46 | 47 | 48 | #define PICO_TFTP_MAX_TIMEOUT 255 49 | #define PICO_TFTP_MAX_FILESIZE (65535 * 512 - 1) 50 | 51 | struct pico_tftp_session; 52 | 53 | struct pico_tftp_session *pico_tftp_session_setup(union pico_address *a, uint16_t family); 54 | int pico_tftp_set_option(struct pico_tftp_session *session, uint8_t type, int32_t value); 55 | int pico_tftp_get_option(struct pico_tftp_session *session, uint8_t type, int32_t *value); 56 | 57 | int pico_tftp_start_rx(struct pico_tftp_session *session, uint16_t port, const char *filename, 58 | int (*user_cb)(struct pico_tftp_session *session, uint16_t event, uint8_t *block, int32_t len, void *arg), void *arg); 59 | int pico_tftp_start_tx(struct pico_tftp_session *session, uint16_t port, const char *filename, 60 | int (*user_cb)(struct pico_tftp_session *session, uint16_t event, uint8_t *block, int32_t len, void *arg), void *arg); 61 | 62 | int pico_tftp_reject_request(union pico_address *addr, uint16_t port, uint16_t error_code, const char *error_message); 63 | int32_t pico_tftp_send(struct pico_tftp_session *session, const uint8_t *data, int32_t len); 64 | 65 | int pico_tftp_listen(uint16_t family, void (*cb)(union pico_address *addr, uint16_t port, uint16_t opcode, char *filename, int32_t len)); 66 | 67 | int pico_tftp_parse_request_args(char *args, int32_t len, int *options, uint8_t *timeout, int32_t *filesize); 68 | 69 | int pico_tftp_abort(struct pico_tftp_session *session, uint16_t error, const char *reason); 70 | int pico_tftp_close_server(void); 71 | 72 | int pico_tftp_get_file_size(struct pico_tftp_session *session, int32_t *file_size); 73 | 74 | /* SPECIFIC APPLICATION DRIVEN FUNCTIONS */ 75 | struct pico_tftp_session *pico_tftp_app_setup(union pico_address *a, uint16_t port, uint16_t family, int *synchro); 76 | 77 | int pico_tftp_app_start_rx(struct pico_tftp_session *session, const char *filename); 78 | int pico_tftp_app_start_tx(struct pico_tftp_session *session, const char *filename); 79 | 80 | int32_t pico_tftp_get(struct pico_tftp_session *session, uint8_t *data, int32_t len); 81 | int32_t pico_tftp_put(struct pico_tftp_session *session, uint8_t *data, int32_t len); 82 | 83 | #endif 84 | -------------------------------------------------------------------------------- /test/examples/dhcp_client.c: -------------------------------------------------------------------------------- 1 | #include "utils.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | /*** START DHCP Client ***/ 8 | #ifdef PICO_SUPPORT_DHCPC 9 | 10 | /* This must stay global, its lifetime is the same as the dhcp negotiation */ 11 | uint32_t dhcpclient_xid; 12 | 13 | 14 | static uint8_t dhcpclient_devices = 0; 15 | 16 | void ping_callback_dhcpclient(struct pico_icmp4_stats *s) 17 | { 18 | char host[30] = { }; 19 | 20 | pico_ipv4_to_string(host, s->dst.addr); 21 | if (s->err == 0) { 22 | dbg("DHCP client: %lu bytes from %s: icmp_req=%lu ttl=64 time=%lu ms\n", 23 | s->size, host, s->seq, (long unsigned int)s->time); 24 | if (s->seq >= 3) { 25 | dbg("DHCP client: TEST SUCCESS!\n"); 26 | if (--dhcpclient_devices <= 0) 27 | exit(0); 28 | } 29 | } else { 30 | dbg("DHCP client: ping %lu to %s error %d\n", s->seq, host, s->err); 31 | dbg("DHCP client: TEST FAILED!\n"); 32 | exit(1); 33 | } 34 | } 35 | 36 | void callback_dhcpclient(void *arg, int code) 37 | { 38 | struct pico_ip4 address = ZERO_IP4, gateway = ZERO_IP4; 39 | char s_address[16] = { }, s_gateway[16] = { }; 40 | 41 | printf("DHCP client: callback happened with code %d!\n", code); 42 | if (code == PICO_DHCP_SUCCESS) { 43 | address = pico_dhcp_get_address(arg); 44 | gateway = pico_dhcp_get_gateway(arg); 45 | pico_ipv4_to_string(s_address, address.addr); 46 | pico_ipv4_to_string(s_gateway, gateway.addr); 47 | printf("DHCP client: got IP %s assigned with cli %p\n", s_address, arg); 48 | #ifdef PICO_SUPPORT_PING 49 | pico_icmp4_ping(s_gateway, 3, 1000, 5000, 32, ping_callback_dhcpclient); 50 | /* optional test to check routing when links get added and deleted */ 51 | /* do { 52 | char *new_arg = NULL, *p = NULL; 53 | new_arg = calloc(1, strlen(s_address) + strlen(":224.7.7.7:6667:6667") + 1); 54 | p = strcat(new_arg, s_address); 55 | p = strcat(p + strlen(s_address), ":224.7.7.7:6667:6667"); 56 | app_mcastsend(new_arg); 57 | } while (0); 58 | */ 59 | #endif 60 | } 61 | } 62 | 63 | void app_dhcp_client(char *arg) 64 | { 65 | char *sdev = NULL; 66 | char *nxt = arg; 67 | struct pico_device *dev = NULL; 68 | 69 | if (!nxt) 70 | goto out; 71 | 72 | while (nxt) { 73 | if (nxt) { 74 | nxt = cpy_arg(&sdev, nxt); 75 | if(!sdev) { 76 | goto out; 77 | } 78 | } 79 | 80 | dev = pico_get_device(sdev); 81 | if(dev == NULL) { 82 | if (sdev) 83 | free(sdev); 84 | 85 | printf("%s: error getting device %s: %s\n", __FUNCTION__, dev->name, strerror(pico_err)); 86 | exit(255); 87 | } 88 | 89 | printf("Starting negotiation\n"); 90 | 91 | if (pico_dhcp_initiate_negotiation(dev, &callback_dhcpclient, &dhcpclient_xid) < 0) { 92 | printf("%s: error initiating negotiation: %s\n", __FUNCTION__, strerror(pico_err)); 93 | if (sdev) 94 | free(sdev); 95 | 96 | exit(255); 97 | } 98 | 99 | if (sdev) 100 | free(sdev); 101 | 102 | dhcpclient_devices++; 103 | } 104 | return; 105 | 106 | out: 107 | fprintf(stderr, "dhcpclient expects the following format: dhcpclient:dev_name:[dev_name]\n"); 108 | if (sdev) 109 | free(sdev); 110 | 111 | exit(255); 112 | } 113 | #endif 114 | /*** END DHCP Client ***/ 115 | -------------------------------------------------------------------------------- /docs/user_manual/chap_api_ipfilter.tex: -------------------------------------------------------------------------------- 1 | \section{IP Filter} 2 | 3 | % Short description/overview of module functions 4 | This module allows the user to add and remove filters. The user can filter packets based on interface, protocol, outgoing address, outgoing netmask, incomming address, incomming netmask, outgoing port, incomming port, priority and type of service. There are four types of filters: ACCEPT, PRIORITY, REJECT, DROP. When creating a PRIORITY filter, it is necessary to give a priority value in a range between '-10' and '10', '0' as default priority. 5 | 6 | 7 | \subsection{pico$\_$ipv4$\_$filter$\_$add} 8 | 9 | \subsubsection*{Description} 10 | Function to add a filter. 11 | 12 | \subsubsection*{Function prototype} 13 | \begin{verbatim} 14 | int pico_ipv4_filter_add(struct pico_device *dev, uint8_t proto, 15 | struct pico_ip4 out_addr, struct pico_ip4 out_addr_netmask, 16 | struct pico_ip4 in_addr, struct pico_ip4 in_addr_netmask, uint16_t out_port, 17 | uint16_t in_port, int8_t priority, uint8_t tos, enum filter_action action); 18 | \end{verbatim} 19 | 20 | \subsubsection*{Parameters} 21 | \begin{itemize}[noitemsep] 22 | \item \texttt{dev} - interface to be filtered 23 | \item \texttt{proto} - protocol to be filtered 24 | \item \texttt{out$\_$addr} - outgoing address to be filtered 25 | \item \texttt{out$\_$addr$\_$netmask} - outgoing address-netmask to be filtered 26 | \item \texttt{in$\_$addr} - incomming address to be filtered 27 | \item \texttt{in$\_$addr$\_$netmask} - incomming address-netmask to be filtered 28 | \item \texttt{out$\_$port} - outgoing port to be filtered 29 | \item \texttt{in$\_$port} - incomming port to be filtered 30 | \item \texttt{priority} - priority to assign on the marked packet 31 | \item \texttt{tos} - type of service to be filtered 32 | \item \texttt{action} - type of action for the filter: ACCEPT, PRIORITY, REJECT and DROP. ACCEPT, filters all packets selected by the filter. PRIORITY is not yet implemented. REJECT drops all packets and send an ICMP message 'Packet Filtered' (Communication Administratively Prohibited). DROP will discard the packet silently. 33 | \end{itemize} 34 | 35 | \subsubsection*{Return value} 36 | On success, this call returns the filter$\_$id from the generated filter. This id must be used when deleting the filter. 37 | On error, -1 is returned and \texttt{pico$\_$err} is set appropriately. 38 | 39 | \subsubsection*{Example} 40 | \begin{verbatim} 41 | /* block all incoming traffic on port 5555 */ 42 | filter_id = pico_ipv4_filter_add(NULL, 6, NULL, NULL, NULL, NULL, 0, 5555, 43 | 0, 0, FILTER_REJECT); 44 | \end{verbatim} 45 | 46 | \subsubsection*{Errors} 47 | 48 | \begin{itemize}[noitemsep] 49 | \item \texttt{PICO$\_$ERR$\_$EINVAL} - invalid argument 50 | \end{itemize} 51 | 52 | 53 | \subsection{pico$\_$ipv4$\_$filter$\_$del} 54 | 55 | \subsubsection*{Description} 56 | Function to delete a filter. 57 | 58 | \subsubsection*{Function prototype} 59 | \begin{verbatim} 60 | int pico_ipv4_filter_del(int filter_id) 61 | \end{verbatim} 62 | 63 | \subsubsection*{Parameters} 64 | \begin{itemize}[noitemsep] 65 | \item \texttt{filter$\_$id} - the id of the filter you want to delete. 66 | \end{itemize} 67 | 68 | \subsubsection*{Return value} 69 | On success, this call returns 0. 70 | On error, -1 is returned and \texttt{pico$\_$err} is set appropriately. 71 | 72 | \subsubsection*{Errors} 73 | 74 | \begin{itemize}[noitemsep] 75 | \item \texttt{PICO$\_$ERR$\_$EINVAL} - invalid argument 76 | \item \texttt{PICO$\_$ERR$\_$EPERM} - operation not permitted 77 | \end{itemize} 78 | 79 | \subsubsection*{Example} 80 | \begin{verbatim} 81 | ret = pico_ipv4_filter_del(filter_id); 82 | \end{verbatim} 83 | 84 | 85 | %\subsubsection*{Parameters} 86 | %\subsubsection*{Return value} 87 | %\subsubsection*{Errors} 88 | %\subsubsection*{Example} 89 | 90 | -------------------------------------------------------------------------------- /test/pico_faulty.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved. 3 | See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage. 4 | Do not redistribute without a written permission by the Copyright 5 | holders. 6 | *********************************************************************/ 7 | 8 | 9 | /* This is a test implementation, with a faulty memory manager, 10 | * intended to increase test coverage 11 | * Warning: not intended for production! 12 | * 13 | */ 14 | 15 | 16 | #ifndef PICO_SUPPORT_POSIX 17 | #define PICO_SUPPORT_POSIX 18 | 19 | #define PICO_FAULTY 20 | 21 | #define MEM_LIMIT (0) 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | extern uint32_t mm_failure_count; 31 | int pico_set_mm_failure(uint32_t nxt); 32 | extern uint32_t max_mem; 33 | extern uint32_t cur_mem; 34 | 35 | /* 36 | #define TIME_PRESCALE 37 | */ 38 | #define dbg printf 39 | 40 | #define stack_fill_pattern(...) do {} while(0) 41 | #define stack_count_free_words(...) do {} while(0) 42 | #define stack_get_free_words() (0) 43 | 44 | static inline void mem_stat_store(void) 45 | { 46 | char fname_mod[] = "/tmp/pico-mem-report-%hu.txt"; 47 | char fname[200]; 48 | char buffer[20]; 49 | int fd; 50 | snprintf(fname, 200, fname_mod, getpid()); 51 | fd = open(fname, O_WRONLY | O_CREAT | O_TRUNC, 0660); 52 | if (fd < 0) { 53 | return; 54 | } 55 | 56 | snprintf(buffer, 20, "%d\n", max_mem); 57 | write(fd, buffer, strlen(buffer)); 58 | close(fd); 59 | } 60 | 61 | 62 | static inline void *pico_zalloc(size_t x) 63 | { 64 | uint32_t *ptr; 65 | if (mm_failure_count > 0) { 66 | if (--mm_failure_count == 0) { 67 | fprintf(stderr, "Malloc failed, for test purposes\n"); 68 | return NULL; 69 | } 70 | } 71 | 72 | ptr = (uint32_t *)calloc(x + sizeof(uint32_t), 1); 73 | *ptr = (uint32_t)x; /* store size of alloc */ 74 | cur_mem += (uint32_t)x; 75 | 76 | #ifndef DISABLE_MM_STATS 77 | if (cur_mem > max_mem) { 78 | max_mem = cur_mem; 79 | if ((MEM_LIMIT > 0) && (max_mem > MEM_LIMIT)) 80 | abort(); 81 | 82 | mem_stat_store(); 83 | } 84 | 85 | #endif 86 | return (void*)(ptr + 1); 87 | } 88 | 89 | static inline void pico_free(void *x) 90 | { 91 | uint32_t *ptr = (uint32_t*)(((uint8_t *)x) - sizeof(uint32_t)); /* fetch size of the alloc */ 92 | cur_mem -= *ptr; 93 | free(ptr); 94 | } 95 | 96 | /* time prescaler */ 97 | #ifdef TIME_PRESCALE 98 | extern int32_t prescale_time; 99 | #endif 100 | 101 | static inline uint32_t PICO_TIME(void) 102 | { 103 | struct timeval t; 104 | gettimeofday(&t, NULL); 105 | #ifdef TIME_PRESCALE 106 | return (prescale_time < 0) ? (uint32_t)(t.tv_sec / 1000 << (-prescale_time)) : \ 107 | (uint32_t)(t.tv_sec / 1000 >> prescale_time); 108 | #else 109 | return (uint32_t)t.tv_sec; 110 | #endif 111 | } 112 | 113 | static inline uint32_t PICO_TIME_MS(void) 114 | { 115 | struct timeval t; 116 | gettimeofday(&t, NULL); 117 | #ifdef TIME_PRESCALER 118 | uint32_t tmp = ((t.tv_sec * 1000) + (t.tv_usec / 1000)); 119 | return (prescale_time < 0) ? (uint32_t)(tmp / 1000 << (-prescale_time)) : \ 120 | (uint32_t)(tmp / 1000 >> prescale_time); 121 | #else 122 | return (uint32_t)((t.tv_sec * 1000) + (t.tv_usec / 1000)); 123 | #endif 124 | } 125 | 126 | static inline void PICO_IDLE(void) 127 | { 128 | usleep(5000); 129 | } 130 | 131 | void memory_stats(void); 132 | 133 | #endif /* PICO_SUPPORT_POSIX */ 134 | 135 | -------------------------------------------------------------------------------- /include/pico_addressing.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved. 3 | See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage. 4 | 5 | *********************************************************************/ 6 | #ifndef INCLUDE_PICO_ADDRESSING 7 | #define INCLUDE_PICO_ADDRESSING 8 | 9 | #include "pico_config.h" 10 | #include "pico_constants.h" 11 | 12 | PACKED_STRUCT_DEF pico_ip4 13 | { 14 | uint32_t addr; 15 | }; 16 | 17 | PACKED_STRUCT_DEF pico_ip6 18 | { 19 | uint8_t addr[16]; 20 | }; 21 | 22 | union pico_address 23 | { 24 | struct pico_ip4 ip4; 25 | struct pico_ip6 ip6; 26 | }; 27 | 28 | /****************************************************************************** 29 | * Ethernet Address Definitions 30 | ******************************************************************************/ 31 | 32 | PACKED_STRUCT_DEF pico_eth 33 | { 34 | uint8_t addr[6]; 35 | uint8_t padding[2]; 36 | }; 37 | 38 | extern const uint8_t PICO_ETHADDR_ALL[]; 39 | 40 | /****************************************************************************** 41 | * Generic 6LoWPAN Address Definitions 42 | ******************************************************************************/ 43 | 44 | /* 6lowpan supports 16-bit short addresses */ 45 | PACKED_STRUCT_DEF pico_6lowpan_short 46 | { 47 | uint16_t addr; 48 | }; 49 | 50 | /* And also EUI-64 addresses */ 51 | PACKED_STRUCT_DEF pico_6lowpan_ext 52 | { 53 | uint8_t addr[8]; 54 | }; 55 | 56 | /* Address memory as either a short 16-bit address or a 64-bit address */ 57 | union pico_6lowpan_u 58 | { 59 | uint8_t data[8]; 60 | struct pico_6lowpan_short _short; 61 | struct pico_6lowpan_ext _ext; 62 | }; 63 | 64 | /* Info data structure to pass to pico_device_init by the device driver */ 65 | struct pico_6lowpan_info 66 | { 67 | struct pico_6lowpan_short addr_short; 68 | struct pico_6lowpan_ext addr_ext; 69 | struct pico_6lowpan_short pan_id; 70 | }; 71 | 72 | /* Different addressing modes for IEEE802.15.4 addresses */ 73 | #define AM_6LOWPAN_NONE (0u) 74 | #define AM_6LOWPAN_RES (1u) 75 | #define AM_6LOWPAN_SHORT (2u) 76 | #define AM_6LOWPAN_EXT (3u) 77 | #define SIZE_6LOWPAN_SHORT (2u) 78 | #define SIZE_6LOWPAN_EXT (8u) 79 | #define SIZE_6LOWPAN(m) (((m) == 2) ? (2) : (((m) == 3) ? (8) : (0))) 80 | 81 | /****************************************************************************** 82 | * Generic 6LoWPAN Address Definitions 83 | ******************************************************************************/ 84 | 85 | /* Storage data structure for IEEE802.15.4 addresses */ 86 | struct pico_802154 87 | { 88 | union pico_6lowpan_u addr; 89 | uint8_t mode; 90 | }; 91 | 92 | /****************************************************************************** 93 | * Link Layer addresses 94 | ******************************************************************************/ 95 | 96 | #define IID_16(iid) (0 == (iid)[2] && 0xff == (iid)[3] && 0xfe == (iid)[4] && 0 == (iid)[5]) 97 | 98 | enum pico_ll_mode 99 | { 100 | LL_MODE_ETHERNET = 0, 101 | #ifdef PICO_SUPPORT_802154 102 | LL_MODE_IEEE802154, 103 | #endif 104 | }; 105 | 106 | union pico_ll_addr 107 | { 108 | struct pico_eth eth; 109 | struct pico_802154 pan; 110 | }; 111 | 112 | PACKED_STRUCT_DEF pico_trans 113 | { 114 | uint16_t sport; 115 | uint16_t dport; 116 | }; 117 | 118 | /* Here are some protocols. */ 119 | #define PICO_PROTO_IPV4 0 120 | #define PICO_PROTO_ICMP4 1 121 | #define PICO_PROTO_IGMP 2 122 | #define PICO_PROTO_TCP 6 123 | #define PICO_PROTO_UDP 17 124 | #define PICO_PROTO_IPV6 41 125 | #define PICO_PROTO_ICMP6 58 126 | 127 | #endif 128 | --------------------------------------------------------------------------------