Porting PicoTCP WIP
This commit is contained in:
10
kernel/picotcp/test/Makefile
Normal file
10
kernel/picotcp/test/Makefile
Normal file
@@ -0,0 +1,10 @@
|
||||
CC=gcc
|
||||
CFLAGS=-ggdb -I../build/include/ -L../build/lib/ -lpicotcp -lvdeplug
|
||||
APPNAME=test_tftp_app_client
|
||||
|
||||
.PHONY: clean
|
||||
all: test_tftp_app_client
|
||||
test_tftp_app_client: test_tftp_app_client.o
|
||||
$(CC) -o test_tftp_app_client ../build/modules/pico_dev_vde.o $^ $(CFLAGS)
|
||||
clean:
|
||||
rm -f ${APPNAME}.o
|
||||
6
kernel/picotcp/test/README.md
Normal file
6
kernel/picotcp/test/README.md
Normal file
@@ -0,0 +1,6 @@
|
||||
To run these tests on your linux system, you will have to install these dependencies:
|
||||
* vde2
|
||||
* libvdeplug2-dev
|
||||
* libpcap0.8-dev
|
||||
|
||||
This will allow you to compile the 'make test' and run the tests
|
||||
360
kernel/picotcp/test/autotest.sh
Executable file
360
kernel/picotcp/test/autotest.sh
Executable file
@@ -0,0 +1,360 @@
|
||||
#!/bin/bash
|
||||
|
||||
TFTP_EXEC_DIR="$(pwd)/build/test"
|
||||
TFTP_WORK_DIR="${TFTP_EXEC_DIR}/tmp"
|
||||
TFTP_WORK_SUBDIR="${TFTP_WORK_DIR}/subdir"
|
||||
TFTP_WORK_FILE="test.img"
|
||||
|
||||
|
||||
|
||||
function tftp_setup() {
|
||||
dd if=/dev/urandom bs=1000 count=10 of=${1}/$TFTP_WORK_FILE
|
||||
}
|
||||
|
||||
function tftp_cleanup() {
|
||||
echo CLEANUP
|
||||
pwd;ls
|
||||
killall -wq picoapp.elf
|
||||
rm -rf $TFTP_WORK_DIR
|
||||
if [ $1 ]; then
|
||||
exit $1
|
||||
fi
|
||||
}
|
||||
|
||||
if ! [ -x "$(command -v vde_switch)" ]; then
|
||||
echo 'VDE Switch is not installed.' >&2
|
||||
fi
|
||||
|
||||
if [ ! -e test/vde_sock_start_user.sh ]; then
|
||||
echo "VDE SOCK START FILE NOT FOUND. NO VDE SETUP. EXITING"
|
||||
exit 1
|
||||
else
|
||||
echo "VDE SOCK START SCRIPT STARTED."
|
||||
./test/vde_sock_start_user.sh
|
||||
fi
|
||||
|
||||
rm -f /tmp/pico-mem-report-*
|
||||
sleep 2
|
||||
ulimit -c unlimited
|
||||
killall -wq picoapp.elf
|
||||
killall -wq picoapp6.elf
|
||||
|
||||
|
||||
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
echo "~~~ 6LoWPAN PING 1HOP (1500B) ~~~"
|
||||
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
(build/test/picoapp6.elf -6 0,0,0) &
|
||||
pids="$! "
|
||||
sleep 1
|
||||
(build/test/picoapp6.elf -6 1,2,1 -a noop) &
|
||||
pids+="$! "
|
||||
sleep 1
|
||||
build/test/picoapp6.elf -6 2,1,0 -a ping,2aaa:abcd:0000:0000:0200:00aa:ab00:0001,1500,0,1 || exit 1
|
||||
#TODO roll out this check for all "daemon" processes
|
||||
for pid in $pids; do ps -o pid= -p $pid || exit 1; done # check whether daemon processes didn't die from e.g. ASAN
|
||||
killall -w picoapp6.elf -s SIGQUIT
|
||||
|
||||
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
echo "~~~ 6LoWPAN UDP 1HOP (1400B) ~~~"
|
||||
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
#TODO are these "daemon" processes that need to be killed, or are they intended to halt on their own, giving a status code?
|
||||
(build/test/picoapp6.elf -6 0,0,0) &
|
||||
sleep 1
|
||||
(build/test/picoapp6.elf -6 1,2,1 -a udpecho,::0,6667,) &
|
||||
sleep 1
|
||||
build/test/picoapp6.elf -6 2,1,0 -a udpclient,2aaa:abcd:0000:0000:0200:00aa:ab00:0001,6667,6667,1400,10,1, || exit 1
|
||||
killall -w picoapp6.elf -s SIGQUIT
|
||||
|
||||
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
echo "~~~ MULTICAST6 TEST ~~~"
|
||||
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
(./build/test/picoapp6.elf --vde pic1,/tmp/pic0.ctl,aaaa::2,ffff::, -a mcastreceive_ipv6,aaaa::2,ff00::e007:707,6667,6667,) &
|
||||
(./build/test/picoapp6.elf --vde pic2,/tmp/pic0.ctl,aaaa::3,ffff::, -a mcastreceive_ipv6,aaaa::3,ff00::e007:707,6667,6667,) &
|
||||
(./build/test/picoapp6.elf --vde pic3,/tmp/pic0.ctl,aaaa::4,ffff::, -a mcastreceive_ipv6,aaaa::4,ff00::e007:707,6667,6667,) &
|
||||
sleep 2
|
||||
./build/test/picoapp6.elf --vde pic0,/tmp/pic0.ctl,aaaa::1,ffff::, -a mcastsend_ipv6,aaaa::1,ff00::e007:707,6667,6667,|| exit 1
|
||||
killall -w picoapp6.elf -s SIGQUIT
|
||||
|
||||
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
echo "~~~ PING6 LOCALHOST TEST ~~~"
|
||||
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
./build/test/picoapp6.elf --loop -a ping,::1,,,, || exit 1
|
||||
killall -w picoapp6.elf
|
||||
|
||||
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
echo "~~~ PING6 TEST ~~~"
|
||||
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
(./build/test/picoapp6.elf --vde pic0,/tmp/pic0.ctl,aaaa::1,ffff::,,,,) &
|
||||
./build/test/picoapp6.elf --vde pic0,/tmp/pic0.ctl,aaaa::2,ffff::,,, -a ping,aaaa::1,,,, || exit 1
|
||||
killall -w picoapp6.elf
|
||||
|
||||
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
echo "~~~ PING6 TEST (aborted in 4 seconds...) ~~~"
|
||||
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
(./build/test/picoapp6.elf --vde pic0,/tmp/pic0.ctl,aaaa::1,ffff::,,,,) &
|
||||
(./build/test/picoapp6.elf --vde pic0,/tmp/pic0.ctl,aaaa::2,ffff::,,, -a ping,aaaa::1,64,4,,) &
|
||||
sleep 7
|
||||
killall -w picoapp6.elf
|
||||
|
||||
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
echo "~~~ TCP6 TEST ~~~"
|
||||
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
(./build/test/picoapp6.elf --vde pic0,/tmp/pic0.ctl,aaaa::1,ffff::,,, -a tcpbench,r,6667,,) &
|
||||
./build/test/picoapp6.elf --vde pic0,/tmp/pic0.ctl,aaaa::2,ffff::,,, -a tcpbench,t,aaaa::1,6667,, || exit 1
|
||||
killall -w picoapp6.elf
|
||||
|
||||
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
echo "~~~ TCP6 TEST (with 2% packet loss on both directions) ~~~"
|
||||
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
(./build/test/picoapp6.elf --vde pic0,/tmp/pic0.ctl,aaaa::1,ffff::,,2,2, -a tcpbench,r,6667,,) &
|
||||
./build/test/picoapp6.elf --vde pic0,/tmp/pic0.ctl,aaaa::2,ffff::,,, -a tcpbench,t,aaaa::1,6667,, || exit 1
|
||||
killall -w picoapp6.elf
|
||||
|
||||
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
echo "~~~ TCP6 TEST (nagle) ~~~"
|
||||
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
(./build/test/picoapp6.elf --vde pic0,/tmp/pic0.ctl,aaaa::1,ffff::,,, -a tcpbench,r,6667,n,) &
|
||||
./build/test/picoapp6.elf --vde pic0,/tmp/pic0.ctl,aaaa::2,ffff::,,, -a tcpbench,t,aaaa::1,6667,n, || exit 1
|
||||
killall -w picoapp6.elf
|
||||
|
||||
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
echo "~~~ UDP6 TEST ~~~"
|
||||
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
(./build/test/picoapp6.elf --vde pic0,/tmp/pic0.ctl,aaaa::1,ffff::,,, -a udpecho,::0,6667,) &
|
||||
pids="$! "
|
||||
./build/test/picoapp6.elf --vde pic0,/tmp/pic0.ctl,aaaa::2,ffff::,,, -a udpclient,aaaa::1,6667,6667,1400,100,10, || exit 1
|
||||
wait $pids || exit 1
|
||||
killall -w picoapp6.elf
|
||||
|
||||
echo
|
||||
echo
|
||||
echo
|
||||
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
echo "~~~ IPV6 FWD TCP TEST ~~~"
|
||||
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
(./build/test/picoapp6.elf --vde pic0,/tmp/pic1.ctl,2001:aabb::2,ffff:ffff::,2001:aabb::ff,, -a tcpbench,r,6667,,) &
|
||||
(./build/test/picoapp6.elf --vde pic0,/tmp/pic0.ctl,2001:aaaa::ff,ffff:ffff::,,, --vde pic1,/tmp/pic1.ctl,2001:aabb::ff,ffff:ffff::,,, -a noop,) &
|
||||
./build/test/picoapp6.elf --vde pic0,/tmp/pic0.ctl,2001:aaaa::1,ffff:ffff::,2001:aaaa::ff,, -a tcpbench,t,2001:aabb::2,6667,, || exit 1
|
||||
sleep 2
|
||||
killall -w picoapp6.elf
|
||||
|
||||
|
||||
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
echo "~~~ MULTICAST TEST ~~~"
|
||||
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
(./build/test/picoapp.elf --vde pic1:/tmp/pic0.ctl:10.40.0.3:255.255.0.0: -a mcastreceive:10.40.0.3:224.7.7.7:6667:6667:) &
|
||||
(./build/test/picoapp.elf --vde pic2:/tmp/pic0.ctl:10.40.0.4:255.255.0.0: -a mcastreceive:10.40.0.4:224.7.7.7:6667:6667:) &
|
||||
(./build/test/picoapp.elf --vde pic3:/tmp/pic0.ctl:10.40.0.5:255.255.0.0: -a mcastreceive:10.40.0.5:224.7.7.7:6667:6667:) &
|
||||
sleep 2
|
||||
./build/test/picoapp.elf --vde pic0:/tmp/pic0.ctl:10.40.0.2:255.255.0.0: -a mcastsend:10.40.0.2:224.7.7.7:6667:6667: || exit 1
|
||||
killall -w picoapp.elf
|
||||
|
||||
echo
|
||||
echo
|
||||
echo
|
||||
echo
|
||||
echo
|
||||
|
||||
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
echo "~~~ IPV4 tests! ~~~"
|
||||
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
|
||||
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
echo "~~~ PING LOCALHOST TEST ~~~"
|
||||
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
./build/test/picoapp.elf --loop -a ping:127.0.0.1:::: || exit 1
|
||||
|
||||
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
echo "~~~ PING TEST ~~~"
|
||||
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
(./build/test/picoapp.elf --vde pic0:/tmp/pic0.ctl:10.40.0.8:255.255.0.0:::) &
|
||||
./build/test/picoapp.elf --vde pic0:/tmp/pic0.ctl:10.40.0.9:255.255.0.0::: -a ping:10.40.0.8:::: || exit 1
|
||||
killall -w picoapp.elf
|
||||
|
||||
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
echo "~~~ PING TEST -- Aborted in 4 seconds ~~~"
|
||||
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
(./build/test/picoapp.elf --vde pic0:/tmp/pic0.ctl:10.40.0.8:255.255.0.0:::) &
|
||||
(./build/test/picoapp.elf --vde pic0:/tmp/pic0.ctl:10.40.0.9:255.255.0.0::: -a ping:10.40.0.8:64:4::) &
|
||||
sleep 7
|
||||
killall -w picoapp.elf
|
||||
|
||||
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
echo "~~~ TCP TEST ~~~"
|
||||
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
(./build/test/picoapp.elf --vde pic0:/tmp/pic0.ctl:10.40.0.8:255.255.0.0:::: -a tcpbench:r:6667::) &
|
||||
./build/test/picoapp.elf --vde pic0:/tmp/pic0.ctl:10.40.0.9:255.255.0.0::: -a tcpbench:t:10.40.0.8:6667:: || exit 1
|
||||
killall -w picoapp.elf
|
||||
|
||||
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
echo "~~~ TCP TEST (with global route) ~~~"
|
||||
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
(./build/test/picoapp.elf --vde pic0:/tmp/pic0.ctl:10.40.0.8:255.255.0.0:::: --vde pic1:/tmp/pic1.ctl:10.50.0.10:255.255.0.0:10.50.0.1: -a tcpbench:r:6667::) &
|
||||
./build/test/picoapp.elf --vde pic0:/tmp/pic0.ctl:10.40.0.9:255.255.0.0::: -a tcpbench:t:10.40.0.8:6667:: || exit 1
|
||||
killall -w picoapp.elf
|
||||
|
||||
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
echo "~~~ TCP TEST (with 2% packet loss on both directions) ~~~"
|
||||
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
(./build/test/picoapp.elf --vde pic0:/tmp/pic0.ctl:10.40.0.8:255.255.0.0::2:2: -a tcpbench:r:6667::) &
|
||||
./build/test/picoapp.elf --vde pic0:/tmp/pic0.ctl:10.40.0.9:255.255.0.0::: -a tcpbench:t:10.40.0.8:6667:: || exit 1
|
||||
killall -w picoapp.elf
|
||||
|
||||
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
echo "~~~ TCP TEST (nagle) ~~~"
|
||||
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
(./build/test/picoapp.elf --vde pic0:/tmp/pic0.ctl:10.40.0.8:255.255.0.0::: -a tcpbench:r:6667:n:) &
|
||||
./build/test/picoapp.elf --vde pic0:/tmp/pic0.ctl:10.40.0.9:255.255.0.0::: -a tcpbench:t:10.40.0.8:6667:n: || exit 1
|
||||
killall -w picoapp.elf
|
||||
|
||||
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
echo "~~~ UDP TEST ~~~"
|
||||
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
(./build/test/picoapp.elf --vde pic0:/tmp/pic0.ctl:10.40.0.8:255.255.0.0::: -a udpecho:10.40.0.8:6667:) &
|
||||
pids="$! "
|
||||
./build/test/picoapp.elf --vde pic0:/tmp/pic0.ctl:10.40.0.9:255.255.0.0::: -a udpclient:10.40.0.8:6667:6667:1400:100:10: || exit 1
|
||||
wait $pids || exit 1
|
||||
|
||||
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
echo "~~~ UDP TEST with fragmentation ~~~"
|
||||
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
(./build/test/picoapp.elf --vde pic0:/tmp/pic0.ctl:10.40.0.8:255.255.0.0::: -a udpecho:10.40.0.8:6667:) &
|
||||
pids="$! "
|
||||
./build/test/picoapp.elf --vde pic0:/tmp/pic0.ctl:10.40.0.9:255.255.0.0::: -a udpclient:10.40.0.8:6667:6667:4500:100:10: || exit 1
|
||||
wait $pids || exit 1
|
||||
|
||||
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
echo "~~~ NAT TCP TEST ~~~"
|
||||
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
(./build/test/picoapp.elf --vde pic0:/tmp/pic0.ctl:10.40.0.10:255.255.0.0::: --vde pic1:/tmp/pic1.ctl:10.50.0.10:255.255.0.0: -a natbox:10.50.0.10) &
|
||||
sleep 2
|
||||
(./build/test/picoapp.elf --vde pic0:/tmp/pic1.ctl:10.50.0.8:255.255.0.0::: -a tcpbench:r:6667:) &
|
||||
sleep 2
|
||||
./build/test/picoapp.elf --vde pic0:/tmp/pic0.ctl:10.40.0.9:255.255.0.0:10.40.0.10::: -a tcpbench:t:10.50.0.8:6667: || exit 1
|
||||
killall -w picoapp.elf
|
||||
|
||||
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
echo "~~~ NAT UDP TEST ~~~"
|
||||
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
(./build/test/picoapp.elf --vde pic0:/tmp/pic0.ctl:10.40.0.10:255.255.0.0::: --vde pic1:/tmp/pic1.ctl:10.50.0.10:255.255.0.0::: -a natbox:10.50.0.10) &
|
||||
(./build/test/picoapp.elf --vde pic0:/tmp/pic1.ctl:10.50.0.8:255.255.0.0::: -a udpecho:10.50.0.8:6667:) &
|
||||
./build/test/picoapp.elf --vde pic0:/tmp/pic0.ctl:10.40.0.9:255.255.0.0:10.40.0.10::: -a udpclient:10.50.0.8:6667:6667:1400:100:10: || exit 1
|
||||
#sometimes udpecho finishes before reaching wait %2
|
||||
#wait %2
|
||||
killall -w picoapp.elf
|
||||
|
||||
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
echo "~~~ MULTICAST TEST ~~~"
|
||||
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
(./build/test/picoapp.elf --vde pic1:/tmp/pic0.ctl:10.40.0.3:255.255.0.0::: -a mcastreceive:10.40.0.3:224.7.7.7:6667:6667:) &
|
||||
(./build/test/picoapp.elf --vde pic2:/tmp/pic0.ctl:10.40.0.4:255.255.0.0::: -a mcastreceive:10.40.0.4:224.7.7.7:6667:6667:) &
|
||||
(./build/test/picoapp.elf --vde pic3:/tmp/pic0.ctl:10.40.0.5:255.255.0.0::: -a mcastreceive:10.40.0.5:224.7.7.7:6667:6667:) &
|
||||
sleep 2
|
||||
./build/test/picoapp.elf --vde pic0:/tmp/pic0.ctl:10.40.0.2:255.255.0.0::: -a mcastsend:10.40.0.2:224.7.7.7:6667:6667: || exit 1
|
||||
killall -w picoapp.elf
|
||||
|
||||
killall -w picoapp.elf
|
||||
|
||||
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
echo "~~~ DHCP TEST ~~~"
|
||||
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
(./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:) &
|
||||
./build/test/picoapp.elf --barevde pic0:/tmp/pic0.ctl: -a dhcpclient:pic0 || exit 1
|
||||
killall -w picoapp.elf
|
||||
|
||||
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
echo "~~~ DHCP DUAL TEST ~~~"
|
||||
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
(./build/test/picoapp.elf --vde pic0:/tmp/pic0.ctl:10.40.0.2:255.255.0.0::: -a dhcpserver:pic0:10.40.0.2:255.255.255.0:64:128:) &
|
||||
(./build/test/picoapp.elf --vde pic1:/tmp/pic1.ctl:10.50.0.2:255.255.0.0::: -a dhcpserver:pic1:10.50.0.2:255.255.255.0:64:128:) &
|
||||
./build/test/picoapp.elf --barevde pic0:/tmp/pic0.ctl: --barevde pic1:/tmp/pic1.ctl: -a dhcpclient:pic0:pic1: || exit 1
|
||||
killall -w picoapp.elf
|
||||
|
||||
#TO DO: the ping address 169.254.22.5 is hardcoded in the slaacv4 test. Nice to pass that by parameter
|
||||
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
echo "~~~ SLAACV4 TEST ~~~"
|
||||
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
(./build/test/picoapp.elf --vde pic0:/tmp/pic0.ctl:169.254.22.5:255.255.0.0:::) &
|
||||
./build/test/picoapp.elf --barevde pic0:/tmp/pic0.ctl: -a slaacv4:pic0 || exit 1
|
||||
killall -w picoapp.elf
|
||||
|
||||
|
||||
./build/test/picoapp.elf --vde pic0:/tmp/pic0.ctl:10.40.0.2:255.255.0.0:10.40.0.1::: -a udpdnsclient:www.google.be:173.194.67.94:: &
|
||||
./build/test/picoapp.elf --vde pic0:/tmp/pic0.ctl:10.40.0.2:255.255.0.0:10.40.0.1::: -a udpdnsclient:ipv6.google.be:doesntmatter:ipv6: &
|
||||
./build/test/picoapp.elf --vde pic0:/tmp/pic0.ctl:10.50.0.2:255.255.0.0:10.50.0.1::: -a sntp:0.europe.pool.ntp.org &
|
||||
sleep 20
|
||||
killall -w picoapp.elf
|
||||
|
||||
|
||||
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
echo "~~~ MDNS TEST ~~~"
|
||||
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
#retrieve a local mdns host name from the host
|
||||
(./build/test/picoapp.elf --vde pic0:/tmp/pic0.ctl:10.50.0.2:255.255.255.0:10.50.0.1: --app mdns:hostfoo.local:hostbar.local:) &
|
||||
(./build/test/picoapp.elf --vde pic0:/tmp/pic0.ctl:10.50.0.3:255.255.255.0:10.50.0.1: --app mdns:hostbar.local:hostfoo.local:) &
|
||||
(./build/test/picoapp.elf --vde pic0:/tmp/pic0.ctl:10.50.0.2:255.255.255.0:10.50.0.1: --app mdns:hostfoobar.local:nonexisting.local:) &
|
||||
sleep 10
|
||||
killall -w picoapp.elf
|
||||
|
||||
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
echo "~~~ DNS_SD TEST ~~~"
|
||||
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
#register a service
|
||||
(./build/test/picoapp.elf --vde pic0:/tmp/pic0.ctl:10.50.0.2:255.255.255.0:10.50.0.1: --app dns_sd:host.local:WebServer) &
|
||||
(./build/test/picoapp.elf --vde pic0:/tmp/pic0.ctl:10.50.0.3:255.255.255.0:10.50.0.1: --app dns_sd:host.local:WebServer) &
|
||||
sleep 30
|
||||
killall -w picoapp.elf
|
||||
|
||||
sleep 1
|
||||
sync
|
||||
|
||||
|
||||
# TFTP TEST BEGINS...
|
||||
|
||||
if [ ! -d $TFTP_WORK_DIR ]; then
|
||||
mkdir $TFTP_WORK_DIR || exit 1
|
||||
fi
|
||||
if [ ! -d ${TFTP_WORK_SUBDIR}/server ]; then
|
||||
mkdir $TFTP_WORK_SUBDIR || exit 1
|
||||
fi
|
||||
|
||||
pushd $TFTP_WORK_DIR
|
||||
|
||||
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
echo "~~~ TFTP GET TEST ~~~"
|
||||
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
tftp_setup $TFTP_WORK_DIR
|
||||
(${TFTP_EXEC_DIR}/picoapp.elf --vde pic0:/tmp/pic0.ctl:10.50.0.2:255.255.255.0:10.50.0.1: --app tftp:S:) &
|
||||
cd $TFTP_WORK_SUBDIR
|
||||
sleep 2
|
||||
${TFTP_EXEC_DIR}/picoapp.elf --vde pic0:/tmp/pic0.ctl:10.50.0.3:255.255.255.0:10.50.0.1: --app tftp:R:${TFTP_WORK_FILE}:10.50.0.2: || tftp_cleanup 1
|
||||
sleep 3
|
||||
killall -w picoapp.elf
|
||||
|
||||
sleep 1
|
||||
|
||||
rm $TFTP_WORK_FILE
|
||||
|
||||
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
echo "~~~ TFTP PUT TEST ~~~"
|
||||
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
(${TFTP_EXEC_DIR}/picoapp.elf --vde pic0:/tmp/pic0.ctl:10.50.0.2:255.255.255.0:10.50.0.1: --app tftp:S:) &
|
||||
cd $TFTP_WORK_DIR
|
||||
tftp_setup $TFTP_WORK_DIR
|
||||
sleep 2
|
||||
${TFTP_EXEC_DIR}/picoapp.elf --vde pic0:/tmp/pic0.ctl:10.50.0.3:255.255.255.0:10.50.0.1: --app tftp:T:${TFTP_WORK_FILE}:10.50.0.2: || tftp_cleanup 1
|
||||
sleep 3
|
||||
|
||||
tftp_cleanup
|
||||
popd
|
||||
# TFTP TEST ENDS.
|
||||
|
||||
MAXMEM=`cat /tmp/pico-mem-report-* | sort -r -n |head -1`
|
||||
echo
|
||||
echo
|
||||
echo
|
||||
echo "MAX memory used: $MAXMEM"
|
||||
rm -f /tmp/pico-mem-report-*
|
||||
|
||||
./test/vde_sock_start_user.sh stop
|
||||
echo "SUCCESS!"
|
||||
4
kernel/picotcp/test/coverage.sh
Executable file
4
kernel/picotcp/test/coverage.sh
Executable file
@@ -0,0 +1,4 @@
|
||||
#!/bin/bash
|
||||
./test/units.sh || exit 1
|
||||
./test/autotest.sh || exit 2
|
||||
exit 0
|
||||
12
kernel/picotcp/test/dummy.c
Normal file
12
kernel/picotcp/test/dummy.c
Normal file
@@ -0,0 +1,12 @@
|
||||
#include "pico_stack.h"
|
||||
|
||||
#if defined(PICO_SUPPORT_RTOS) || defined (PICO_SUPPORT_PTHREAD)
|
||||
volatile uint32_t pico_ms_tick;
|
||||
#endif
|
||||
|
||||
int main(void)
|
||||
{
|
||||
pico_stack_init();
|
||||
pico_stack_tick();
|
||||
return 0;
|
||||
}
|
||||
36
kernel/picotcp/test/examples/Makefile
Normal file
36
kernel/picotcp/test/examples/Makefile
Normal file
@@ -0,0 +1,36 @@
|
||||
PREFIX?=../../build
|
||||
CFLAGS+=-I../../include/ -I../../modules -I../../build/include -I . -ggdb
|
||||
|
||||
|
||||
$(PREFIX)/examples/%.o: %.c
|
||||
@mkdir -p $(PREFIX)/examples
|
||||
@echo -e "\t[CC] $@"
|
||||
@$(CC) -c $(CFLAGS) -o $@ $<
|
||||
|
||||
OBJS:= \
|
||||
$(PREFIX)/examples/dhcp_client.o \
|
||||
$(PREFIX)/examples/dhcp_server.o \
|
||||
$(PREFIX)/examples/dns_sd.o \
|
||||
$(PREFIX)/examples/dnsclient.o \
|
||||
$(PREFIX)/examples/mdns.o \
|
||||
$(PREFIX)/examples/multicast_recv.o \
|
||||
$(PREFIX)/examples/multicast_ip6_recv.o \
|
||||
$(PREFIX)/examples/multicast_send.o \
|
||||
$(PREFIX)/examples/multicast_ip6_send.o \
|
||||
$(PREFIX)/examples/natbox.o \
|
||||
$(PREFIX)/examples/noop.o \
|
||||
$(PREFIX)/examples/ping.o \
|
||||
$(PREFIX)/examples/slaacv4.o \
|
||||
$(PREFIX)/examples/sntp.o \
|
||||
$(PREFIX)/examples/tcpbench.o \
|
||||
$(PREFIX)/examples/tcpclient.o \
|
||||
$(PREFIX)/examples/tcpecho.o \
|
||||
$(PREFIX)/examples/tftp.o \
|
||||
$(PREFIX)/examples/udp_client.o \
|
||||
$(PREFIX)/examples/udp_echo.o \
|
||||
$(PREFIX)/examples/udpnat.o \
|
||||
$(PREFIX)/examples/udp_sendto_test.o \
|
||||
$(PREFIX)/examples/iperfc.o \
|
||||
|
||||
|
||||
all: $(OBJS)
|
||||
114
kernel/picotcp/test/examples/dhcp_client.c
Normal file
114
kernel/picotcp/test/examples/dhcp_client.c
Normal file
@@ -0,0 +1,114 @@
|
||||
#include "utils.h"
|
||||
#include <pico_ipv4.h>
|
||||
#include <pico_dhcp_client.h>
|
||||
#include <pico_socket.h>
|
||||
#include <pico_icmp4.h>
|
||||
#include <pico_device.h>
|
||||
/*** START DHCP Client ***/
|
||||
#ifdef PICO_SUPPORT_DHCPC
|
||||
|
||||
/* This must stay global, its lifetime is the same as the dhcp negotiation */
|
||||
uint32_t dhcpclient_xid;
|
||||
|
||||
|
||||
static uint8_t dhcpclient_devices = 0;
|
||||
|
||||
void ping_callback_dhcpclient(struct pico_icmp4_stats *s)
|
||||
{
|
||||
char host[30] = { };
|
||||
|
||||
pico_ipv4_to_string(host, s->dst.addr);
|
||||
if (s->err == 0) {
|
||||
dbg("DHCP client: %lu bytes from %s: icmp_req=%lu ttl=64 time=%lu ms\n",
|
||||
s->size, host, s->seq, (long unsigned int)s->time);
|
||||
if (s->seq >= 3) {
|
||||
dbg("DHCP client: TEST SUCCESS!\n");
|
||||
if (--dhcpclient_devices <= 0)
|
||||
exit(0);
|
||||
}
|
||||
} else {
|
||||
dbg("DHCP client: ping %lu to %s error %d\n", s->seq, host, s->err);
|
||||
dbg("DHCP client: TEST FAILED!\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
void callback_dhcpclient(void *arg, int code)
|
||||
{
|
||||
struct pico_ip4 address = ZERO_IP4, gateway = ZERO_IP4;
|
||||
char s_address[16] = { }, s_gateway[16] = { };
|
||||
|
||||
printf("DHCP client: callback happened with code %d!\n", code);
|
||||
if (code == PICO_DHCP_SUCCESS) {
|
||||
address = pico_dhcp_get_address(arg);
|
||||
gateway = pico_dhcp_get_gateway(arg);
|
||||
pico_ipv4_to_string(s_address, address.addr);
|
||||
pico_ipv4_to_string(s_gateway, gateway.addr);
|
||||
printf("DHCP client: got IP %s assigned with cli %p\n", s_address, arg);
|
||||
#ifdef PICO_SUPPORT_PING
|
||||
pico_icmp4_ping(s_gateway, 3, 1000, 5000, 32, ping_callback_dhcpclient);
|
||||
/* optional test to check routing when links get added and deleted */
|
||||
/* do {
|
||||
char *new_arg = NULL, *p = NULL;
|
||||
new_arg = calloc(1, strlen(s_address) + strlen(":224.7.7.7:6667:6667") + 1);
|
||||
p = strcat(new_arg, s_address);
|
||||
p = strcat(p + strlen(s_address), ":224.7.7.7:6667:6667");
|
||||
app_mcastsend(new_arg);
|
||||
} while (0);
|
||||
*/
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void app_dhcp_client(char *arg)
|
||||
{
|
||||
char *sdev = NULL;
|
||||
char *nxt = arg;
|
||||
struct pico_device *dev = NULL;
|
||||
|
||||
if (!nxt)
|
||||
goto out;
|
||||
|
||||
while (nxt) {
|
||||
if (nxt) {
|
||||
nxt = cpy_arg(&sdev, nxt);
|
||||
if(!sdev) {
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
dev = pico_get_device(sdev);
|
||||
if(dev == NULL) {
|
||||
if (sdev)
|
||||
free(sdev);
|
||||
|
||||
printf("%s: error getting device %s: %s\n", __FUNCTION__, dev->name, strerror(pico_err));
|
||||
exit(255);
|
||||
}
|
||||
|
||||
printf("Starting negotiation\n");
|
||||
|
||||
if (pico_dhcp_initiate_negotiation(dev, &callback_dhcpclient, &dhcpclient_xid) < 0) {
|
||||
printf("%s: error initiating negotiation: %s\n", __FUNCTION__, strerror(pico_err));
|
||||
if (sdev)
|
||||
free(sdev);
|
||||
|
||||
exit(255);
|
||||
}
|
||||
|
||||
if (sdev)
|
||||
free(sdev);
|
||||
|
||||
dhcpclient_devices++;
|
||||
}
|
||||
return;
|
||||
|
||||
out:
|
||||
fprintf(stderr, "dhcpclient expects the following format: dhcpclient:dev_name:[dev_name]\n");
|
||||
if (sdev)
|
||||
free(sdev);
|
||||
|
||||
exit(255);
|
||||
}
|
||||
#endif
|
||||
/*** END DHCP Client ***/
|
||||
99
kernel/picotcp/test/examples/dhcp_server.c
Normal file
99
kernel/picotcp/test/examples/dhcp_server.c
Normal file
@@ -0,0 +1,99 @@
|
||||
#include "utils.h"
|
||||
#include <pico_ipv4.h>
|
||||
#include <pico_device.h>
|
||||
#include <pico_dhcp_server.h>
|
||||
|
||||
/*** START DHCP Server ***/
|
||||
#ifdef PICO_SUPPORT_DHCPD
|
||||
/* ./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
|
||||
* ./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: \
|
||||
* -a dhcpserver:pic0:10.40.0.10:255.255.255.0:64:128:pic1:10.50.0.10:255.255.255.0:64:128
|
||||
*/
|
||||
void app_dhcp_server(char *arg)
|
||||
{
|
||||
struct pico_device *dev = NULL;
|
||||
struct pico_dhcp_server_setting s = {
|
||||
0
|
||||
};
|
||||
int pool_start = 0, pool_end = 0;
|
||||
char *s_name = NULL, *s_addr = NULL, *s_netm = NULL, *s_pool_start = NULL, *s_pool_end = NULL;
|
||||
char *nxt = arg;
|
||||
|
||||
if (!nxt)
|
||||
goto out;
|
||||
|
||||
while (nxt) {
|
||||
if (nxt) {
|
||||
nxt = cpy_arg(&s_name, nxt);
|
||||
if (!s_name) {
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (nxt) {
|
||||
nxt = cpy_arg(&s_addr, nxt);
|
||||
if (s_addr) {
|
||||
pico_string_to_ipv4(s_addr, &s.server_ip.addr);
|
||||
} else {
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (nxt) {
|
||||
nxt = cpy_arg(&s_netm, nxt);
|
||||
if (s_netm) {
|
||||
pico_string_to_ipv4(s_netm, &s.netmask.addr);
|
||||
} else {
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (nxt) {
|
||||
nxt = cpy_arg(&s_pool_start, nxt);
|
||||
if (s_pool_start && atoi(s_pool_start)) {
|
||||
pool_start = atoi(s_pool_start);
|
||||
} else {
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (nxt) {
|
||||
nxt = cpy_arg(&s_pool_end, nxt);
|
||||
if (s_pool_end && atoi(s_pool_end)) {
|
||||
pool_end = atoi(s_pool_end);
|
||||
} else {
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
goto out;
|
||||
}
|
||||
|
||||
dev = (struct pico_device *)pico_get_device(s_name);
|
||||
if (dev == NULL) {
|
||||
fprintf(stderr, "No device with name %s found\n", s_name);
|
||||
exit(255);
|
||||
}
|
||||
|
||||
s.dev = dev;
|
||||
s.pool_start = (s.server_ip.addr & s.netmask.addr) | long_be(pool_start);
|
||||
s.pool_end = (s.server_ip.addr & s.netmask.addr) | long_be(pool_end);
|
||||
|
||||
pico_dhcp_server_initiate(&s);
|
||||
}
|
||||
return;
|
||||
|
||||
out:
|
||||
fprintf(stderr, "dhcpserver expects the following format: dhcpserver:dev_name:dev_addr:dev_netm:pool_start:pool_end\n");
|
||||
exit(255);
|
||||
|
||||
}
|
||||
#endif
|
||||
/*** END DHCP Server ***/
|
||||
112
kernel/picotcp/test/examples/dns_sd.c
Normal file
112
kernel/picotcp/test/examples/dns_sd.c
Normal file
@@ -0,0 +1,112 @@
|
||||
#include "utils.h"
|
||||
#include <pico_dns_sd.h>
|
||||
#include <pico_ipv4.h>
|
||||
#include <pico_addressing.h>
|
||||
#include <pico_device.h>
|
||||
#include <pico_ipv4.h>
|
||||
|
||||
/*** START DNS_SD ***/
|
||||
#ifdef PICO_SUPPORT_DNS_SD
|
||||
|
||||
#define TTL 30
|
||||
#define SECONDS 10
|
||||
|
||||
static int fully_initialized = 0;
|
||||
static char *service_name = NULL;
|
||||
|
||||
void dns_sd_claimed_callback( pico_mdns_rtree *tree,
|
||||
char *str,
|
||||
void *arg )
|
||||
{
|
||||
printf("DONE - Registering DNS-SD Service\n");
|
||||
|
||||
IGNORE_PARAMETER(tree);
|
||||
IGNORE_PARAMETER(str);
|
||||
IGNORE_PARAMETER(arg);
|
||||
}
|
||||
|
||||
void dns_sd_init_callback( pico_mdns_rtree *tree,
|
||||
char *str,
|
||||
void *arg )
|
||||
{
|
||||
PICO_DNS_SD_KV_VECTOR_DECLARE(key_value_pair_vector);
|
||||
|
||||
IGNORE_PARAMETER(str);
|
||||
IGNORE_PARAMETER(arg);
|
||||
IGNORE_PARAMETER(tree);
|
||||
|
||||
pico_dns_sd_kv_vector_add(&key_value_pair_vector, "key", "value");
|
||||
|
||||
printf("DONE - Initialising DNS Service Discovery module.\n");
|
||||
|
||||
if (pico_dns_sd_register_service(service_name,
|
||||
"_http._tcp", 80,
|
||||
&key_value_pair_vector,
|
||||
TTL, dns_sd_claimed_callback, NULL) < 0) {
|
||||
printf("Registering service failed!\n");
|
||||
}
|
||||
|
||||
fully_initialized = 1;
|
||||
}
|
||||
|
||||
void app_dns_sd(char *arg, struct pico_ip4 address)
|
||||
{
|
||||
char *hostname;
|
||||
char *nxt = arg;
|
||||
uint64_t starttime = 0;
|
||||
int once = 0;
|
||||
|
||||
if (!nxt) {
|
||||
exit(255);
|
||||
}
|
||||
|
||||
nxt = cpy_arg(&hostname, nxt);
|
||||
if(!hostname) {
|
||||
exit(255);
|
||||
}
|
||||
|
||||
if(!nxt) {
|
||||
printf("Not enough args supplied!\n");
|
||||
exit(255);
|
||||
}
|
||||
|
||||
nxt = cpy_arg(&service_name, nxt);
|
||||
if(!service_name) {
|
||||
exit(255);
|
||||
}
|
||||
|
||||
printf("\nStarting DNS Service Discovery module...\n");
|
||||
if (pico_dns_sd_init(hostname, address, &dns_sd_init_callback, NULL) != 0) {
|
||||
printf("Initialisation returned with Error!\n");
|
||||
exit(255);
|
||||
}
|
||||
|
||||
printf("\nTry reinitialising DNS-SD\n");
|
||||
if (pico_dns_sd_init(hostname, address, &dns_sd_init_callback, NULL)) {
|
||||
printf("Initialisation returned with Error!\n");
|
||||
exit(255);
|
||||
}
|
||||
|
||||
printf("DONE - Re-initialising DNS-SD module.\n");
|
||||
|
||||
starttime = PICO_TIME_MS();
|
||||
printf("Starting time: %d\n", starttime);
|
||||
|
||||
while(1) {
|
||||
pico_stack_tick();
|
||||
usleep(2000);
|
||||
|
||||
if (((PICO_TIME_MS() - starttime) > SECONDS * 1000) && fully_initialized && !once) {
|
||||
printf("\nTry reinitialising DNS-SD (a second time)\n");
|
||||
if (pico_dns_sd_init(hostname, address, &dns_sd_init_callback, NULL)) {
|
||||
printf("Initialisation returned with Error!\n");
|
||||
exit(255);
|
||||
}
|
||||
once = 1;
|
||||
printf("DONE - Re-initialising mDNS module. (a second time)\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
/*** END DNS_SD ***/
|
||||
120
kernel/picotcp/test/examples/dnsclient.c
Normal file
120
kernel/picotcp/test/examples/dnsclient.c
Normal file
@@ -0,0 +1,120 @@
|
||||
#include <stdint.h>
|
||||
#include <pico_stack.h>
|
||||
#include <pico_ipv4.h>
|
||||
#include <pico_dns_client.h>
|
||||
#include "utils.h"
|
||||
extern int IPV6_MODE;
|
||||
|
||||
/*** START UDP DNS CLIENT ***/
|
||||
/*
|
||||
./test/vde_sock_start.sh
|
||||
echo 1 > /proc/sys/net/ipv4/ip_forward
|
||||
iptables -t nat -A POSTROUTING -o wlan0 -j MASQUERADE
|
||||
iptables -A FORWARD -i pic0 -o wlan0 -j ACCEPT
|
||||
iptables -A FORWARD -i wlan0 -o pic0 -j ACCEPT
|
||||
./build/test/picoapp.elf --vde pic0:/tmp/pic0.ctl:10.40.0.2:255.255.0.0:10.40.0.1: -a udpdnsclient:www.google.be:173.194.67.94
|
||||
*/
|
||||
void cb_udpdnsclient_getaddr(char *ip, void *arg)
|
||||
{
|
||||
uint8_t *id = (uint8_t *) arg;
|
||||
|
||||
if (!ip) {
|
||||
picoapp_dbg("%s: ERROR occured! (id: %u)\n", __FUNCTION__, *id);
|
||||
return;
|
||||
}
|
||||
|
||||
picoapp_dbg("%s: ip %s (id: %u)\n", __FUNCTION__, ip, *id);
|
||||
if (arg)
|
||||
PICO_FREE(arg);
|
||||
}
|
||||
|
||||
void cb_udpdnsclient_getname(char *name, void *arg)
|
||||
{
|
||||
uint8_t *id = (uint8_t *) arg;
|
||||
|
||||
if (!name) {
|
||||
picoapp_dbg("%s: ERROR occured! (id: %u)\n", __FUNCTION__, *id);
|
||||
return;
|
||||
}
|
||||
|
||||
picoapp_dbg("%s: name %s (id: %u)\n", __FUNCTION__, name, *id);
|
||||
if (arg)
|
||||
PICO_FREE(arg);
|
||||
}
|
||||
|
||||
void app_udpdnsclient(char *arg)
|
||||
{
|
||||
struct pico_ip4 nameserver;
|
||||
char *dname, *daddr;
|
||||
char *nxt;
|
||||
char *ipver;
|
||||
int v = 4;
|
||||
uint8_t *getaddr_id, *getname_id, *getaddr6_id, *getname6_id;
|
||||
|
||||
nxt = cpy_arg(&dname, arg);
|
||||
if (!dname || !nxt) {
|
||||
picoapp_dbg(" udpdnsclient expects the following format: udpdnsclient:dest_name:dest_ip:[ipv6]\n");
|
||||
exit(255);
|
||||
}
|
||||
|
||||
nxt = cpy_arg(&daddr, nxt);
|
||||
if (!daddr || !nxt) {
|
||||
picoapp_dbg(" udpdnsclient expects the following format: udpdnsclient:dest_name:dest_ip:[ipv6]\n");
|
||||
exit(255);
|
||||
}
|
||||
|
||||
nxt = cpy_arg(&ipver, nxt);
|
||||
if (!ipver || strcmp("ipv6", ipver) != 0)
|
||||
v = 4;
|
||||
else
|
||||
v = 6;
|
||||
|
||||
picoapp_dbg("UDP DNS client started.\n");
|
||||
|
||||
picoapp_dbg("----- Deleting non existant nameserver -----\n");
|
||||
pico_string_to_ipv4("127.0.0.1", &nameserver.addr);
|
||||
pico_dns_client_nameserver(&nameserver, PICO_DNS_NS_DEL);
|
||||
picoapp_dbg("----- Adding 8.8.8.8 nameserver -----\n");
|
||||
pico_string_to_ipv4("8.8.8.8", &nameserver.addr);
|
||||
pico_dns_client_nameserver(&nameserver, PICO_DNS_NS_ADD);
|
||||
picoapp_dbg("----- Deleting 8.8.8.8 nameserver -----\n");
|
||||
pico_string_to_ipv4("8.8.8.8", &nameserver.addr);
|
||||
pico_dns_client_nameserver(&nameserver, PICO_DNS_NS_DEL);
|
||||
picoapp_dbg("----- Adding 8.8.8.8 nameserver -----\n");
|
||||
pico_string_to_ipv4("8.8.8.8", &nameserver.addr);
|
||||
pico_dns_client_nameserver(&nameserver, PICO_DNS_NS_ADD);
|
||||
picoapp_dbg("----- Adding 8.8.4.4 nameserver -----\n");
|
||||
pico_string_to_ipv4("8.8.4.4", &nameserver.addr);
|
||||
pico_dns_client_nameserver(&nameserver, PICO_DNS_NS_ADD);
|
||||
if (!IPV6_MODE) {
|
||||
if (v == 4) {
|
||||
picoapp_dbg("Mode: IPv4\n");
|
||||
getaddr_id = calloc(1, sizeof(uint8_t));
|
||||
*getaddr_id = 1;
|
||||
picoapp_dbg(">>>>> DNS GET ADDR OF %s\n", dname);
|
||||
pico_dns_client_getaddr(dname, &cb_udpdnsclient_getaddr, getaddr_id);
|
||||
|
||||
getname_id = calloc(1, sizeof(uint8_t));
|
||||
*getname_id = 2;
|
||||
picoapp_dbg(">>>>> DNS GET NAME OF %s\n", daddr);
|
||||
pico_dns_client_getname(daddr, &cb_udpdnsclient_getname, getname_id);
|
||||
return;
|
||||
}
|
||||
|
||||
picoapp_dbg("Mode: IPv6\n");
|
||||
|
||||
#ifdef PICO_SUPPORT_IPV6
|
||||
getaddr6_id = calloc(1, sizeof(uint8_t));
|
||||
*getaddr6_id = 3;
|
||||
picoapp_dbg(">>>>> DNS GET ADDR6 OF %s\n", dname);
|
||||
pico_dns_client_getaddr6(dname, &cb_udpdnsclient_getaddr, getaddr6_id);
|
||||
getname6_id = calloc(1, sizeof(uint8_t));
|
||||
*getname6_id = 4;
|
||||
picoapp_dbg(">>>>> DNS GET NAME OF ipv6 addr 2a00:1450:400c:c06::64\n");
|
||||
pico_dns_client_getname6("2a00:1450:400c:c06::64", &cb_udpdnsclient_getname, getname6_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
/*** END UDP DNS CLIENT ***/
|
||||
142
kernel/picotcp/test/examples/iperfc.c
Normal file
142
kernel/picotcp/test/examples/iperfc.c
Normal file
@@ -0,0 +1,142 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include "pico_ipv6.h"
|
||||
#include "pico_stack.h"
|
||||
#include "pico_socket.h"
|
||||
#include "utils.h"
|
||||
|
||||
#define DURATION 30
|
||||
|
||||
struct iperf_hdr {
|
||||
int32_t flags; /* 0 */
|
||||
int32_t numThreads; /* 1 */
|
||||
int32_t mPort; /* 5001 */
|
||||
int32_t bufferlen; /* 0 */
|
||||
int32_t mWinBand; /* 0 */
|
||||
int32_t mAmount; /* 0xfffffc18 */
|
||||
};
|
||||
|
||||
#define IPERF_PORT 5001
|
||||
#define MTU 1444
|
||||
#define SEND_BUF_SIZ (1024 * 2048)
|
||||
|
||||
char *cpy_arg(char **dst, char *str);
|
||||
extern int IPV6_MODE;
|
||||
|
||||
static pico_time deadline;
|
||||
|
||||
static void panic(void)
|
||||
{
|
||||
for(;; ) ;
|
||||
}
|
||||
|
||||
static char buf[MTU] = {};
|
||||
|
||||
static void buf_paint(void)
|
||||
{
|
||||
char paint[11] = "0123456789";
|
||||
int i;
|
||||
for (i = 0; i < MTU; i++) {
|
||||
buf[i] = paint[i % 10];
|
||||
}
|
||||
}
|
||||
|
||||
static void send_hdr(struct pico_socket *s)
|
||||
{
|
||||
struct iperf_hdr hdr = {};
|
||||
hdr.numThreads = long_be(1);
|
||||
hdr.mPort = long_be(5001);
|
||||
hdr.mAmount = long_be(0xfffffc18);
|
||||
pico_socket_write(s, &hdr, sizeof(hdr));
|
||||
deadline = PICO_TIME_MS() + DURATION * 1000;
|
||||
}
|
||||
|
||||
static void iperf_cb(uint16_t ev, struct pico_socket *s)
|
||||
{
|
||||
int r;
|
||||
static int end = 0;
|
||||
if (ev & PICO_SOCK_EV_CONN) {
|
||||
send_hdr(s);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((!end) && (ev & PICO_SOCK_EV_WR)) {
|
||||
if (PICO_TIME_MS() > deadline) {
|
||||
pico_socket_close(s);
|
||||
if (!pico_timer_add(2000, deferred_exit, NULL)) {
|
||||
printf("Failed to start exit timer, exiting now\n");
|
||||
exit(1);
|
||||
}
|
||||
end++;
|
||||
}
|
||||
|
||||
pico_socket_write(s, buf, MTU);
|
||||
}
|
||||
|
||||
if (!(end) && (ev & (PICO_SOCK_EV_FIN | PICO_SOCK_EV_CLOSE))) {
|
||||
if (!pico_timer_add(2000, deferred_exit, NULL)) {
|
||||
printf("Failed to start exit timer, exiting now\n");
|
||||
exit(1);
|
||||
}
|
||||
end++;
|
||||
}
|
||||
}
|
||||
|
||||
static void iperfc_socket_setup(union pico_address *addr, uint16_t family)
|
||||
{
|
||||
int yes = 1;
|
||||
uint16_t send_port = 0;
|
||||
struct pico_socket *s = NULL;
|
||||
uint32_t bufsize = SEND_BUF_SIZ;
|
||||
send_port = short_be(5001);
|
||||
s = pico_socket_open(family, PICO_PROTO_TCP, &iperf_cb);
|
||||
pico_socket_setoption(s, PICO_SOCKET_OPT_SNDBUF, &bufsize);
|
||||
pico_socket_connect(s, addr, send_port);
|
||||
}
|
||||
|
||||
void app_iperfc(char *arg)
|
||||
{
|
||||
struct pico_ip4 my_eth_addr, netmask;
|
||||
struct pico_device *pico_dev_eth;
|
||||
char *daddr = NULL, *dport = NULL;
|
||||
char *nxt = arg;
|
||||
uint16_t send_port = 0, listen_port = short_be(5001);
|
||||
int i = 0, ret = 0, yes = 1;
|
||||
struct pico_socket *s = NULL;
|
||||
uint16_t family = PICO_PROTO_IPV4;
|
||||
union pico_address dst = {
|
||||
.ip4 = {0}, .ip6 = {{0}}
|
||||
};
|
||||
union pico_address inaddr_any = {
|
||||
.ip4 = {0}, .ip6 = {{0}}
|
||||
};
|
||||
|
||||
/* start of argument parsing */
|
||||
if (nxt) {
|
||||
nxt = cpy_arg(&daddr, arg);
|
||||
if (daddr) {
|
||||
if (!IPV6_MODE)
|
||||
pico_string_to_ipv4(daddr, &dst.ip4.addr);
|
||||
|
||||
#ifdef PICO_SUPPORT_IPV6
|
||||
else {
|
||||
pico_string_to_ipv6(daddr, dst.ip6.addr);
|
||||
family = PICO_PROTO_IPV6;
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
/* missing dest_addr */
|
||||
goto out;
|
||||
}
|
||||
|
||||
iperfc_socket_setup(&dst, family);
|
||||
return;
|
||||
out:
|
||||
dbg("Error parsing options!\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
83
kernel/picotcp/test/examples/mdns.c
Normal file
83
kernel/picotcp/test/examples/mdns.c
Normal file
@@ -0,0 +1,83 @@
|
||||
#include "utils.h"
|
||||
#include "pico_dns_common.h"
|
||||
#include "pico_mdns.h"
|
||||
#include "pico_ipv4.h"
|
||||
#include "pico_addressing.h"
|
||||
|
||||
/*** START MDNS ***/
|
||||
|
||||
#ifdef PICO_SUPPORT_MDNS
|
||||
|
||||
#define SECONDS 10
|
||||
|
||||
static int fully_initialized = 0;
|
||||
|
||||
void mdns_init_callback( pico_mdns_rtree *rtree,
|
||||
char *str,
|
||||
void *arg )
|
||||
{
|
||||
printf("\nInitialised with hostname: %s\n\n", str);
|
||||
|
||||
fully_initialized = 1;
|
||||
}
|
||||
|
||||
void app_mdns(char *arg, struct pico_ip4 address)
|
||||
{
|
||||
char *hostname, *peername;
|
||||
char *nxt = arg;
|
||||
uint64_t starttime = 0;
|
||||
int once = 0;
|
||||
|
||||
if (!nxt)
|
||||
exit(255);
|
||||
|
||||
nxt = cpy_arg(&hostname, nxt);
|
||||
if(!hostname) {
|
||||
exit(255);
|
||||
}
|
||||
|
||||
if(!nxt) {
|
||||
printf("Not enough args supplied!\n");
|
||||
exit(255);
|
||||
}
|
||||
|
||||
nxt = cpy_arg(&peername, nxt);
|
||||
if(!peername) {
|
||||
exit(255);
|
||||
}
|
||||
|
||||
printf("\nStarting mDNS module...\n");
|
||||
if (pico_mdns_init(hostname, address, &mdns_init_callback, NULL)) {
|
||||
printf("Initialisation returned with Error!\n");
|
||||
exit(255);
|
||||
}
|
||||
|
||||
printf("\nTry reinitialising mDNS\n");
|
||||
if (pico_mdns_init(hostname, address, &mdns_init_callback, NULL)) {
|
||||
printf("Initialisation returned with Error!\n");
|
||||
exit(255);
|
||||
}
|
||||
|
||||
printf("DONE - Re-initialising mDNS module.\n");
|
||||
|
||||
starttime = PICO_TIME_MS();
|
||||
printf("Starting time: %d\n", starttime);
|
||||
|
||||
while(1) {
|
||||
pico_stack_tick();
|
||||
usleep(2000);
|
||||
|
||||
if (((PICO_TIME_MS() - starttime) > SECONDS * 1000) && fully_initialized && !once) {
|
||||
printf("\nTry reinitialising mDNS (a second time)\n");
|
||||
if (pico_mdns_init(hostname, address, &mdns_init_callback, NULL)) {
|
||||
printf("Initialisation returned with Error!\n");
|
||||
exit(255);
|
||||
}
|
||||
once = 1;
|
||||
printf("DONE - Re-initialising mDNS module. (a second time)\n");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/*** END MDNS ***/
|
||||
182
kernel/picotcp/test/examples/multicast_ip6_recv.c
Normal file
182
kernel/picotcp/test/examples/multicast_ip6_recv.c
Normal file
@@ -0,0 +1,182 @@
|
||||
#include "utils.h"
|
||||
#include <pico_ipv6.h>
|
||||
#include <pico_socket.h>
|
||||
|
||||
extern void app_udpecho(char *arg);
|
||||
|
||||
/*** START Multicast RECEIVE + ECHO ***/
|
||||
/*
|
||||
* multicast receive expects the following format: mcastreceive:link_addr:mcast_addr:listen_port:sendto_port
|
||||
* link_addr: mcastreceive picoapp IP address
|
||||
* mcast_addr: multicast IP address to receive
|
||||
* listen_port: port number on which the mcastreceive listens
|
||||
* sendto_port: port number to echo multicast traffic to (echo to originating IP address)
|
||||
*
|
||||
* f.e.: ./build/test/picoapp.elf --vde pic1:/tmp/pic0.ctl:10.40.0.3:255.255.0.0: -a mcastreceive:10.40.0.3:224.7.7.7:6667:6667
|
||||
*/
|
||||
extern struct udpclient_pas *udpclient_pas;
|
||||
extern struct udpecho_pas *udpecho_pas;
|
||||
#ifdef PICO_SUPPORT_MCAST
|
||||
void app_mcastreceive_ipv6(char *arg)
|
||||
{
|
||||
char *new_arg = NULL, *p = NULL, *nxt = arg;
|
||||
char *laddr = NULL, *maddr = NULL, *lport = NULL, *sport = NULL;
|
||||
uint16_t listen_port = 0;
|
||||
union pico_address inaddr_link = {
|
||||
0
|
||||
}, inaddr_mcast = {
|
||||
0
|
||||
}, src[5] = {
|
||||
{.ip6 = { 0xfe, 0x80, 0x00, 0x00, 0x00, 0, 0, 0, 0, 0, 0, 0, 0xac, 0x10, 0x01, 0 }},
|
||||
{.ip6 = { 0xfe, 0x80, 0x00, 0x00, 0x00, 0, 0, 0, 0, 0, 0, 0, 0xac, 0x10, 0x01, 0x10}},
|
||||
{.ip6 = { 0xfe, 0x80, 0x00, 0x00, 0x00, 0, 0, 0, 0, 0, 0, 0, 0xac, 0x10, 0x01, 0x01 }},
|
||||
{.ip6 = { 0xff, 0x00, 0x00, 0x00, 0x00, 0, 0, 0, 0, 0, 0, 0, 0xe0, 0x01, 0x01, 0x01 }},
|
||||
};
|
||||
struct pico_ip_mreq mreq = ZERO_MREQ_IP6;
|
||||
struct pico_ip_mreq_source mreq_source = ZERO_MREQ_SRC_IP6;
|
||||
/* start of parameter parsing */
|
||||
if (nxt) {
|
||||
nxt = cpy_arg(&laddr, nxt);
|
||||
if (laddr) {
|
||||
pico_string_to_ipv6(laddr, &inaddr_link.ip6.addr[0]);
|
||||
} else {
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
/* no arguments */
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (nxt) {
|
||||
nxt = cpy_arg(&maddr, nxt);
|
||||
if (maddr) {
|
||||
pico_string_to_ipv6(maddr, &inaddr_mcast.ip6.addr[0]);
|
||||
} else {
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
/* missing multicast address */
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (nxt) {
|
||||
nxt = cpy_arg(&lport, nxt);
|
||||
if (lport && atoi(lport)) {
|
||||
listen_port = short_be(atoi(lport));
|
||||
} else {
|
||||
/* incorrect listen_port */
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
/* missing listen_port */
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (nxt) {
|
||||
nxt = cpy_arg(&sport, nxt);
|
||||
if (sport && atoi(sport)) {
|
||||
/* unused at this moment */
|
||||
/* send_port = short_be(atoi(sport)); */
|
||||
} else {
|
||||
/* incorrect send_port */
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
/* missing send_port */
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* end of parameter parsing */
|
||||
|
||||
printf("\n%s: multicast receive started. Receiving packets on [%s]:%d\n\n", __FUNCTION__, maddr, short_be(listen_port));
|
||||
|
||||
/* udpecho:bind_addr:listen_port[:sendto_port:datasize] */
|
||||
new_arg = calloc(1, strlen(laddr) + 1 + strlen(lport) + 1 + strlen(sport) + strlen(",64:") + 1);
|
||||
p = strcat(new_arg, laddr);
|
||||
p = strcat(p + strlen(laddr), ",");
|
||||
p = strcat(p + 1, lport);
|
||||
p = strcat(p + strlen(lport), ",");
|
||||
p = strcat(p + 1, sport);
|
||||
p = strcat(p + strlen(sport), ",64,");
|
||||
|
||||
/* DAD needs to verify the link address before we can continue */
|
||||
while(!pico_ipv6_link_get(&inaddr_link.ip6)) {
|
||||
pico_stack_tick();
|
||||
usleep(2000);
|
||||
}
|
||||
app_udpecho(new_arg);
|
||||
|
||||
memcpy(&mreq.mcast_group_addr, &inaddr_mcast, sizeof(struct pico_ip6));
|
||||
memcpy( &mreq_source.mcast_group_addr, &inaddr_mcast, sizeof(struct pico_ip6));
|
||||
memcpy(&mreq.mcast_link_addr, &inaddr_link, sizeof(struct pico_ip6));
|
||||
memcpy(&mreq_source.mcast_link_addr, &inaddr_link, sizeof(struct pico_ip6));
|
||||
memcpy(&mreq_source.mcast_source_addr, &src[0], sizeof(struct pico_ip6));
|
||||
if(pico_socket_setoption(udpecho_pas->s, PICO_IP_ADD_MEMBERSHIP, &mreq) < 0) {
|
||||
printf("%s: socket_setoption PICO_IP_ADD_MEMBERSHIP failed: %s\n", __FUNCTION__, strerror(pico_err));
|
||||
}
|
||||
|
||||
if(pico_socket_setoption(udpecho_pas->s, PICO_IP_DROP_MEMBERSHIP, &mreq) < 0) {
|
||||
printf("%s: socket_setoption PICO_IP_DROP_MEMBERSHIP failed: %s\n", __FUNCTION__, strerror(pico_err));
|
||||
}
|
||||
|
||||
if(pico_socket_setoption(udpecho_pas->s, PICO_IP_ADD_MEMBERSHIP, &mreq) < 0) {
|
||||
printf("%s: socket_setoption PICO_IP_ADD_MEMBERSHIP failed: %s\n", __FUNCTION__, strerror(pico_err));
|
||||
}
|
||||
|
||||
if(pico_socket_setoption(udpecho_pas->s, PICO_IP_BLOCK_SOURCE, &mreq_source) < 0) {
|
||||
printf("%s: socket_setoption PICO_IP_BLOCK_SOURCE failed: %s\n", __FUNCTION__, strerror(pico_err));
|
||||
}
|
||||
|
||||
if(pico_socket_setoption(udpecho_pas->s, PICO_IP_UNBLOCK_SOURCE, &mreq_source) < 0) {
|
||||
printf("%s: socket_setoption PICO_IP_UNBLOCK_SOURCE failed: %s\n", __FUNCTION__, strerror(pico_err));
|
||||
}
|
||||
|
||||
if(pico_socket_setoption(udpecho_pas->s, PICO_IP_DROP_MEMBERSHIP, &mreq) < 0) {
|
||||
printf("%s: socket_setoption PICO_IP_DROP_MEMBERSHIP failed: %s\n", __FUNCTION__, strerror(pico_err));
|
||||
}
|
||||
|
||||
if(pico_socket_setoption(udpecho_pas->s, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source) < 0) {
|
||||
printf("%s: socket_setoption PICO_IP_ADD_SOURCE_MEMBERSHIP: %s\n", __FUNCTION__, strerror(pico_err));
|
||||
}
|
||||
|
||||
if(pico_socket_setoption(udpecho_pas->s, PICO_IP_DROP_SOURCE_MEMBERSHIP, &mreq_source) < 0) {
|
||||
printf("%s: socket_setoption PICO_IP_DROP_SOURCE_MEMBERSHIP: %s\n", __FUNCTION__, strerror(pico_err));
|
||||
}
|
||||
|
||||
if(pico_socket_setoption(udpecho_pas->s, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source) < 0) {
|
||||
printf("%s: socket_setoption PICO_IP_ADD_SOURCE_MEMBERSHIP: %s\n", __FUNCTION__, strerror(pico_err));
|
||||
}
|
||||
|
||||
memcpy(&mreq_source.mcast_source_addr, &src[1], sizeof(struct pico_ip6));
|
||||
if(pico_socket_setoption(udpecho_pas->s, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source) < 0) {
|
||||
printf("%s: socket_setoption PICO_IP_ADD_SOURCE_MEMBERSHIP: %s\n", __FUNCTION__, strerror(pico_err));
|
||||
}
|
||||
|
||||
if(pico_socket_setoption(udpecho_pas->s, PICO_IP_DROP_MEMBERSHIP, &mreq) < 0) {
|
||||
printf("%s: socket_setoption PICO_IP_DROP_MEMBERSHIP failed: %s\n", __FUNCTION__, strerror(pico_err));
|
||||
}
|
||||
|
||||
memcpy(&mreq_source.mcast_source_addr, &src[2], sizeof(struct pico_ip6));
|
||||
if(pico_socket_setoption(udpecho_pas->s, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source) < 0) {
|
||||
printf("%s: socket_setoption PICO_IP_ADD_SOURCE_MEMBERSHIP: %s\n", __FUNCTION__, strerror(pico_err));
|
||||
}
|
||||
|
||||
memcpy(&mreq_source.mcast_group_addr, &src[3], sizeof(struct pico_ip6));
|
||||
if(pico_socket_setoption(udpecho_pas->s, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source) < 0) {
|
||||
printf("%s: socket_setoption PICO_IP_ADD_SOURCE_MEMBERSHIP: %s\n", __FUNCTION__, strerror(pico_err));
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
out:
|
||||
fprintf(stderr, "mcastreceive expects the following format: mcastreceive:link_addr:mcast_addr:listen_port[:send_port]\n");
|
||||
exit(255);
|
||||
}
|
||||
#else
|
||||
void app_mcastreceive_ipv6(char *arg)
|
||||
{
|
||||
printf("ERROR: PICO_SUPPORT_MCAST disabled\n");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
/*** END Multicast RECEIVE + ECHO ***/
|
||||
140
kernel/picotcp/test/examples/multicast_ip6_send.c
Normal file
140
kernel/picotcp/test/examples/multicast_ip6_send.c
Normal file
@@ -0,0 +1,140 @@
|
||||
#include "utils.h"
|
||||
#include <pico_ipv4.h>
|
||||
#include <pico_ipv6.h>
|
||||
#include <pico_socket.h>
|
||||
|
||||
extern void app_udpclient(char *arg);
|
||||
/*** START Multicast SEND ***/
|
||||
/*
|
||||
* multicast send expects the following format: mcastsend:link_addr:mcast_addr:sendto_port:listen_port
|
||||
* link_addr: mcastsend picoapp IP address
|
||||
* mcast_addr: multicast IP address to send to
|
||||
* sendto_port: port number to send multicast traffic to
|
||||
* listen_port: port number on which the mcastsend can receive data
|
||||
*
|
||||
* f.e.: ./build/test/picoapp.elf --vde pic0:/tmp/pic0.ctl:10.40.0.2:255.255.255.0: -a mcastsend:10.40.0.2:224.7.7.7:6667:6667
|
||||
*/
|
||||
extern struct udpclient_pas *udpclient_pas;
|
||||
#ifdef PICO_SUPPORT_MCAST
|
||||
void app_mcastsend_ipv6(char *arg)
|
||||
{
|
||||
int retval = 0;
|
||||
char *maddr = NULL, *laddr = NULL, *lport = NULL, *sport = NULL;
|
||||
uint16_t sendto_port = 0;
|
||||
struct pico_ip6 inaddr_link = {
|
||||
0
|
||||
}, inaddr_mcast = {
|
||||
0
|
||||
};
|
||||
char *new_arg = NULL, *p = NULL, *nxt = arg;
|
||||
struct pico_ip_mreq mreq = ZERO_MREQ_IP6;
|
||||
|
||||
/* start of parameter parsing */
|
||||
if (nxt) {
|
||||
nxt = cpy_arg(&laddr, nxt);
|
||||
if (laddr) {
|
||||
pico_string_to_ipv6(laddr, &inaddr_link.addr[0]);
|
||||
} else {
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
/* no arguments */
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (nxt) {
|
||||
nxt = cpy_arg(&maddr, nxt);
|
||||
if (maddr) {
|
||||
pico_string_to_ipv6(maddr, &inaddr_mcast.addr[0]);
|
||||
} else {
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
/* missing multicast address */
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (nxt) {
|
||||
nxt = cpy_arg(&sport, nxt);
|
||||
if (sport && atoi(sport)) {
|
||||
sendto_port = short_be(atoi(sport));
|
||||
} else {
|
||||
/* incorrect send_port */
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
/* missing send_port */
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (nxt) {
|
||||
nxt = cpy_arg(&lport, nxt);
|
||||
if (lport && atoi(lport)) {
|
||||
/* unused at this moment */
|
||||
/* listen_port = short_be(atoi(lport)); */
|
||||
} else {
|
||||
/* incorrect listen_port */
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
/* missing listen_port */
|
||||
goto out;
|
||||
}
|
||||
|
||||
picoapp_dbg("\n%s: mcastsend started. Sending packets to %s:%u\n\n", __FUNCTION__, maddr, short_be(sendto_port));
|
||||
|
||||
/* udpclient:dest_addr:sendto_port[:listen_port:datasize:loops:subloops] */
|
||||
new_arg = calloc(1, strlen(maddr) + 1 + strlen(sport) + 1 + strlen(lport) + strlen(",64,10,5,") + 1);
|
||||
p = strcat(new_arg, maddr);
|
||||
p = strcat(p + strlen(maddr), ",");
|
||||
p = strcat(p + 1, sport);
|
||||
p = strcat(p + strlen(sport), ",");
|
||||
p = strcat(p + 1, lport);
|
||||
p = strcat(p + strlen(lport), ",64,10,5,");
|
||||
|
||||
/* DAD needs to verify the link address before we can continue */
|
||||
while(!pico_ipv6_link_get(&inaddr_link)) {
|
||||
pico_stack_tick();
|
||||
usleep(2000);
|
||||
}
|
||||
app_udpclient(new_arg);
|
||||
|
||||
memcpy(&mreq.mcast_group_addr, &inaddr_mcast, sizeof(struct pico_ip6));
|
||||
memcpy(&mreq.mcast_link_addr, &inaddr_link, sizeof(struct pico_ip6));
|
||||
if(pico_socket_setoption(udpclient_pas->s, PICO_IP_ADD_MEMBERSHIP, &mreq) < 0) {
|
||||
picoapp_dbg("%s: socket_setoption PICO_IP_ADD_MEMBERSHIP failed: %s\n", __FUNCTION__, strerror(pico_err));
|
||||
retval = 1;
|
||||
}
|
||||
|
||||
if (new_arg)
|
||||
free(new_arg);
|
||||
|
||||
if (lport)
|
||||
free(lport);
|
||||
|
||||
if (maddr)
|
||||
free(maddr);
|
||||
|
||||
if (sport)
|
||||
free(sport);
|
||||
|
||||
if (laddr)
|
||||
free(laddr);
|
||||
|
||||
if (retval)
|
||||
exit(retval);
|
||||
|
||||
return;
|
||||
|
||||
out:
|
||||
picoapp_dbg("mcastsend expects the following format: mcastsend:link_addr:mcast_addr:sendto_port:listen_port\n");
|
||||
exit(255);
|
||||
}
|
||||
#else
|
||||
void app_mcastsend_ipv6(char *arg)
|
||||
{
|
||||
picoapp_dbg("ERROR: PICO_SUPPORT_MCAST disabled\n");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
/*** END Multicast SEND ***/
|
||||
171
kernel/picotcp/test/examples/multicast_recv.c
Normal file
171
kernel/picotcp/test/examples/multicast_recv.c
Normal file
@@ -0,0 +1,171 @@
|
||||
#include "utils.h"
|
||||
#include <pico_ipv4.h>
|
||||
#include <pico_socket.h>
|
||||
|
||||
extern void app_udpecho(char *arg);
|
||||
|
||||
/*** START Multicast RECEIVE + ECHO ***/
|
||||
/*
|
||||
* multicast receive expects the following format: mcastreceive:link_addr:mcast_addr:listen_port:sendto_port
|
||||
* link_addr: mcastreceive picoapp IP address
|
||||
* mcast_addr: multicast IP address to receive
|
||||
* listen_port: port number on which the mcastreceive listens
|
||||
* sendto_port: port number to echo multicast traffic to (echo to originating IP address)
|
||||
*
|
||||
* f.e.: ./build/test/picoapp.elf --vde pic1:/tmp/pic0.ctl:10.40.0.3:255.255.0.0: -a mcastreceive:10.40.0.3:224.7.7.7:6667:6667
|
||||
*/
|
||||
extern struct udpclient_pas *udpclient_pas;
|
||||
extern struct udpecho_pas *udpecho_pas;
|
||||
#ifdef PICO_SUPPORT_MCAST
|
||||
void app_mcastreceive(char *arg)
|
||||
{
|
||||
char *new_arg = NULL, *p = NULL, *nxt = arg;
|
||||
char *laddr = NULL, *maddr = NULL, *lport = NULL, *sport = NULL;
|
||||
uint16_t listen_port = 0;
|
||||
union pico_address inaddr_link = {
|
||||
0
|
||||
}, inaddr_mcast = {
|
||||
0
|
||||
};
|
||||
struct pico_ip_mreq mreq = ZERO_MREQ;
|
||||
struct pico_ip_mreq_source mreq_source = ZERO_MREQ_SRC;
|
||||
|
||||
/* start of parameter parsing */
|
||||
if (nxt) {
|
||||
nxt = cpy_arg(&laddr, nxt);
|
||||
if (laddr) {
|
||||
pico_string_to_ipv4(laddr, &inaddr_link.ip4.addr);
|
||||
} else {
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
/* no arguments */
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (nxt) {
|
||||
nxt = cpy_arg(&maddr, nxt);
|
||||
if (maddr) {
|
||||
pico_string_to_ipv4(maddr, &inaddr_mcast.ip4.addr);
|
||||
} else {
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
/* missing multicast address */
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (nxt) {
|
||||
nxt = cpy_arg(&lport, nxt);
|
||||
if (lport && atoi(lport)) {
|
||||
listen_port = short_be(atoi(lport));
|
||||
} else {
|
||||
/* incorrect listen_port */
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
/* missing listen_port */
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (nxt) {
|
||||
nxt = cpy_arg(&sport, nxt);
|
||||
if (sport && atoi(sport)) {
|
||||
/* unused at this moment */
|
||||
/* send_port = short_be(atoi(sport)); */
|
||||
} else {
|
||||
/* incorrect send_port */
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
/* missing send_port */
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* end of parameter parsing */
|
||||
|
||||
printf("\n%s: multicast receive started. Receiving packets on %s:%d\n\n", __FUNCTION__, maddr, short_be(listen_port));
|
||||
|
||||
/* udpecho:bind_addr:listen_port[:sendto_port:datasize] */
|
||||
new_arg = calloc(1, strlen(laddr) + 1 + strlen(lport) + 1 + strlen(sport) + strlen(":64:") + 1);
|
||||
p = strcat(new_arg, laddr);
|
||||
p = strcat(p + strlen(laddr), ":");
|
||||
p = strcat(p + 1, lport);
|
||||
p = strcat(p + strlen(lport), ":");
|
||||
p = strcat(p + 1, sport);
|
||||
p = strcat(p + strlen(sport), ":64:");
|
||||
|
||||
app_udpecho(new_arg);
|
||||
|
||||
mreq.mcast_group_addr = mreq_source.mcast_group_addr = inaddr_mcast;
|
||||
mreq.mcast_link_addr = mreq_source.mcast_link_addr = inaddr_link;
|
||||
mreq_source.mcast_source_addr.ip4.addr = long_be(0XAC100101);
|
||||
if(pico_socket_setoption(udpecho_pas->s, PICO_IP_ADD_MEMBERSHIP, &mreq) < 0) {
|
||||
printf("%s: socket_setoption PICO_IP_ADD_MEMBERSHIP failed: %s\n", __FUNCTION__, strerror(pico_err));
|
||||
}
|
||||
|
||||
if(pico_socket_setoption(udpecho_pas->s, PICO_IP_DROP_MEMBERSHIP, &mreq) < 0) {
|
||||
printf("%s: socket_setoption PICO_IP_DROP_MEMBERSHIP failed: %s\n", __FUNCTION__, strerror(pico_err));
|
||||
}
|
||||
|
||||
if(pico_socket_setoption(udpecho_pas->s, PICO_IP_ADD_MEMBERSHIP, &mreq) < 0) {
|
||||
printf("%s: socket_setoption PICO_IP_ADD_MEMBERSHIP failed: %s\n", __FUNCTION__, strerror(pico_err));
|
||||
}
|
||||
|
||||
if(pico_socket_setoption(udpecho_pas->s, PICO_IP_BLOCK_SOURCE, &mreq_source) < 0) {
|
||||
printf("%s: socket_setoption PICO_IP_BLOCK_SOURCE failed: %s\n", __FUNCTION__, strerror(pico_err));
|
||||
}
|
||||
|
||||
if(pico_socket_setoption(udpecho_pas->s, PICO_IP_UNBLOCK_SOURCE, &mreq_source) < 0) {
|
||||
printf("%s: socket_setoption PICO_IP_UNBLOCK_SOURCE failed: %s\n", __FUNCTION__, strerror(pico_err));
|
||||
}
|
||||
|
||||
if(pico_socket_setoption(udpecho_pas->s, PICO_IP_DROP_MEMBERSHIP, &mreq) < 0) {
|
||||
printf("%s: socket_setoption PICO_IP_DROP_MEMBERSHIP failed: %s\n", __FUNCTION__, strerror(pico_err));
|
||||
}
|
||||
|
||||
if(pico_socket_setoption(udpecho_pas->s, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source) < 0) {
|
||||
printf("%s: socket_setoption PICO_IP_ADD_SOURCE_MEMBERSHIP: %s\n", __FUNCTION__, strerror(pico_err));
|
||||
}
|
||||
|
||||
if(pico_socket_setoption(udpecho_pas->s, PICO_IP_DROP_SOURCE_MEMBERSHIP, &mreq_source) < 0) {
|
||||
printf("%s: socket_setoption PICO_IP_DROP_SOURCE_MEMBERSHIP: %s\n", __FUNCTION__, strerror(pico_err));
|
||||
}
|
||||
|
||||
if(pico_socket_setoption(udpecho_pas->s, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source) < 0) {
|
||||
printf("%s: socket_setoption PICO_IP_ADD_SOURCE_MEMBERSHIP: %s\n", __FUNCTION__, strerror(pico_err));
|
||||
}
|
||||
|
||||
mreq_source.mcast_source_addr.ip4.addr = long_be(0XAC10010A);
|
||||
if(pico_socket_setoption(udpecho_pas->s, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source) < 0) {
|
||||
printf("%s: socket_setoption PICO_IP_ADD_SOURCE_MEMBERSHIP: %s\n", __FUNCTION__, strerror(pico_err));
|
||||
}
|
||||
|
||||
if(pico_socket_setoption(udpecho_pas->s, PICO_IP_DROP_MEMBERSHIP, &mreq) < 0) {
|
||||
printf("%s: socket_setoption PICO_IP_DROP_MEMBERSHIP failed: %s\n", __FUNCTION__, strerror(pico_err));
|
||||
}
|
||||
|
||||
mreq_source.mcast_source_addr.ip4.addr = long_be(0XAC100101);
|
||||
if(pico_socket_setoption(udpecho_pas->s, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source) < 0) {
|
||||
printf("%s: socket_setoption PICO_IP_ADD_SOURCE_MEMBERSHIP: %s\n", __FUNCTION__, strerror(pico_err));
|
||||
}
|
||||
|
||||
mreq_source.mcast_group_addr.ip4.addr = long_be(0XE0010101);
|
||||
if(pico_socket_setoption(udpecho_pas->s, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source) < 0) {
|
||||
printf("%s: socket_setoption PICO_IP_ADD_SOURCE_MEMBERSHIP: %s\n", __FUNCTION__, strerror(pico_err));
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
out:
|
||||
fprintf(stderr, "mcastreceive expects the following format: mcastreceive:link_addr:mcast_addr:listen_port[:send_port]\n");
|
||||
exit(255);
|
||||
}
|
||||
#else
|
||||
void app_mcastreceive(char *arg)
|
||||
{
|
||||
printf("ERROR: PICO_SUPPORT_MCAST disabled\n");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
/*** END Multicast RECEIVE + ECHO ***/
|
||||
129
kernel/picotcp/test/examples/multicast_send.c
Normal file
129
kernel/picotcp/test/examples/multicast_send.c
Normal file
@@ -0,0 +1,129 @@
|
||||
#include "utils.h"
|
||||
#include <pico_ipv4.h>
|
||||
#include <pico_socket.h>
|
||||
|
||||
extern void app_udpclient(char *arg);
|
||||
/*** START Multicast SEND ***/
|
||||
/*
|
||||
* multicast send expects the following format: mcastsend:link_addr:mcast_addr:sendto_port:listen_port
|
||||
* link_addr: mcastsend picoapp IP address
|
||||
* mcast_addr: multicast IP address to send to
|
||||
* sendto_port: port number to send multicast traffic to
|
||||
* listen_port: port number on which the mcastsend can receive data
|
||||
*
|
||||
* f.e.: ./build/test/picoapp.elf --vde pic0:/tmp/pic0.ctl:10.40.0.2:255.255.255.0: -a mcastsend:10.40.0.2:224.7.7.7:6667:6667
|
||||
*/
|
||||
extern struct udpclient_pas *udpclient_pas;
|
||||
#ifdef PICO_SUPPORT_MCAST
|
||||
void app_mcastsend(char *arg)
|
||||
{
|
||||
char *maddr = NULL, *laddr = NULL, *lport = NULL, *sport = NULL;
|
||||
uint16_t sendto_port = 0;
|
||||
union pico_address inaddr_link = {
|
||||
0
|
||||
}, inaddr_mcast = {
|
||||
0
|
||||
};
|
||||
char *new_arg = NULL, *p = NULL, *nxt = arg;
|
||||
struct pico_ip_mreq mreq = ZERO_MREQ;
|
||||
|
||||
/* start of parameter parsing */
|
||||
if (nxt) {
|
||||
nxt = cpy_arg(&laddr, nxt);
|
||||
if (laddr) {
|
||||
pico_string_to_ipv4(laddr, &inaddr_link.ip4.addr);
|
||||
} else {
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
/* no arguments */
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (nxt) {
|
||||
nxt = cpy_arg(&maddr, nxt);
|
||||
if (maddr) {
|
||||
pico_string_to_ipv4(maddr, &inaddr_mcast.ip4.addr);
|
||||
} else {
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
/* missing multicast address */
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (nxt) {
|
||||
nxt = cpy_arg(&sport, nxt);
|
||||
if (sport && atoi(sport)) {
|
||||
sendto_port = short_be(atoi(sport));
|
||||
} else {
|
||||
/* incorrect send_port */
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
/* missing send_port */
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (nxt) {
|
||||
nxt = cpy_arg(&lport, nxt);
|
||||
if (lport && atoi(lport)) {
|
||||
/* unused at this moment */
|
||||
/* listen_port = short_be(atoi(lport)); */
|
||||
} else {
|
||||
/* incorrect listen_port */
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
/* missing listen_port */
|
||||
goto out;
|
||||
}
|
||||
|
||||
picoapp_dbg("\n%s: mcastsend started. Sending packets to %08X:%u\n\n", __FUNCTION__, long_be(inaddr_mcast.addr), short_be(sendto_port));
|
||||
|
||||
/* udpclient:dest_addr:sendto_port[:listen_port:datasize:loops:subloops] */
|
||||
new_arg = calloc(1, strlen(maddr) + 1 + strlen(sport) + 1 + strlen(lport) + strlen(":64:10:5:") + 1);
|
||||
p = strcat(new_arg, maddr);
|
||||
p = strcat(p + strlen(maddr), ":");
|
||||
p = strcat(p + 1, sport);
|
||||
p = strcat(p + strlen(sport), ":");
|
||||
p = strcat(p + 1, lport);
|
||||
p = strcat(p + strlen(lport), ":64:10:5:");
|
||||
|
||||
app_udpclient(new_arg);
|
||||
free(new_arg);
|
||||
|
||||
mreq.mcast_group_addr = inaddr_mcast;
|
||||
mreq.mcast_link_addr = inaddr_link;
|
||||
if(pico_socket_setoption(udpclient_pas->s, PICO_IP_ADD_MEMBERSHIP, &mreq) < 0) {
|
||||
picoapp_dbg("%s: socket_setoption PICO_IP_ADD_MEMBERSHIP failed: %s\n", __FUNCTION__, strerror(pico_err));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* free strdups */
|
||||
if (maddr)
|
||||
free(maddr);
|
||||
|
||||
if (laddr)
|
||||
free(laddr);
|
||||
|
||||
if (lport)
|
||||
free(lport);
|
||||
|
||||
if (sport)
|
||||
free(sport);
|
||||
|
||||
return;
|
||||
|
||||
out:
|
||||
picoapp_dbg("mcastsend expects the following format: mcastsend:link_addr:mcast_addr:sendto_port:listen_port\n");
|
||||
exit(255);
|
||||
}
|
||||
#else
|
||||
void app_mcastsend(char *arg)
|
||||
{
|
||||
picoapp_dbg("ERROR: PICO_SUPPORT_MCAST disabled\n");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
/*** END Multicast SEND ***/
|
||||
31
kernel/picotcp/test/examples/natbox.c
Normal file
31
kernel/picotcp/test/examples/natbox.c
Normal file
@@ -0,0 +1,31 @@
|
||||
#include "utils.h"
|
||||
#include <pico_ipv4.h>
|
||||
#include <pico_nat.h>
|
||||
|
||||
/*** START NATBOX ***/
|
||||
void app_natbox(char *arg)
|
||||
{
|
||||
char *dest = NULL;
|
||||
struct pico_ip4 ipdst, pub_addr, priv_addr;
|
||||
struct pico_ipv4_link *link;
|
||||
|
||||
cpy_arg(&dest, arg);
|
||||
if (!dest) {
|
||||
fprintf(stderr, "natbox needs the following format: natbox:dst_addr\n");
|
||||
exit(255);
|
||||
}
|
||||
|
||||
pico_string_to_ipv4(dest, &ipdst.addr);
|
||||
link = pico_ipv4_link_get(&ipdst);
|
||||
if (!link) {
|
||||
fprintf(stderr, "natbox: Destination not found.\n");
|
||||
exit(255);
|
||||
}
|
||||
|
||||
pico_ipv4_nat_enable(link);
|
||||
pico_string_to_ipv4("10.50.0.10", &pub_addr.addr);
|
||||
pico_string_to_ipv4("10.40.0.08", &priv_addr.addr);
|
||||
pico_ipv4_port_forward(pub_addr, short_be(5555), priv_addr, short_be(6667), PICO_PROTO_UDP, PICO_NAT_PORT_FORWARD_ADD);
|
||||
fprintf(stderr, "natbox: started.\n");
|
||||
}
|
||||
/*** END NATBOX ***/
|
||||
11
kernel/picotcp/test/examples/noop.c
Normal file
11
kernel/picotcp/test/examples/noop.c
Normal file
@@ -0,0 +1,11 @@
|
||||
/* NOOP */
|
||||
#include <pico_stack.h>
|
||||
void app_noop(void)
|
||||
{
|
||||
while(1) {
|
||||
pico_stack_tick();
|
||||
usleep(2000);
|
||||
}
|
||||
}
|
||||
|
||||
/* END NOOP */
|
||||
138
kernel/picotcp/test/examples/ping.c
Normal file
138
kernel/picotcp/test/examples/ping.c
Normal file
@@ -0,0 +1,138 @@
|
||||
#include "utils.h"
|
||||
#include <pico_ipv4.h>
|
||||
#include <pico_ipv6.h>
|
||||
#include <pico_icmp4.h>
|
||||
#include <pico_icmp6.h>
|
||||
/*** START PING ***/
|
||||
#ifdef PICO_SUPPORT_PING
|
||||
#define NUM_PING 10
|
||||
|
||||
void cb_ping(struct pico_icmp4_stats *s)
|
||||
{
|
||||
char host[30];
|
||||
pico_ipv4_to_string(host, s->dst.addr);
|
||||
if (s->err == 0) {
|
||||
dbg("%lu bytes from %s: icmp_req=%lu ttl=%lu time=%lu ms\n", s->size, host, s->seq,
|
||||
s->ttl, (long unsigned int)s->time);
|
||||
if (s->seq >= NUM_PING)
|
||||
exit(0);
|
||||
} else {
|
||||
dbg("PING %lu to %s: Error %d\n", s->seq, host, s->err);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef PICO_SUPPORT_IPV6
|
||||
void cb_ping6(struct pico_icmp6_stats *s)
|
||||
{
|
||||
char host[50];
|
||||
pico_ipv6_to_string(host, s->dst.addr);
|
||||
if (s->err == 0) {
|
||||
dbg("%lu bytes from %s: icmp_req=%lu ttl=%lu time=%lu ms\n", s->size, host, s->seq,
|
||||
s->ttl, (long unsigned int)s->time);
|
||||
if (s->seq >= NUM_PING)
|
||||
exit(0);
|
||||
} else {
|
||||
dbg("PING %lu to %s: Error %d\n", s->seq, host, s->err);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void ping_abort_timer(pico_time now, void *_id)
|
||||
{
|
||||
int *id = (int *) _id;
|
||||
printf("Ping: aborting...\n");
|
||||
if (!IPV6_MODE)
|
||||
pico_icmp4_ping_abort(*id);
|
||||
|
||||
#ifdef PICO_SUPPORT_IPV6
|
||||
else
|
||||
pico_icmp6_ping_abort(*id);
|
||||
#endif
|
||||
}
|
||||
|
||||
void app_ping(char *arg)
|
||||
{
|
||||
char *dest = NULL;
|
||||
char *next = NULL;
|
||||
char *abort = NULL;
|
||||
char *delay = NULL;
|
||||
char *asize = NULL;
|
||||
int initial_delay = 0;
|
||||
struct pico_ip6 dst;
|
||||
static int id;
|
||||
int timeout = 0;
|
||||
int size = 64;
|
||||
|
||||
next = cpy_arg(&dest, arg);
|
||||
if (!dest) {
|
||||
fprintf(stderr, "ping needs the following format: ping:dst_addr:[size:[abort after N sec:[wait N sec before start]]]\n");
|
||||
exit(255);
|
||||
}
|
||||
pico_string_to_ipv6(dest, dst.addr);
|
||||
if (next) {
|
||||
next = cpy_arg(&asize, next);
|
||||
size = atoi(asize);
|
||||
free(asize);
|
||||
if (size <= 0) {
|
||||
size = 64; /* Default */
|
||||
}
|
||||
}
|
||||
|
||||
if (next) {
|
||||
next = cpy_arg(&abort, next);
|
||||
if (strlen(abort) > 0) {
|
||||
printf("Got arg: '%s'\n", abort);
|
||||
timeout = atoi(abort);
|
||||
if (timeout < 0) {
|
||||
fprintf(stderr, "ping needs the following format: ping:dst_addr:[size:[abort after N sec:[wait N sec before start]]]\n");
|
||||
exit(255);
|
||||
}
|
||||
printf("Aborting ping after %d seconds\n", timeout);
|
||||
}
|
||||
}
|
||||
|
||||
if (next) {
|
||||
next = cpy_arg(&delay, next);
|
||||
if (strlen(delay) > 0) {
|
||||
initial_delay = atoi(delay);
|
||||
if (initial_delay > 0) {
|
||||
printf("Initial delay: %d seconds\n", initial_delay);
|
||||
initial_delay = PICO_TIME_MS() + initial_delay * 1000;
|
||||
while (PICO_TIME_MS() < initial_delay) {
|
||||
pico_stack_tick();
|
||||
usleep(10000);
|
||||
}
|
||||
}
|
||||
}
|
||||
free(delay);
|
||||
}
|
||||
printf("Starting ping.\n");
|
||||
|
||||
if (!IPV6_MODE)
|
||||
id = pico_icmp4_ping(dest, NUM_PING, 1000, 10000, size, cb_ping);
|
||||
|
||||
#ifdef PICO_SUPPORT_IPV6
|
||||
else
|
||||
id = pico_icmp6_ping(dest, NUM_PING, 1000, 10000, size, cb_ping6, pico_ipv6_source_dev_find(&dst));
|
||||
#endif
|
||||
if (timeout > 0) {
|
||||
printf("Adding abort timer after %d seconds for id %d\n", timeout, id);
|
||||
if (!pico_timer_add(timeout * 1000, ping_abort_timer, &id)) {
|
||||
printf("Failed to set ping abort timeout, aborting ping\n");
|
||||
ping_abort_timer((pico_time)0, &id);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* free copied args */
|
||||
if (dest)
|
||||
free(dest);
|
||||
|
||||
if (abort)
|
||||
free(abort);
|
||||
}
|
||||
#endif
|
||||
/*** END PING ***/
|
||||
|
||||
72
kernel/picotcp/test/examples/slaacv4.c
Normal file
72
kernel/picotcp/test/examples/slaacv4.c
Normal file
@@ -0,0 +1,72 @@
|
||||
#include "utils.h"
|
||||
#include <pico_slaacv4.h>
|
||||
#include <pico_icmp4.h>
|
||||
/*** START SLAACV4 ***/
|
||||
|
||||
void ping_callback_slaacv4(struct pico_icmp4_stats *s)
|
||||
{
|
||||
char host[30] = { };
|
||||
|
||||
pico_ipv4_to_string(host, s->dst.addr);
|
||||
if (s->err == 0) {
|
||||
dbg("SLAACV4: %lu bytes from %s: icmp_req=%lu ttl=64 time=%lu ms\n", s->size, host,
|
||||
s->seq, (long unsigned int)s->time);
|
||||
if (s->seq >= 3) {
|
||||
dbg("SLAACV4: TEST SUCCESS!\n");
|
||||
pico_slaacv4_unregisterip();
|
||||
exit(0);
|
||||
}
|
||||
} else {
|
||||
dbg("SLAACV4: ping %lu to %s error %d\n", s->seq, host, s->err);
|
||||
dbg("SLAACV4: TEST FAILED!\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
void slaacv4_cb(struct pico_ip4 *ip, uint8_t code)
|
||||
{
|
||||
char dst[16] = "169.254.22.5";
|
||||
printf("SLAACV4 CALLBACK ip:0x%X code:%d \n", ip->addr, code);
|
||||
if (code == 0)
|
||||
{
|
||||
#ifdef PICO_SUPPORT_PING
|
||||
pico_icmp4_ping(dst, 3, 1000, 5000, 32, ping_callback_slaacv4);
|
||||
#else
|
||||
exit(0);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
exit(255);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void app_slaacv4(char *arg)
|
||||
{
|
||||
char *sdev = NULL;
|
||||
char *nxt = arg;
|
||||
struct pico_device *dev = NULL;
|
||||
|
||||
if (!nxt)
|
||||
exit(255);
|
||||
|
||||
while (nxt) {
|
||||
if (nxt) {
|
||||
nxt = cpy_arg(&sdev, nxt);
|
||||
if(!sdev) {
|
||||
exit(255);
|
||||
}
|
||||
}
|
||||
}
|
||||
dev = pico_get_device(sdev);
|
||||
free(sdev);
|
||||
if(dev == NULL) {
|
||||
printf("%s: error getting device %s: %s\n", __FUNCTION__, dev->name, strerror(pico_err));
|
||||
exit(255);
|
||||
}
|
||||
|
||||
pico_slaacv4_claimip(dev, slaacv4_cb);
|
||||
}
|
||||
/*** END SLAACv4 ***/
|
||||
59
kernel/picotcp/test/examples/sntp.c
Normal file
59
kernel/picotcp/test/examples/sntp.c
Normal file
@@ -0,0 +1,59 @@
|
||||
#include "utils.h"
|
||||
#include <pico_sntp_client.h>
|
||||
/*** START SNTP ***/
|
||||
|
||||
#ifdef PICO_SUPPORT_SNTP_CLIENT
|
||||
|
||||
void sntp_timeout(pico_time __attribute__((unused)) now, void *arg)
|
||||
{
|
||||
struct pico_timeval ptv;
|
||||
struct timeval tv;
|
||||
pico_sntp_gettimeofday(&ptv);
|
||||
gettimeofday(&tv, NULL);
|
||||
printf("Linux sec: %u, msec: %u\n", (unsigned int)tv.tv_sec, (unsigned int)tv.tv_usec / 1000);
|
||||
printf("Picotcp sec: %u, msec: %u\n", (unsigned int)ptv.tv_sec, (unsigned int)ptv.tv_msec);
|
||||
printf("SNTP test succesfull!\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void cb_synced(pico_err_t status)
|
||||
{
|
||||
if(status == PICO_ERR_ENETDOWN) {
|
||||
printf("SNTP: Cannot resolve ntp server name\n");
|
||||
exit(1);
|
||||
} else if (status == PICO_ERR_ETIMEDOUT) {
|
||||
printf("SNTP: Timed out, did not receive ntp packet from server\n");
|
||||
exit(1);
|
||||
} else if (status == PICO_ERR_EINVAL) {
|
||||
printf("SNTP: Conversion error\n");
|
||||
exit(1);
|
||||
} else if (status == PICO_ERR_ENOTCONN) {
|
||||
printf("SNTP: Socket error\n");
|
||||
exit(1);
|
||||
} else if (status == PICO_ERR_NOERR) {
|
||||
if (!pico_timer_add(2000, sntp_timeout, NULL)) {
|
||||
printf("SNTP: Failed to start timeout timer, exiting program \n");
|
||||
exit(1);
|
||||
}
|
||||
} else {
|
||||
printf("SNTP: Invalid status received in cb_synced\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
void app_sntp(char *servername)
|
||||
{
|
||||
struct pico_timeval tv;
|
||||
printf("Starting SNTP query towards %s\n", servername);
|
||||
if(pico_sntp_gettimeofday(&tv) == 0)
|
||||
printf("Wrongly succesfull gettimeofday\n");
|
||||
else
|
||||
printf("Unsuccesfull gettimeofday (not synced)\n");
|
||||
|
||||
if(pico_sntp_sync(servername, &cb_synced) == 0)
|
||||
printf("Succesfull sync call!\n");
|
||||
else
|
||||
printf("Error in sync\n");
|
||||
}
|
||||
#endif
|
||||
/*** END SNTP ***/
|
||||
320
kernel/picotcp/test/examples/tcpbench.c
Normal file
320
kernel/picotcp/test/examples/tcpbench.c
Normal file
@@ -0,0 +1,320 @@
|
||||
#include "utils.h"
|
||||
#include <pico_ipv4.h>
|
||||
#include <pico_ipv6.h>
|
||||
#include <pico_socket.h>
|
||||
/*** START TCP BENCH ***/
|
||||
#define TCP_BENCH_TX 1
|
||||
#define TCP_BENCH_RX 2
|
||||
#define TCP_BENCH_TX_FOREVER 3
|
||||
static char *buffer1;
|
||||
static char *buffer0;
|
||||
|
||||
int tcpbench_mode = 0;
|
||||
struct pico_socket *tcpbench_sock = NULL;
|
||||
static pico_time tcpbench_time_start, tcpbench_time_end;
|
||||
|
||||
void cb_tcpbench(uint16_t ev, struct pico_socket *s)
|
||||
{
|
||||
static int closed = 0;
|
||||
static unsigned long count = 0;
|
||||
uint8_t recvbuf[1500];
|
||||
uint16_t port;
|
||||
char peer[200];
|
||||
/* struct pico_socket *sock_a; */
|
||||
|
||||
static int tcpbench_wr_size = 0;
|
||||
static int tcpbench_rd_size = 0;
|
||||
int tcpbench_w = 0;
|
||||
int tcpbench_r = 0;
|
||||
double tcpbench_time = 0;
|
||||
|
||||
count++;
|
||||
|
||||
if (ev & PICO_SOCK_EV_RD) {
|
||||
do {
|
||||
/* read data, but discard */
|
||||
tcpbench_r = pico_socket_read(s, recvbuf, 1500);
|
||||
if (tcpbench_r > 0) {
|
||||
tcpbench_rd_size += tcpbench_r;
|
||||
}
|
||||
} while (tcpbench_r > 0);
|
||||
if (tcpbench_time_start == 0)
|
||||
tcpbench_time_start = PICO_TIME_MS();
|
||||
|
||||
printf("tcpbench_rd_size = %d \r", tcpbench_rd_size);
|
||||
}
|
||||
|
||||
if (ev & PICO_SOCK_EV_CONN) {
|
||||
if (!IPV6_MODE) {
|
||||
struct pico_ip4 orig;
|
||||
if (tcpbench_mode == TCP_BENCH_TX || tcpbench_mode == TCP_BENCH_TX_FOREVER) {
|
||||
printf("tcpbench> Connection established with server.\n");
|
||||
} else if (tcpbench_mode == TCP_BENCH_RX) {
|
||||
/* sock_a = pico_socket_accept(s, &orig, &port); */
|
||||
pico_socket_accept(s, &orig, &port);
|
||||
pico_ipv4_to_string(peer, orig.addr);
|
||||
printf("tcpbench> Connection established with %s:%d.\n", peer, short_be(port));
|
||||
}
|
||||
} else {
|
||||
struct pico_ip6 orig;
|
||||
if (tcpbench_mode == TCP_BENCH_TX || tcpbench_mode == TCP_BENCH_TX_FOREVER) {
|
||||
printf("tcpbench> Connection established with server.\n");
|
||||
} else if (tcpbench_mode == TCP_BENCH_RX) {
|
||||
/* sock_a = pico_socket_accept(s, &orig, &port); */
|
||||
pico_socket_accept(s, &orig, &port);
|
||||
#ifdef PICO_SUPPORT_IPV6
|
||||
pico_ipv6_to_string(peer, orig.addr);
|
||||
printf("tcpbench> Connection established with [%s]:%d.\n", peer, short_be(port));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ev & PICO_SOCK_EV_FIN) {
|
||||
printf("tcpbench> Socket closed. Exit normally. \n");
|
||||
if (tcpbench_mode == TCP_BENCH_RX) {
|
||||
tcpbench_time_end = PICO_TIME_MS();
|
||||
tcpbench_time = (tcpbench_time_end - tcpbench_time_start) / 1000.0; /* get number of seconds */
|
||||
printf("tcpbench> received %d bytes in %lf seconds\n", tcpbench_rd_size, tcpbench_time);
|
||||
printf("tcpbench> average read throughput %lf kbit/sec\n", ((tcpbench_rd_size * 8.0) / tcpbench_time) / 1000);
|
||||
pico_socket_shutdown(s, PICO_SHUT_WR);
|
||||
printf("tcpbench> Called shutdown write, ev = %d\n", ev);
|
||||
}
|
||||
|
||||
if (!pico_timer_add(5000, deferred_exit, NULL)) {
|
||||
printf("tcpbench> Failed to start exit timer, exiting now\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (ev & PICO_SOCK_EV_ERR) {
|
||||
printf("tcpbench> ---- Socket Error received: %s. Bailing out.\n", strerror(pico_err));
|
||||
if (!pico_err == PICO_ERR_ECONNRESET) {
|
||||
if (pico_timer_add(5000, deferred_exit, NULL)) {
|
||||
printf("tcpbench> Failed to start exit timer, exiting now\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
printf("tcpbench> ---- Socket Error: '%s'. Was unexpected! Something went wrong.\n", strerror(pico_err));
|
||||
exit(2);
|
||||
}
|
||||
}
|
||||
|
||||
if (ev & PICO_SOCK_EV_CLOSE) {
|
||||
printf("tcpbench> event close\n");
|
||||
if (tcpbench_mode == TCP_BENCH_RX) {
|
||||
pico_socket_close(s);
|
||||
printf("tcpbench> Called shutdown write, ev = %d\n", ev);
|
||||
} else if (tcpbench_mode == TCP_BENCH_TX || tcpbench_mode == TCP_BENCH_TX_FOREVER) {
|
||||
pico_socket_close(s);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (ev & PICO_SOCK_EV_WR) {
|
||||
if (((tcpbench_wr_size < TCPSIZ) && (tcpbench_mode == TCP_BENCH_TX)) || tcpbench_mode == TCP_BENCH_TX_FOREVER) {
|
||||
do {
|
||||
tcpbench_w = pico_socket_write(tcpbench_sock, buffer0 + (tcpbench_wr_size % TCPSIZ), TCPSIZ - (tcpbench_wr_size % TCPSIZ));
|
||||
if (tcpbench_w > 0) {
|
||||
tcpbench_wr_size += tcpbench_w;
|
||||
/* printf("tcpbench> SOCKET WRITTEN - %d\n",tcpbench_w); */
|
||||
} else {
|
||||
/* printf("pico_socket_write returned %d\n", tcpbench_w); */
|
||||
}
|
||||
|
||||
if (tcpbench_time_start == 0)
|
||||
tcpbench_time_start = PICO_TIME_MS();
|
||||
} while(tcpbench_w > 0);
|
||||
printf("tcpbench_wr_size = %d \r", tcpbench_wr_size);
|
||||
} else {
|
||||
if (!closed && tcpbench_mode == TCP_BENCH_TX) {
|
||||
tcpbench_time_end = PICO_TIME_MS();
|
||||
pico_socket_shutdown(s, PICO_SHUT_WR);
|
||||
printf("tcpbench> TCPSIZ written\n");
|
||||
printf("tcpbench> Called shutdown()\n");
|
||||
tcpbench_time = (tcpbench_time_end - tcpbench_time_start) / 1000.0; /* get number of seconds */
|
||||
printf("tcpbench> Transmitted %u bytes in %lf seconds\n", TCPSIZ, tcpbench_time);
|
||||
printf("tcpbench> average write throughput %lf kbit/sec\n", ((TCPSIZ * 8.0) / tcpbench_time) / 1000);
|
||||
closed = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void app_tcpbench(char *arg)
|
||||
{
|
||||
struct pico_socket *s;
|
||||
char *dport = NULL;
|
||||
char *dest = NULL;
|
||||
char *mode = NULL;
|
||||
char *nagle = NULL;
|
||||
int port = 0, i;
|
||||
uint16_t port_be = 0;
|
||||
char *nxt;
|
||||
char *sport = NULL;
|
||||
int nagle_off = 1;
|
||||
union {
|
||||
struct pico_ip4 ip4;
|
||||
struct pico_ip6 ip6;
|
||||
} inaddr_any = {
|
||||
.ip4 = {0}, .ip6 = {{0}}
|
||||
};
|
||||
|
||||
nxt = cpy_arg(&mode, arg);
|
||||
|
||||
if ((*mode == 't') || (*mode == 'f')) { /* TEST BENCH SEND MODE */
|
||||
if (*mode == 't')
|
||||
tcpbench_mode = TCP_BENCH_TX;
|
||||
else
|
||||
tcpbench_mode = TCP_BENCH_TX_FOREVER;
|
||||
|
||||
printf("tcpbench> TX\n");
|
||||
|
||||
nxt = cpy_arg(&dest, nxt);
|
||||
if (!dest) {
|
||||
fprintf(stderr, "tcpbench send needs the following format: tcpbench:tx:dst_addr[:dport][:n] -- 'n' is for nagle\n");
|
||||
exit(255);
|
||||
}
|
||||
|
||||
printf ("+++ Dest is %s\n", dest);
|
||||
if (nxt) {
|
||||
printf("Next arg: %s\n", nxt);
|
||||
nxt = cpy_arg(&dport, nxt);
|
||||
printf("Dport: %s\n", dport);
|
||||
}
|
||||
|
||||
if (nxt) {
|
||||
printf("Next arg: %s\n", nxt);
|
||||
nxt = cpy_arg(&nagle, nxt);
|
||||
printf("nagle: %s\n", nagle);
|
||||
if (strlen(nagle) == 1 && nagle[0] == 'n') {
|
||||
nagle_off = 0;
|
||||
printf("Nagle algorithm enabled\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (dport) {
|
||||
port = atoi(dport);
|
||||
port_be = short_be((uint16_t)port);
|
||||
}
|
||||
|
||||
if (port == 0) {
|
||||
port_be = short_be(5555);
|
||||
}
|
||||
|
||||
buffer0 = malloc(TCPSIZ);
|
||||
buffer1 = malloc(TCPSIZ);
|
||||
printf("Buffer1 (%p)\n", buffer1);
|
||||
for (i = 0; i < TCPSIZ; i++) {
|
||||
char c = (i % 26) + 'a';
|
||||
buffer0[i] = c;
|
||||
}
|
||||
memset(buffer1, 'a', TCPSIZ);
|
||||
printf("tcpbench> Connecting to: %s:%d\n", dest, short_be(port_be));
|
||||
|
||||
if (!IPV6_MODE) {
|
||||
struct pico_ip4 server_addr;
|
||||
s = pico_socket_open(PICO_PROTO_IPV4, PICO_PROTO_TCP, &cb_tcpbench);
|
||||
if (!s)
|
||||
exit(1);
|
||||
|
||||
pico_socket_setoption(s, PICO_TCP_NODELAY, &nagle_off);
|
||||
|
||||
/* NOTE: used to set a fixed local port and address
|
||||
local_port = short_be(6666);
|
||||
pico_string_to_ipv4("10.40.0.11", &local_addr.addr);
|
||||
pico_socket_bind(s, &local_addr, &local_port);*/
|
||||
|
||||
pico_string_to_ipv4(dest, &server_addr.addr);
|
||||
pico_socket_connect(s, &server_addr, port_be);
|
||||
} else {
|
||||
struct pico_ip6 server_addr;
|
||||
s = pico_socket_open(PICO_PROTO_IPV6, PICO_PROTO_TCP, &cb_tcpbench);
|
||||
if (!s)
|
||||
exit(1);
|
||||
|
||||
pico_socket_setoption(s, PICO_TCP_NODELAY, &nagle_off);
|
||||
|
||||
/* NOTE: used to set a fixed local port and address
|
||||
local_port = short_be(6666);
|
||||
pico_string_to_ipv4("10.40.0.11", &local_addr.addr);
|
||||
pico_socket_bind(s, &local_addr, &local_port);*/
|
||||
#ifdef PICO_SUPPORT_IPV6
|
||||
pico_string_to_ipv6(dest, server_addr.addr);
|
||||
pico_socket_connect(s, &server_addr, port_be);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
} else if (*mode == 'r') { /* TEST BENCH RECEIVE MODE */
|
||||
int ret;
|
||||
tcpbench_mode = TCP_BENCH_RX;
|
||||
printf("tcpbench> RX\n");
|
||||
|
||||
cpy_arg(&sport, nxt);
|
||||
if (!sport) {
|
||||
fprintf(stderr, "tcpbench receive needs the following format: tcpbench:rx[:dport]\n");
|
||||
exit(255);
|
||||
}
|
||||
|
||||
if (sport) {
|
||||
printf("s-port is %s\n", sport);
|
||||
port = atoi(sport);
|
||||
port_be = short_be((uint16_t)port);
|
||||
printf("tcpbench> Got port %d\n", port);
|
||||
free(sport);
|
||||
}
|
||||
|
||||
if (port == 0) {
|
||||
port_be = short_be(5555);
|
||||
}
|
||||
|
||||
printf("tcpbench> OPEN\n");
|
||||
if (!IPV6_MODE)
|
||||
s = pico_socket_open(PICO_PROTO_IPV4, PICO_PROTO_TCP, &cb_tcpbench);
|
||||
else
|
||||
s = pico_socket_open(PICO_PROTO_IPV6, PICO_PROTO_TCP, &cb_tcpbench);
|
||||
|
||||
if (!s)
|
||||
exit(1);
|
||||
|
||||
printf("tcpbench> BIND\n");
|
||||
if (!IPV6_MODE)
|
||||
ret = pico_socket_bind(s, &inaddr_any.ip4, &port_be);
|
||||
else
|
||||
ret = pico_socket_bind(s, &inaddr_any.ip6, &port_be);
|
||||
|
||||
if (ret < 0) {
|
||||
printf("tcpbench> BIND failed because %s\n", strerror(pico_err));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf("tcpbench> LISTEN\n");
|
||||
if (pico_socket_listen(s, 40) != 0)
|
||||
exit(1);
|
||||
|
||||
printf("tcpbench> listening port %u ...\n", short_be(port_be));
|
||||
} else {
|
||||
printf("tcpbench> wrong mode argument\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
tcpbench_sock = s;
|
||||
|
||||
/* free strdups */
|
||||
if (dport)
|
||||
free(dport);
|
||||
|
||||
if (dest)
|
||||
free (dest);
|
||||
|
||||
if (mode)
|
||||
free (mode);
|
||||
|
||||
if (nagle)
|
||||
free (nagle);
|
||||
|
||||
return;
|
||||
}
|
||||
/*** END TCP BENCH ***/
|
||||
197
kernel/picotcp/test/examples/tcpclient.c
Normal file
197
kernel/picotcp/test/examples/tcpclient.c
Normal file
@@ -0,0 +1,197 @@
|
||||
#include "utils.h"
|
||||
#include <pico_ipv4.h>
|
||||
#include <pico_ipv6.h>
|
||||
#include <pico_socket.h>
|
||||
/*** START TCP CLIENT ***/
|
||||
static char *buffer1;
|
||||
static char *buffer0;
|
||||
|
||||
void compare_results(pico_time __attribute__((unused)) now, void __attribute__((unused)) *arg)
|
||||
{
|
||||
#ifdef CONSISTENCY_CHECK /* TODO: Enable */
|
||||
int i;
|
||||
printf("Calculating result.... (%p)\n", buffer1);
|
||||
|
||||
if (memcmp(buffer0, buffer1, TCPSIZ) == 0)
|
||||
exit(0);
|
||||
|
||||
for (i = 0; i < TCPSIZ; i++) {
|
||||
if (buffer0[i] != buffer1[i]) {
|
||||
fprintf(stderr, "Error at byte %d - %c!=%c\n", i, buffer0[i], buffer1[i]);
|
||||
exit(115);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
exit(0);
|
||||
|
||||
}
|
||||
|
||||
void cb_tcpclient(uint16_t ev, struct pico_socket *s)
|
||||
{
|
||||
static int w_size = 0;
|
||||
static int r_size = 0;
|
||||
static int closed = 0;
|
||||
int r, w;
|
||||
static unsigned long count = 0;
|
||||
|
||||
count++;
|
||||
picoapp_dbg("tcpclient> wakeup %lu, event %u\n", count, ev);
|
||||
|
||||
if (ev & PICO_SOCK_EV_RD) {
|
||||
do {
|
||||
r = pico_socket_read(s, buffer1 + r_size, TCPSIZ - r_size);
|
||||
if (r > 0) {
|
||||
r_size += r;
|
||||
picoapp_dbg("SOCKET READ - %d\n", r_size);
|
||||
}
|
||||
|
||||
if (r < 0)
|
||||
exit(5);
|
||||
} while(r > 0);
|
||||
}
|
||||
|
||||
if (ev & PICO_SOCK_EV_CONN) {
|
||||
printf("Connection established with server.\n");
|
||||
}
|
||||
|
||||
if (ev & PICO_SOCK_EV_FIN) {
|
||||
printf("Socket closed. Exit normally. \n");
|
||||
if (!pico_timer_add(2000, compare_results, NULL)) {
|
||||
printf("Failed to start exit timer, exiting now\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (ev & PICO_SOCK_EV_ERR) {
|
||||
printf("Socket error received: %s. Bailing out.\n", strerror(pico_err));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (ev & PICO_SOCK_EV_CLOSE) {
|
||||
printf("Socket received close from peer - Wrong case if not all client data sent!\n");
|
||||
pico_socket_close(s);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ev & PICO_SOCK_EV_WR) {
|
||||
if (w_size < TCPSIZ) {
|
||||
do {
|
||||
w = pico_socket_write(s, buffer0 + w_size, TCPSIZ - w_size);
|
||||
if (w > 0) {
|
||||
w_size += w;
|
||||
picoapp_dbg("SOCKET WRITTEN - %d\n", w_size);
|
||||
if (w < 0)
|
||||
exit(5);
|
||||
}
|
||||
} while(w > 0);
|
||||
} else {
|
||||
#ifdef INFINITE_TCPTEST
|
||||
w_size = 0;
|
||||
return;
|
||||
#endif
|
||||
if (!closed) {
|
||||
pico_socket_shutdown(s, PICO_SHUT_WR);
|
||||
printf("Called shutdown()\n");
|
||||
closed = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void app_tcpclient(char *arg)
|
||||
{
|
||||
char *daddr = NULL, *dport = NULL;
|
||||
char *nxt = arg;
|
||||
uint16_t send_port = 0, listen_port = short_be(5555);
|
||||
int i = 0, ret = 0, yes = 1;
|
||||
struct pico_socket *s = NULL;
|
||||
union pico_address dst = {
|
||||
.ip4 = {0}, .ip6 = {{0}}
|
||||
};
|
||||
union pico_address inaddr_any = {
|
||||
.ip4 = {0}, .ip6 = {{0}}
|
||||
};
|
||||
|
||||
/* start of argument parsing */
|
||||
if (nxt) {
|
||||
nxt = cpy_arg(&daddr, arg);
|
||||
if (daddr) {
|
||||
if (!IPV6_MODE)
|
||||
pico_string_to_ipv4(daddr, &dst.ip4.addr);
|
||||
|
||||
#ifdef PICO_SUPPORT_IPV6
|
||||
else
|
||||
pico_string_to_ipv6(daddr, dst.ip6.addr);
|
||||
#endif
|
||||
} else {
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
/* missing dest_addr */
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (nxt) {
|
||||
nxt = cpy_arg(&dport, nxt);
|
||||
if (dport && atoi(dport)) {
|
||||
send_port = short_be(atoi(dport));
|
||||
} else {
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
/* missing send_port */
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* end of argument parsing */
|
||||
|
||||
buffer0 = malloc(TCPSIZ);
|
||||
buffer1 = malloc(TCPSIZ);
|
||||
printf("Buffer1 (%p)\n", buffer1);
|
||||
for (i = 0; i < TCPSIZ; i++) {
|
||||
char c = (i % 26) + 'a';
|
||||
buffer0[i] = c;
|
||||
}
|
||||
memset(buffer1, 'a', TCPSIZ);
|
||||
|
||||
printf("Connecting to: %s:%d\n", daddr, short_be(send_port));
|
||||
|
||||
if (!IPV6_MODE)
|
||||
s = pico_socket_open(PICO_PROTO_IPV4, PICO_PROTO_TCP, &cb_tcpclient);
|
||||
else
|
||||
s = pico_socket_open(PICO_PROTO_IPV6, PICO_PROTO_TCP, &cb_tcpclient);
|
||||
|
||||
if (!s) {
|
||||
printf("%s: error opening socket: %s\n", __FUNCTION__, strerror(pico_err));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
pico_socket_setoption(s, PICO_TCP_NODELAY, &yes);
|
||||
|
||||
if (!IPV6_MODE)
|
||||
ret = pico_socket_bind(s, &inaddr_any.ip4, &listen_port);
|
||||
else
|
||||
ret = pico_socket_bind(s, &inaddr_any.ip6, &listen_port);
|
||||
|
||||
if (ret < 0) {
|
||||
printf("%s: error binding socket to port %u: %s\n", __FUNCTION__, short_be(listen_port), strerror(pico_err));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!IPV6_MODE)
|
||||
ret = pico_socket_connect(s, &dst.ip4, send_port);
|
||||
else
|
||||
ret = pico_socket_connect(s, &dst.ip6, send_port);
|
||||
|
||||
if (ret < 0) {
|
||||
printf("%s: error connecting to %s:%u: %s\n", __FUNCTION__, daddr, short_be(send_port), strerror(pico_err));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
out:
|
||||
fprintf(stderr, "tcpclient expects the following format: tcpclient:dest_addr:dest_port\n");
|
||||
exit(255);
|
||||
}
|
||||
/*** END TCP CLIENT ***/
|
||||
178
kernel/picotcp/test/examples/tcpecho.c
Normal file
178
kernel/picotcp/test/examples/tcpecho.c
Normal file
@@ -0,0 +1,178 @@
|
||||
#include "utils.h"
|
||||
#include <pico_socket.h>
|
||||
#include <pico_ipv4.h>
|
||||
/*** START TCP ECHO ***/
|
||||
#define BSIZE (1024 * 10)
|
||||
static char recvbuf[BSIZE];
|
||||
static int pos = 0, len = 0;
|
||||
static int flag = 0;
|
||||
|
||||
int send_tcpecho(struct pico_socket *s)
|
||||
{
|
||||
int w, ww = 0;
|
||||
if (len > pos) {
|
||||
do {
|
||||
w = pico_socket_write(s, recvbuf + pos, len - pos);
|
||||
if (w > 0) {
|
||||
pos += w;
|
||||
ww += w;
|
||||
if (pos >= len) {
|
||||
pos = 0;
|
||||
len = 0;
|
||||
}
|
||||
}
|
||||
} while((w > 0) && (pos < len));
|
||||
}
|
||||
|
||||
return ww;
|
||||
}
|
||||
|
||||
void cb_tcpecho(uint16_t ev, struct pico_socket *s)
|
||||
{
|
||||
int r = 0;
|
||||
|
||||
picoapp_dbg("tcpecho> wakeup ev=%u\n", ev);
|
||||
|
||||
if (ev & PICO_SOCK_EV_RD) {
|
||||
if (flag & PICO_SOCK_EV_CLOSE)
|
||||
printf("SOCKET> EV_RD, FIN RECEIVED\n");
|
||||
|
||||
while (len < BSIZE) {
|
||||
r = pico_socket_read(s, recvbuf + len, BSIZE - len);
|
||||
if (r > 0) {
|
||||
len += r;
|
||||
flag &= ~(PICO_SOCK_EV_RD);
|
||||
} else {
|
||||
flag |= PICO_SOCK_EV_RD;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (flag & PICO_SOCK_EV_WR) {
|
||||
flag &= ~PICO_SOCK_EV_WR;
|
||||
send_tcpecho(s);
|
||||
}
|
||||
}
|
||||
|
||||
if (ev & PICO_SOCK_EV_CONN) {
|
||||
uint32_t ka_val = 0;
|
||||
struct pico_socket *sock_a = {
|
||||
0
|
||||
};
|
||||
struct pico_ip4 orig = {
|
||||
0
|
||||
};
|
||||
uint16_t port = 0;
|
||||
char peer[30] = {
|
||||
0
|
||||
};
|
||||
int yes = 1;
|
||||
|
||||
sock_a = pico_socket_accept(s, &orig, &port);
|
||||
pico_ipv4_to_string(peer, orig.addr);
|
||||
printf("Connection established with %s:%d.\n", peer, short_be(port));
|
||||
pico_socket_setoption(sock_a, PICO_TCP_NODELAY, &yes);
|
||||
/* Set keepalive options */
|
||||
ka_val = 5;
|
||||
pico_socket_setoption(sock_a, PICO_SOCKET_OPT_KEEPCNT, &ka_val);
|
||||
ka_val = 30000;
|
||||
pico_socket_setoption(sock_a, PICO_SOCKET_OPT_KEEPIDLE, &ka_val);
|
||||
ka_val = 5000;
|
||||
pico_socket_setoption(sock_a, PICO_SOCKET_OPT_KEEPINTVL, &ka_val);
|
||||
}
|
||||
|
||||
if (ev & PICO_SOCK_EV_FIN) {
|
||||
printf("Socket closed. Exit normally. \n");
|
||||
if (!pico_timer_add(2000, deferred_exit, NULL)) {
|
||||
printf("Failed to start exit timer, exiting now\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (ev & PICO_SOCK_EV_ERR) {
|
||||
printf("Socket error received: %s. Bailing out.\n", strerror(pico_err));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (ev & PICO_SOCK_EV_CLOSE) {
|
||||
printf("Socket received close from peer.\n");
|
||||
if (flag & PICO_SOCK_EV_RD) {
|
||||
pico_socket_shutdown(s, PICO_SHUT_WR);
|
||||
printf("SOCKET> Called shutdown write, ev = %d\n", ev);
|
||||
}
|
||||
}
|
||||
|
||||
if (ev & PICO_SOCK_EV_WR) {
|
||||
r = send_tcpecho(s);
|
||||
if (r == 0)
|
||||
flag |= PICO_SOCK_EV_WR;
|
||||
else
|
||||
flag &= (~PICO_SOCK_EV_WR);
|
||||
}
|
||||
}
|
||||
|
||||
void app_tcpecho(char *arg)
|
||||
{
|
||||
char *nxt = arg;
|
||||
char *lport = NULL;
|
||||
uint16_t listen_port = 0;
|
||||
int ret = 0, yes = 1;
|
||||
struct pico_socket *s = NULL;
|
||||
union {
|
||||
struct pico_ip4 ip4;
|
||||
struct pico_ip6 ip6;
|
||||
} inaddr_any = {
|
||||
.ip4 = {0}, .ip6 = {{0}}
|
||||
};
|
||||
|
||||
/* start of argument parsing */
|
||||
if (nxt) {
|
||||
nxt = cpy_arg(&lport, nxt);
|
||||
if (lport && atoi(lport)) {
|
||||
listen_port = short_be(atoi(lport));
|
||||
} else {
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
/* missing listen_port */
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* end of argument parsing */
|
||||
|
||||
if (!IPV6_MODE)
|
||||
s = pico_socket_open(PICO_PROTO_IPV4, PICO_PROTO_TCP, &cb_tcpecho);
|
||||
else
|
||||
s = pico_socket_open(PICO_PROTO_IPV6, PICO_PROTO_TCP, &cb_tcpecho);
|
||||
|
||||
if (!s) {
|
||||
printf("%s: error opening socket: %s\n", __FUNCTION__, strerror(pico_err));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
pico_socket_setoption(s, PICO_TCP_NODELAY, &yes);
|
||||
|
||||
|
||||
|
||||
if (!IPV6_MODE)
|
||||
ret = pico_socket_bind(s, &inaddr_any.ip4, &listen_port);
|
||||
else
|
||||
ret = pico_socket_bind(s, &inaddr_any.ip6, &listen_port);
|
||||
|
||||
if (ret < 0) {
|
||||
printf("%s: error binding socket to port %u: %s\n", __FUNCTION__, short_be(listen_port), strerror(pico_err));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (pico_socket_listen(s, 40) != 0) {
|
||||
printf("%s: error listening on port %u\n", __FUNCTION__, short_be(listen_port));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf("Launching PicoTCP echo server\n");
|
||||
return;
|
||||
|
||||
out:
|
||||
fprintf(stderr, "tcpecho expects the following format: tcpecho:listen_port\n");
|
||||
exit(255);
|
||||
}
|
||||
/*** END TCP ECHO ***/
|
||||
485
kernel/picotcp/test/examples/tftp.c
Normal file
485
kernel/picotcp/test/examples/tftp.c
Normal file
@@ -0,0 +1,485 @@
|
||||
#include "utils.h"
|
||||
#include <pico_stack.h>
|
||||
#include <pico_tftp.h>
|
||||
#include <pico_ipv4.h>
|
||||
#include <pico_ipv6.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
/* Let's use linux fs */
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
/*** START TFTP ***/
|
||||
#ifdef PICO_SUPPORT_TFTP
|
||||
#define TFTP_MODE_SRV 0
|
||||
#define TFTP_MODE_CLI 1
|
||||
#define TFTP_MODE_PSH 2
|
||||
#define TFTP_TX_COUNT 2000
|
||||
#define TFTP_PAYLOAD_SIZE 512
|
||||
unsigned char tftp_txbuf[TFTP_PAYLOAD_SIZE];
|
||||
static uint16_t family;
|
||||
|
||||
struct command_t {
|
||||
char operation;
|
||||
char *filename;
|
||||
union pico_address server_address;
|
||||
struct command_t *next;
|
||||
};
|
||||
|
||||
struct note_t {
|
||||
char *filename;
|
||||
int fd;
|
||||
char direction;
|
||||
int32_t filesize;
|
||||
struct note_t *next;
|
||||
};
|
||||
|
||||
struct note_t *clipboard = NULL;
|
||||
|
||||
struct note_t *add_note(const char *filename, int fd, char direction)
|
||||
{
|
||||
struct note_t *note = PICO_ZALLOC(sizeof(struct note_t));
|
||||
|
||||
note->filename = strdup(filename);
|
||||
note->fd = fd;
|
||||
note->direction = direction;
|
||||
note->filesize = 0;
|
||||
note->next = clipboard;
|
||||
clipboard = note;
|
||||
return note;
|
||||
}
|
||||
|
||||
void del_note(struct note_t *note)
|
||||
{
|
||||
struct note_t *prev;
|
||||
|
||||
if (note == clipboard)
|
||||
{
|
||||
clipboard = clipboard->next;
|
||||
if (note->filename)
|
||||
free (note->filename);
|
||||
|
||||
PICO_FREE(note);
|
||||
} else {
|
||||
for (prev = clipboard; prev->next; prev = prev->next)
|
||||
if (prev->next == note) {
|
||||
prev->next = note->next;
|
||||
if (note->filename)
|
||||
free (note->filename);
|
||||
|
||||
PICO_FREE(note);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
struct command_t *add_command(struct command_t *commands, char operation,
|
||||
char *filename, union pico_address *server_address)
|
||||
{
|
||||
struct command_t *command = PICO_ZALLOC(sizeof(struct command_t));
|
||||
|
||||
command->operation = operation;
|
||||
command->filename = filename;
|
||||
memcpy(&command->server_address, server_address, sizeof(union pico_address));
|
||||
command->next = commands;
|
||||
return command;
|
||||
}
|
||||
|
||||
int32_t get_filesize(const char *filename)
|
||||
{
|
||||
int ret;
|
||||
struct stat buf;
|
||||
|
||||
ret = stat(filename, &buf);
|
||||
if (ret)
|
||||
return -1;
|
||||
|
||||
return buf.st_size;
|
||||
}
|
||||
|
||||
struct note_t *setup_transfer(char operation, const char *filename)
|
||||
{
|
||||
int fd;
|
||||
|
||||
printf("operation %c\n", operation);
|
||||
fd = open(filename, (toupper(operation) == 'T') ? O_RDONLY : O_WRONLY | O_EXCL | O_CREAT, 0666);
|
||||
if (fd < 0) {
|
||||
perror("open");
|
||||
fprintf(stderr, "Unable to handle file %s\n", filename);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return add_note(filename, fd, operation);
|
||||
}
|
||||
|
||||
int cb_tftp_tx(struct pico_tftp_session *session, uint16_t event, uint8_t *block, int32_t len, void *arg)
|
||||
{
|
||||
struct note_t *note = (struct note_t *) arg;
|
||||
|
||||
if (event != PICO_TFTP_EV_OK) {
|
||||
fprintf(stderr, "TFTP: Error %" PRIu16 ": %s\n", event, block);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
len = read(note->fd, tftp_txbuf, PICO_TFTP_PAYLOAD_SIZE);
|
||||
|
||||
if (len >= 0) {
|
||||
note->filesize += len;
|
||||
pico_tftp_send(session, tftp_txbuf, len);
|
||||
if (len < PICO_TFTP_PAYLOAD_SIZE) {
|
||||
printf("TFTP: file %s (%" PRId32 " bytes) TX transfer complete!\n", note->filename, note->filesize);
|
||||
close(note->fd);
|
||||
del_note(note);
|
||||
}
|
||||
} else {
|
||||
perror("read");
|
||||
fprintf(stderr, "Filesystem error reading file %s, cancelling current transfer\n", note->filename);
|
||||
pico_tftp_abort(session, TFTP_ERR_EACC, "Error on read");
|
||||
del_note(note);
|
||||
}
|
||||
|
||||
if (!clipboard) {
|
||||
if (!pico_timer_add(3000, deferred_exit, NULL)) {
|
||||
printf("Failed to start exit timer, exiting now\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
int cb_tftp_tx_opt(struct pico_tftp_session *session, uint16_t event, uint8_t *block, int32_t len, void *arg)
|
||||
{
|
||||
int ret;
|
||||
int32_t filesize;
|
||||
|
||||
if (event == PICO_TFTP_EV_OPT) {
|
||||
ret = pico_tftp_get_option(session, PICO_TFTP_OPTION_FILE, &filesize);
|
||||
if (ret)
|
||||
printf("TFTP: Option filesize is not used\n");
|
||||
else
|
||||
printf("TFTP: We expect to transmit %" PRId32 " bytes\n", filesize);
|
||||
|
||||
event = PICO_TFTP_EV_OK;
|
||||
}
|
||||
|
||||
return cb_tftp_tx(session, event, block, len, arg);
|
||||
}
|
||||
|
||||
int cb_tftp_rx(struct pico_tftp_session *session, uint16_t event, uint8_t *block, int32_t len, void *arg)
|
||||
{
|
||||
struct note_t *note = (struct note_t *) arg;
|
||||
int ret;
|
||||
|
||||
if (event != PICO_TFTP_EV_OK) {
|
||||
fprintf(stderr, "TFTP: Error %" PRIu16 ": %s\n", event, block);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!note)
|
||||
return 0;
|
||||
|
||||
note->filesize += len;
|
||||
if (write(note->fd, block, len) < 0) {
|
||||
perror("write");
|
||||
fprintf(stderr, "Filesystem error writing file %s, cancelling current transfer\n", note->filename);
|
||||
pico_tftp_abort(session, TFTP_ERR_EACC, "Error on write");
|
||||
del_note(note);
|
||||
} else {
|
||||
if (len != PICO_TFTP_PAYLOAD_SIZE) {
|
||||
printf("TFTP: file %s (%" PRId32 " bytes) RX transfer complete!\n", note->filename, note->filesize);
|
||||
close(note->fd);
|
||||
del_note(note);
|
||||
}
|
||||
}
|
||||
|
||||
if (!clipboard) {
|
||||
if (!pico_timer_add(3000, deferred_exit, NULL)) {
|
||||
printf("Failed to start exit timer, exiting now\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
int cb_tftp_rx_opt(struct pico_tftp_session *session, uint16_t event, uint8_t *block, int32_t len, void *arg)
|
||||
{
|
||||
int ret;
|
||||
int32_t filesize;
|
||||
|
||||
if (event == PICO_TFTP_EV_OPT) {
|
||||
ret = pico_tftp_get_option(session, PICO_TFTP_OPTION_FILE, &filesize);
|
||||
if (ret)
|
||||
printf("TFTP: Option filesize is not used\n");
|
||||
else
|
||||
printf("TFTP: We expect to receive %" PRId32 " bytes\n", filesize);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return cb_tftp_rx(session, event, block, len, arg);
|
||||
}
|
||||
|
||||
struct pico_tftp_session *make_session_or_die(union pico_address *addr, uint16_t family)
|
||||
{
|
||||
struct pico_tftp_session *session;
|
||||
|
||||
session = pico_tftp_session_setup(addr, family);
|
||||
if (!session) {
|
||||
fprintf(stderr, "TFTP: Error in session setup\n");
|
||||
exit(3);
|
||||
}
|
||||
|
||||
return session;
|
||||
}
|
||||
|
||||
struct note_t *transfer_prepare(struct pico_tftp_session **psession, char operation, const char *filename, union pico_address *addr, uint16_t family)
|
||||
{
|
||||
struct note_t *note;
|
||||
|
||||
note = setup_transfer(operation, filename);
|
||||
*psession = make_session_or_die(addr, family);
|
||||
return note;
|
||||
}
|
||||
|
||||
void start_rx(struct pico_tftp_session *session, const char *filename, uint16_t port,
|
||||
int (*rx_callback)(struct pico_tftp_session *session, uint16_t err, uint8_t *block, int32_t len, void *arg),
|
||||
struct note_t *note)
|
||||
{
|
||||
if (pico_tftp_start_rx(session, port, filename, rx_callback, note)) {
|
||||
fprintf(stderr, "TFTP: Error in initialization\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
void start_tx(struct pico_tftp_session *session, const char *filename, uint16_t port,
|
||||
int (*tx_callback)(struct pico_tftp_session *session, uint16_t err, uint8_t *block, int32_t len, void *arg),
|
||||
struct note_t *note)
|
||||
{
|
||||
if (pico_tftp_start_tx(session, port, filename, tx_callback, note)) {
|
||||
fprintf(stderr, "TFTP: Error in initialization\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
void tftp_listen_cb(union pico_address *addr, uint16_t port, uint16_t opcode, char *filename, int32_t len)
|
||||
{
|
||||
struct note_t *note;
|
||||
struct pico_tftp_session *session;
|
||||
|
||||
printf("TFTP listen callback (BASIC) from remote port %" PRIu16 ".\n", short_be(port));
|
||||
if (opcode == PICO_TFTP_RRQ) {
|
||||
printf("Received TFTP get request for %s\n", filename);
|
||||
note = transfer_prepare(&session, 't', filename, addr, family);
|
||||
start_tx(session, filename, port, cb_tftp_tx, note);
|
||||
} else if (opcode == PICO_TFTP_WRQ) {
|
||||
printf("Received TFTP put request for %s\n", filename);
|
||||
note = transfer_prepare(&session, 'r', filename, addr, family);
|
||||
start_rx(session, filename, port, cb_tftp_rx, note);
|
||||
}
|
||||
}
|
||||
|
||||
void tftp_listen_cb_opt(union pico_address *addr, uint16_t port, uint16_t opcode, char *filename, int32_t len)
|
||||
{
|
||||
struct note_t *note;
|
||||
struct pico_tftp_session *session;
|
||||
int options;
|
||||
uint8_t timeout;
|
||||
int32_t filesize;
|
||||
int ret;
|
||||
|
||||
printf("TFTP listen callback (OPTIONS) from remote port %" PRIu16 ".\n", short_be(port));
|
||||
/* declare the options we want to support */
|
||||
ret = pico_tftp_parse_request_args(filename, len, &options, &timeout, &filesize);
|
||||
if (ret)
|
||||
pico_tftp_reject_request(addr, port, TFTP_ERR_EOPT, "Malformed request");
|
||||
|
||||
if (opcode == PICO_TFTP_RRQ) {
|
||||
printf("Received TFTP get request for %s\n", filename);
|
||||
note = transfer_prepare(&session, 'T', filename, addr, family);
|
||||
|
||||
if (options & PICO_TFTP_OPTION_TIME)
|
||||
pico_tftp_set_option(session, PICO_TFTP_OPTION_TIME, timeout);
|
||||
|
||||
if (options & PICO_TFTP_OPTION_FILE) {
|
||||
ret = get_filesize(filename);
|
||||
if (ret < 0) {
|
||||
pico_tftp_reject_request(addr, port, TFTP_ERR_ENOENT, "File not found");
|
||||
return;
|
||||
}
|
||||
|
||||
pico_tftp_set_option(session, PICO_TFTP_OPTION_FILE, ret);
|
||||
}
|
||||
|
||||
start_tx(session, filename, port, cb_tftp_tx_opt, note);
|
||||
} else { /* opcode == PICO_TFTP_WRQ */
|
||||
printf("Received TFTP put request for %s\n", filename);
|
||||
|
||||
note = transfer_prepare(&session, 'R', filename, addr, family);
|
||||
if (options & PICO_TFTP_OPTION_TIME)
|
||||
pico_tftp_set_option(session, PICO_TFTP_OPTION_TIME, timeout);
|
||||
|
||||
if (options & PICO_TFTP_OPTION_FILE)
|
||||
pico_tftp_set_option(session, PICO_TFTP_OPTION_FILE, filesize);
|
||||
|
||||
start_rx(session, filename, port, cb_tftp_rx_opt, note);
|
||||
}
|
||||
}
|
||||
|
||||
void print_usage(int exit_code)
|
||||
{
|
||||
printf("\nUsage: tftp:OPTION:[OPTION]...\n"
|
||||
"\nOtions can be repeated. Every option may be one of the following:\n"
|
||||
"\ts\t\t\t starts the basic server (RFC1350)\n"
|
||||
"\tS\t\t\t starts the server with option handling capability\n"
|
||||
"\tt:file:ip\t\t PUT request (without options) for file to server ip\n"
|
||||
"\tT:file:ip\t\t PUT request for file to server ip\n"
|
||||
"\tr:file:ip\t\t GET request (without options) for file to server ip\n"
|
||||
"\tR:file:ip\t\t GET request for file to server ip\n"
|
||||
"Example:\n"
|
||||
"\t\t tftp:S:T:firstFile:10.40.0.2:R:another.file:10.40.0.5:T:secondFile:10.40.0.2\n\n");
|
||||
exit(exit_code);
|
||||
}
|
||||
|
||||
struct command_t *parse_arguments_recursive(struct command_t *commands, char *arg)
|
||||
{
|
||||
char *next;
|
||||
char *operation;
|
||||
char *filename;
|
||||
char *address;
|
||||
static union pico_address remote_address;
|
||||
int ret;
|
||||
struct command_t *new_cmd = NULL;
|
||||
|
||||
if (!arg)
|
||||
return commands;
|
||||
|
||||
next = cpy_arg(&operation, arg);
|
||||
switch (*operation) {
|
||||
case 'S':
|
||||
case 's':
|
||||
filename = address = NULL;
|
||||
break;
|
||||
case 'T':
|
||||
case 'R':
|
||||
case 't':
|
||||
case 'r':
|
||||
if (!next) {
|
||||
fprintf(stderr, "Incomplete client command %s (filename componet is missing)\n", arg);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
next = cpy_arg(&filename, next);
|
||||
if (!next) {
|
||||
fprintf(stderr, "Incomplete client command %s (address component is missing)\n", arg);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
next = cpy_arg(&address, next);
|
||||
if (!IPV6_MODE)
|
||||
ret = pico_string_to_ipv4(address, &remote_address.ip4.addr);
|
||||
else
|
||||
ret = pico_string_to_ipv6(address, remote_address.ip6.addr);
|
||||
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Invalid IP address %s\n", address);
|
||||
print_usage(2);
|
||||
}
|
||||
|
||||
if (address)
|
||||
free(address);
|
||||
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Invalid command %s\n", operation);
|
||||
return NULL;
|
||||
};
|
||||
|
||||
new_cmd = add_command(commands, *operation, filename, &remote_address);
|
||||
free(operation);
|
||||
return parse_arguments_recursive(new_cmd, next);
|
||||
}
|
||||
|
||||
struct command_t *parse_arguments(char *arg)
|
||||
{
|
||||
struct command_t *reversed = parse_arguments_recursive(NULL, arg);
|
||||
struct command_t *commands = NULL;
|
||||
struct command_t *current;
|
||||
|
||||
if (!reversed) {
|
||||
fprintf(stderr, "Wrong command line!\n");
|
||||
print_usage(1);
|
||||
}
|
||||
|
||||
while (reversed) {
|
||||
current = reversed;
|
||||
reversed = reversed->next;
|
||||
current->next = commands;
|
||||
commands = current;
|
||||
}
|
||||
return commands;
|
||||
}
|
||||
|
||||
void app_tftp(char *arg)
|
||||
{
|
||||
struct command_t *commands, *old_cmd;
|
||||
struct note_t *note;
|
||||
struct pico_tftp_session *session;
|
||||
int is_server_enabled = 0;
|
||||
int filesize;
|
||||
|
||||
family = IPV6_MODE ? PICO_PROTO_IPV6 : PICO_PROTO_IPV4;
|
||||
|
||||
commands = parse_arguments(arg);
|
||||
while (commands) {
|
||||
|
||||
if (toupper(commands->operation) != 'S')
|
||||
note = transfer_prepare(&session, commands->operation, commands->filename, &commands->server_address, family);
|
||||
|
||||
switch (commands->operation) {
|
||||
case 'S':
|
||||
case 's':
|
||||
if (!is_server_enabled) {
|
||||
pico_tftp_listen(PICO_PROTO_IPV4, (commands->operation == 'S') ? tftp_listen_cb_opt : tftp_listen_cb);
|
||||
is_server_enabled = 1;
|
||||
}
|
||||
|
||||
break;
|
||||
case 'T':
|
||||
filesize = get_filesize(commands->filename);
|
||||
if (filesize < 0) {
|
||||
fprintf(stderr, "TFTP: unable to read size of file %s\n", commands->filename);
|
||||
exit(3);
|
||||
}
|
||||
|
||||
pico_tftp_set_option(session, PICO_TFTP_OPTION_FILE, filesize);
|
||||
start_tx(session, commands->filename, short_be(PICO_TFTP_PORT), cb_tftp_tx_opt, note);
|
||||
break;
|
||||
case 't':
|
||||
start_tx(session, commands->filename, short_be(PICO_TFTP_PORT), cb_tftp_tx, note);
|
||||
break;
|
||||
case 'R':
|
||||
pico_tftp_set_option(session, PICO_TFTP_OPTION_FILE, 0);
|
||||
start_rx(session, commands->filename, short_be(PICO_TFTP_PORT), cb_tftp_rx_opt, note);
|
||||
break;
|
||||
case 'r':
|
||||
start_rx(session, commands->filename, short_be(PICO_TFTP_PORT), cb_tftp_rx, note);
|
||||
}
|
||||
old_cmd = commands;
|
||||
commands = commands->next;
|
||||
if (old_cmd->filename)
|
||||
free(old_cmd->filename);
|
||||
|
||||
/* commands are allocated using PICO_ZALLOC, so use PICO_FREE */
|
||||
PICO_FREE(old_cmd);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
/* END TFTP */
|
||||
290
kernel/picotcp/test/examples/udp_client.c
Normal file
290
kernel/picotcp/test/examples/udp_client.c
Normal file
@@ -0,0 +1,290 @@
|
||||
#include "utils.h"
|
||||
#include <pico_ipv4.h>
|
||||
#include <pico_ipv6.h>
|
||||
#include <pico_socket.h>
|
||||
|
||||
/*** START UDP CLIENT ***/
|
||||
/*
|
||||
* udpclient expects the following format: udpclient:dest_addr:sendto_port[:listen_port:datasize:loops:subloops]
|
||||
* dest_addr: IP address to send datagrams to
|
||||
* sendto_port: port number to send datagrams to
|
||||
* listen_port [OPTIONAL]: port number on which the udpclient listens
|
||||
* datasize [OPTIONAL]: size of the data given to the socket in one go
|
||||
* loops [OPTIONAL]: number of intervals in which data is send
|
||||
* subloops [OPTIONAL]: number of sends in one interval
|
||||
*
|
||||
* REMARK: once an optional parameter is given, all optional parameters need a value!
|
||||
*
|
||||
* f.e.: ./build/test/picoapp.elf --vde pic0:/tmp/pic0.ctl:10.40.0.2:255.255.255.0: -a udpclient:10.40.0.3:6667:6667:1400:100:10
|
||||
*/
|
||||
|
||||
struct udpclient_pas *udpclient_pas;
|
||||
|
||||
static int exit_retry = 0;
|
||||
|
||||
static void request_exit_echo(pico_time now, void *arg)
|
||||
{
|
||||
struct pico_socket *s = (struct pico_socket *)arg;
|
||||
char end[4] = "end";
|
||||
pico_socket_send(s, end, 4);
|
||||
if (exit_retry++ > 3) {
|
||||
if (!pico_timer_add(1000, deferred_exit, udpclient_pas)) {
|
||||
printf("Failed to start exit timer, exiting now\n");
|
||||
exit(1);
|
||||
}
|
||||
} else {
|
||||
if (!pico_timer_add(1000, request_exit_echo, s)) {
|
||||
printf("Failed to start request_exit_echo timer, sending request now\n");
|
||||
request_exit_echo((pico_time)0, NULL);
|
||||
exit(1);
|
||||
}
|
||||
printf("%s: requested exit of echo\n", __FUNCTION__);
|
||||
}
|
||||
}
|
||||
|
||||
void udpclient_send(pico_time __attribute__((unused)) now, void __attribute__((unused)) *arg)
|
||||
{
|
||||
struct pico_socket *s = udpclient_pas->s;
|
||||
char *buf = NULL;
|
||||
int i = 0, w = 0;
|
||||
static uint16_t loop = 0;
|
||||
|
||||
if (++loop > udpclient_pas->loops) {
|
||||
if (!pico_timer_add(1000, request_exit_echo, s)) {
|
||||
printf("Failed to start request_exit_echo timer, sending request now\n");
|
||||
request_exit_echo((pico_time)0, NULL);
|
||||
exit(1);
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
buf = calloc(1, udpclient_pas->datasize);
|
||||
if (!buf) {
|
||||
printf("%s: no memory available\n", __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
memset(buf, '1', udpclient_pas->datasize);
|
||||
picoapp_dbg("%s: performing loop %u\n", __FUNCTION__, loop);
|
||||
for (i = 0; i < udpclient_pas->subloops; i++) {
|
||||
w = pico_socket_send(s, buf, udpclient_pas->datasize);
|
||||
if (w <= 0)
|
||||
break;
|
||||
}
|
||||
picoapp_dbg("%s: written %u byte(s) in each of %u subloops\n", __FUNCTION__, udpclient_pas->datasize, i);
|
||||
free(buf);
|
||||
}
|
||||
|
||||
if (!pico_timer_add(100, udpclient_send, NULL)) {
|
||||
printf("Failed to start send timer, sending exit request to echo and exiting\n");
|
||||
request_exit_echo((pico_time)0, NULL);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
void cb_udpclient(uint16_t ev, struct pico_socket *s)
|
||||
{
|
||||
char *recvbuf = NULL;
|
||||
int r = 0;
|
||||
|
||||
if (ev & PICO_SOCK_EV_RD) {
|
||||
recvbuf = calloc(1, udpclient_pas->datasize);
|
||||
if (!recvbuf) {
|
||||
printf("%s: no memory available\n", __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
do {
|
||||
r = pico_socket_recv(s, recvbuf, udpclient_pas->datasize);
|
||||
} while ( r > 0);
|
||||
free(recvbuf);
|
||||
}
|
||||
|
||||
if (ev == PICO_SOCK_EV_ERR) {
|
||||
printf("Socket Error received. Bailing out.\n");
|
||||
free(udpclient_pas);
|
||||
exit(7);
|
||||
}
|
||||
}
|
||||
|
||||
void app_udpclient(char *arg)
|
||||
{
|
||||
char *daddr = NULL, *lport = NULL, *sport = NULL, *s_datasize = NULL, *s_loops = NULL, *s_subloops = NULL;
|
||||
char *nxt = arg;
|
||||
char sinaddr_any[40] = {
|
||||
0
|
||||
};
|
||||
uint16_t listen_port = 0;
|
||||
int ret = 0;
|
||||
|
||||
udpclient_pas = calloc(1, sizeof(struct udpclient_pas));
|
||||
if (!udpclient_pas) {
|
||||
printf("%s: no memory available\n", __FUNCTION__);
|
||||
exit(255);
|
||||
}
|
||||
|
||||
udpclient_pas->s = NULL;
|
||||
udpclient_pas->loops = 100;
|
||||
udpclient_pas->subloops = 10;
|
||||
udpclient_pas->datasize = 1400;
|
||||
|
||||
/* start of argument parsing */
|
||||
if (nxt) {
|
||||
nxt = cpy_arg(&daddr, arg);
|
||||
if (daddr) {
|
||||
if (!IPV6_MODE)
|
||||
pico_string_to_ipv4(daddr, &udpclient_pas->dst.ip4.addr);
|
||||
|
||||
#ifdef PICO_SUPPORT_IPV6
|
||||
else
|
||||
pico_string_to_ipv6(daddr, udpclient_pas->dst.ip6.addr);
|
||||
#endif
|
||||
} else {
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
/* missing dest_addr */
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (nxt) {
|
||||
nxt = cpy_arg(&sport, nxt);
|
||||
if (sport && atoi(sport)) {
|
||||
udpclient_pas->sport = short_be(atoi(sport));
|
||||
} else {
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
/* missing send_port */
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (nxt) {
|
||||
nxt = cpy_arg(&lport, nxt);
|
||||
if (lport && atoi(lport)) {
|
||||
listen_port = short_be(atoi(lport));
|
||||
} else {
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
/* missing listen_port, use default */
|
||||
listen_port = 0;
|
||||
}
|
||||
|
||||
if (nxt) {
|
||||
nxt = cpy_arg(&s_datasize, nxt);
|
||||
if (s_datasize && atoi(s_datasize)) {
|
||||
udpclient_pas->datasize = atoi(s_datasize);
|
||||
} else {
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
/* missing datasize, incomplete optional parameters? -> exit */
|
||||
if (lport)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (nxt) {
|
||||
nxt = cpy_arg(&s_loops, nxt);
|
||||
if (s_loops && atoi(s_loops)) {
|
||||
udpclient_pas->loops = atoi(s_loops);
|
||||
} else {
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
/* missing loops, incomplete optional parameters? -> exit */
|
||||
if (s_datasize)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (nxt) {
|
||||
nxt = cpy_arg(&s_subloops, nxt);
|
||||
if (s_subloops && atoi(s_subloops)) {
|
||||
udpclient_pas->subloops = atoi(s_subloops);
|
||||
} else {
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
/* missing subloops, incomplete optional parameters? -> exit */
|
||||
if (s_loops)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* end of argument parsing */
|
||||
|
||||
if (!IPV6_MODE)
|
||||
pico_ipv4_to_string(sinaddr_any, inaddr_any.addr);
|
||||
|
||||
#ifdef PICO_SUPPORT_IPV6
|
||||
else
|
||||
pico_ipv6_to_string(sinaddr_any, inaddr6_any.addr);
|
||||
#endif
|
||||
|
||||
if (!IPV6_MODE)
|
||||
udpclient_pas->s = pico_socket_open(PICO_PROTO_IPV4, PICO_PROTO_UDP, &cb_udpclient);
|
||||
else
|
||||
udpclient_pas->s = pico_socket_open(PICO_PROTO_IPV6, PICO_PROTO_UDP, &cb_udpclient);
|
||||
|
||||
if (!udpclient_pas->s) {
|
||||
printf("%s: error opening socket: %s\n", __FUNCTION__, strerror(pico_err));
|
||||
free(udpclient_pas);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!IPV6_MODE)
|
||||
ret = pico_socket_bind(udpclient_pas->s, &inaddr_any, &listen_port);
|
||||
else
|
||||
ret = pico_socket_bind(udpclient_pas->s, &inaddr6_any, &listen_port);
|
||||
|
||||
if (ret < 0) {
|
||||
free(udpclient_pas);
|
||||
printf("%s: error binding socket to %s:%u: %s\n", __FUNCTION__, sinaddr_any, short_be(listen_port), strerror(pico_err));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!IPV6_MODE)
|
||||
ret = pico_socket_connect(udpclient_pas->s, &udpclient_pas->dst.ip4, udpclient_pas->sport);
|
||||
else
|
||||
ret = pico_socket_connect(udpclient_pas->s, &udpclient_pas->dst.ip6, udpclient_pas->sport);
|
||||
|
||||
if (ret < 0) {
|
||||
printf("%s: error connecting to [%s]:%u: %s\n", __FUNCTION__, daddr, short_be(udpclient_pas->sport), strerror(pico_err));
|
||||
free(udpclient_pas);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf("\n%s: UDP client launched. Sending packets of %u bytes in %u loops and %u subloops to %s:%u\n\n",
|
||||
__FUNCTION__, udpclient_pas->datasize, udpclient_pas->loops, udpclient_pas->subloops, daddr, short_be(udpclient_pas->sport));
|
||||
|
||||
if (!pico_timer_add(100, udpclient_send, NULL)) {
|
||||
printf("Failed to start send timer, sending exit request to echo and exiting\n");
|
||||
request_exit_echo((pico_time)0, NULL);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* free strdups */
|
||||
if (daddr)
|
||||
free (daddr);
|
||||
|
||||
if (lport)
|
||||
free (lport);
|
||||
|
||||
if (sport)
|
||||
free (sport);
|
||||
|
||||
if (s_datasize)
|
||||
free (s_datasize);
|
||||
|
||||
if (s_loops)
|
||||
free (s_loops);
|
||||
|
||||
if (s_subloops)
|
||||
free (s_subloops);
|
||||
|
||||
return;
|
||||
|
||||
out:
|
||||
fprintf(stderr, "udpclient expects the following format: udpclient:dest_addr:dest_port[:listen_port:datasize:loops:subloops]\n");
|
||||
free(udpclient_pas);
|
||||
exit(255);
|
||||
}
|
||||
/*** END UDP CLIENT ***/
|
||||
216
kernel/picotcp/test/examples/udp_echo.c
Normal file
216
kernel/picotcp/test/examples/udp_echo.c
Normal file
@@ -0,0 +1,216 @@
|
||||
#include "utils.h"
|
||||
#include <pico_ipv4.h>
|
||||
#include <pico_ipv6.h>
|
||||
#include <pico_socket.h>
|
||||
|
||||
/**** START UDP ECHO ****/
|
||||
/*
|
||||
* udpecho expects the following format: udpecho:bind_addr:listen_port[:sendto_port:datasize]
|
||||
* bind_addr: IP address to bind to
|
||||
* listen_port: port number on which the udpecho listens
|
||||
* sendto_port [OPTIONAL]: port number to echo datagrams to (echo to originating IP address)
|
||||
* datasize [OPTIONAL]: max size of the data red from the socket in one go
|
||||
*
|
||||
* REMARK: once an optional parameter is given, all optional parameters need a value!
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
static int udpecho_exit = 0;
|
||||
|
||||
struct udpecho_pas *udpecho_pas;
|
||||
|
||||
void cb_udpecho(uint16_t ev, struct pico_socket *s)
|
||||
{
|
||||
char *recvbuf = NULL;
|
||||
uint16_t port = 0;
|
||||
int r = 0;
|
||||
union {
|
||||
struct pico_ip4 ip4;
|
||||
struct pico_ip6 ip6;
|
||||
} peer;
|
||||
if (udpecho_exit)
|
||||
return;
|
||||
|
||||
if (ev == PICO_SOCK_EV_RD) {
|
||||
recvbuf = calloc(1, udpecho_pas->datasize);
|
||||
if (!recvbuf) {
|
||||
printf("%s: no memory available\n", __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
do {
|
||||
r = pico_socket_recvfrom(s, recvbuf, udpecho_pas->datasize, IPV6_MODE ? (void *)peer.ip6.addr : (void *)&peer.ip4.addr, &port);
|
||||
/* printf("UDP recvfrom returned %d\n", r); */
|
||||
if (r > 0) {
|
||||
if (strncmp(recvbuf, "end", 3) == 0) {
|
||||
printf("Client requested to exit... test successful.\n");
|
||||
if (!pico_timer_add(1000, deferred_exit, udpecho_pas)) {
|
||||
printf("Failed to start exit timer, exiting now\n");
|
||||
exit(1);
|
||||
}
|
||||
udpecho_exit++;
|
||||
}
|
||||
|
||||
pico_socket_sendto(s, recvbuf, r, IPV6_MODE ? (void *)peer.ip6.addr : (void *)&peer.ip4.addr, port);
|
||||
}
|
||||
} while (r > 0);
|
||||
free(recvbuf);
|
||||
}
|
||||
|
||||
if (ev == PICO_SOCK_EV_ERR) {
|
||||
printf("Socket Error received. Bailing out.\n");
|
||||
free(udpecho_pas);
|
||||
exit(7);
|
||||
}
|
||||
|
||||
picoapp_dbg("%s: received packet from %08X:%u\n", __FUNCTION__, long_be(peer), short_be(port));
|
||||
}
|
||||
|
||||
void app_udpecho(char *arg)
|
||||
{
|
||||
char *baddr = NULL, *lport = NULL, *sport = NULL, *s_datasize = NULL;
|
||||
char *nxt = arg;
|
||||
uint16_t listen_port = 0;
|
||||
struct pico_ip4 inaddr_bind = { };
|
||||
struct pico_ip6 inaddr_bind6 = { };
|
||||
int ret = 0;
|
||||
|
||||
udpecho_pas = calloc(1, sizeof(struct udpecho_pas));
|
||||
if (!udpecho_pas) {
|
||||
printf("%s: no memory available\n", __FUNCTION__);
|
||||
exit(255);
|
||||
}
|
||||
|
||||
udpecho_pas->s = NULL;
|
||||
udpecho_pas->sendto_port = 0;
|
||||
udpecho_pas->datasize = 5000;
|
||||
|
||||
/* start of argument parsing */
|
||||
if (nxt) {
|
||||
nxt = cpy_arg(&baddr, nxt);
|
||||
if (baddr) {
|
||||
if (!IPV6_MODE)
|
||||
pico_string_to_ipv4(baddr, &inaddr_bind.addr);
|
||||
|
||||
#ifdef PICO_SUPPORT_IPV6
|
||||
else
|
||||
pico_string_to_ipv6(baddr, inaddr_bind6.addr);
|
||||
#endif
|
||||
} else {
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
/* missing bind_addr */
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (nxt) {
|
||||
nxt = cpy_arg(&lport, nxt);
|
||||
if (lport && atoi(lport)) {
|
||||
listen_port = short_be(atoi(lport));
|
||||
} else {
|
||||
listen_port = short_be(5555);
|
||||
}
|
||||
} else {
|
||||
/* missing listen_port */
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (nxt) {
|
||||
nxt = cpy_arg(&sport, nxt);
|
||||
if (sport && atoi(sport)) {
|
||||
udpecho_pas->sendto_port = atoi(sport);
|
||||
} else {
|
||||
/* incorrect send_port */
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
/* missing send_port, use default */
|
||||
}
|
||||
|
||||
if (nxt) {
|
||||
nxt = cpy_arg(&s_datasize, nxt);
|
||||
if (s_datasize && atoi(s_datasize)) {
|
||||
udpecho_pas->datasize = atoi(s_datasize);
|
||||
} else {
|
||||
/* incorrect datasize */
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
/* missing datasize, incomplete optional parameters? -> exit */
|
||||
if (sport)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* end of argument parsing */
|
||||
if (!IPV6_MODE)
|
||||
udpecho_pas->s = pico_socket_open(PICO_PROTO_IPV4, PICO_PROTO_UDP, &cb_udpecho);
|
||||
else
|
||||
udpecho_pas->s = pico_socket_open(PICO_PROTO_IPV6, PICO_PROTO_UDP, &cb_udpecho);
|
||||
|
||||
if (!udpecho_pas->s) {
|
||||
printf("%s: error opening socket: %s\n", __FUNCTION__, strerror(pico_err));
|
||||
free(udpecho_pas);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!IPV6_MODE)
|
||||
ret = pico_socket_bind(udpecho_pas->s, &inaddr_bind, &listen_port);
|
||||
else {
|
||||
ret = pico_socket_bind(udpecho_pas->s, &inaddr_bind6, &listen_port);
|
||||
printf("udpecho> Bound to [%s]:%d.\n", baddr, short_be(listen_port));
|
||||
}
|
||||
|
||||
if (ret != 0) {
|
||||
free(udpecho_pas);
|
||||
if (!IPV6_MODE)
|
||||
printf("%s: error binding socket to %08X:%u: %s\n", __FUNCTION__, long_be(inaddr_bind.addr), short_be(listen_port), strerror(pico_err));
|
||||
else
|
||||
printf("%s: error binding socket to [%s]:%u: %s\n", __FUNCTION__, baddr, short_be(listen_port), strerror(pico_err));
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#ifdef PICOAPP_IPFILTER
|
||||
{
|
||||
struct pico_ip4 address, in_addr_netmask, in_addr;
|
||||
/* struct pico_ipv4_link *link; */
|
||||
int ret = 0;
|
||||
address.addr = 0x0800280a;
|
||||
in_addr_netmask.addr = 0x00FFFFFF;
|
||||
in_addr.addr = 0x0000320a;
|
||||
/* link = pico_ipv4_link_get(&address); */
|
||||
|
||||
printf("udpecho> IPFILTER ENABLED\n");
|
||||
|
||||
/*Adjust your IPFILTER*/
|
||||
ret |= pico_ipv4_filter_add(NULL, 17, NULL, NULL, &in_addr, &in_addr_netmask, 0, 5555, 0, 0, FILTER_DROP);
|
||||
|
||||
if (ret < 0)
|
||||
printf("Filter_add invalid argument\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
printf("\n%s: UDP echo launched. Receiving packets of %u bytes on port %u\n\n", __FUNCTION__, udpecho_pas->datasize, short_be(listen_port));
|
||||
|
||||
/* free strdups */
|
||||
if (baddr)
|
||||
free (baddr);
|
||||
|
||||
if (lport)
|
||||
free (lport);
|
||||
|
||||
if (sport)
|
||||
free (sport);
|
||||
|
||||
if (s_datasize)
|
||||
free (s_datasize);
|
||||
|
||||
return;
|
||||
|
||||
out:
|
||||
fprintf(stderr, "udpecho expects the following format: udpecho:bind_addr:listen_port[:sendto_port:datasize]\n");
|
||||
free(udpecho_pas);
|
||||
exit(255);
|
||||
}
|
||||
/*** END UDP ECHO ***/
|
||||
88
kernel/picotcp/test/examples/udp_sendto_test.c
Normal file
88
kernel/picotcp/test/examples/udp_sendto_test.c
Normal file
@@ -0,0 +1,88 @@
|
||||
#include "utils.h"
|
||||
#include <pico_ipv6.h>
|
||||
#include <pico_socket.h>
|
||||
|
||||
/**** START UDP ECHO ****/
|
||||
/*
|
||||
* udpecho expects the following format: udpecho:bind_addr:listen_port[:sendto_port:datasize]
|
||||
* bind_addr: IP address to bind to
|
||||
* listen_port: port number on which the udpecho listens
|
||||
* sendto_port [OPTIONAL]: port number to echo datagrams to (echo to originating IP address)
|
||||
* datasize [OPTIONAL]: max size of the data red from the socket in one go
|
||||
*
|
||||
* REMARK: once an optional parameter is given, all optional parameters need a value!
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
void dummy_cb(uint16_t __attribute__((unused)) ev, struct pico_socket __attribute__((unused)) *s)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void app_sendto_test(char *arg)
|
||||
{
|
||||
char *nxt = arg;
|
||||
char *dstaddr = NULL;
|
||||
char *dstport = NULL;
|
||||
struct pico_ip4 inaddr_dst = {};
|
||||
struct pico_ip6 inaddr_dst6 = {};
|
||||
uint16_t dport;
|
||||
struct pico_socket *sock;
|
||||
int ret;
|
||||
|
||||
/* start of argument parsing */
|
||||
if (nxt) {
|
||||
nxt = cpy_arg(&dstaddr, nxt);
|
||||
if (dstaddr) {
|
||||
if (!IPV6_MODE)
|
||||
pico_string_to_ipv4(dstaddr, &inaddr_dst.addr);
|
||||
|
||||
#ifdef PICO_SUPPORT_IPV6
|
||||
else
|
||||
pico_string_to_ipv6(dstaddr, inaddr_dst6.addr);
|
||||
#endif
|
||||
} else {
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
/* missing bind_addr */
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (nxt) {
|
||||
nxt = cpy_arg(&dstport, nxt);
|
||||
if (dstport && atoi(dstport)) {
|
||||
dport = short_be(atoi(dstport));
|
||||
} else {
|
||||
dport = short_be(5555);
|
||||
}
|
||||
} else {
|
||||
/* missing listen_port */
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!IPV6_MODE)
|
||||
sock = pico_socket_open(PICO_PROTO_IPV4, PICO_PROTO_UDP, &dummy_cb);
|
||||
else
|
||||
sock = pico_socket_open(PICO_PROTO_IPV6, PICO_PROTO_UDP, &dummy_cb);
|
||||
|
||||
ret = pico_socket_sendto(sock, "Testing", 7u, ((IPV6_MODE) ? (void *)(&inaddr_dst6) : (void *)(&inaddr_dst)), dport);
|
||||
if (ret < 0)
|
||||
printf("Failure in first pico_socket_send\n");
|
||||
|
||||
ret = pico_socket_sendto(sock, "Testing", 7u, ((IPV6_MODE) ? (void *)(&inaddr_dst6) : (void *)(&inaddr_dst)), dport);
|
||||
if (ret < 0)
|
||||
printf("Failure in second pico_socket_send\n");
|
||||
|
||||
ret = pico_socket_close(sock);
|
||||
if (ret)
|
||||
printf("Failure in pico_socket_close\n");
|
||||
|
||||
printf("\n%s: UDP sendto test launched. Sending packets to ip %s port %u\n\n", __FUNCTION__, dstaddr, short_be(dport));
|
||||
return;
|
||||
|
||||
out:
|
||||
fprintf(stderr, "udp_sendto_test expects the following format: udp_sendto_test:dest_addr:[dest_por]t\n");
|
||||
exit(255);
|
||||
}
|
||||
151
kernel/picotcp/test/examples/udpnat.c
Normal file
151
kernel/picotcp/test/examples/udpnat.c
Normal file
@@ -0,0 +1,151 @@
|
||||
#include "utils.h"
|
||||
#include <pico_ipv6.h>
|
||||
#include <pico_socket.h>
|
||||
|
||||
/*** START UDP NAT CLIENT ***/
|
||||
/* ./build/test/picoapp.elf --vde pic0:/tmp/pic0.ctl:10.40.0.9:255.255.0.0:10.40.0.10: -a udpnatclient:10.50.0.8:6667: */
|
||||
static struct pico_ip4 udpnatclient_inaddr_dst;
|
||||
static uint16_t udpnatclient_port_be;
|
||||
|
||||
void udpnatclient_send(pico_time __attribute__((unused)) now, void *arg)
|
||||
{
|
||||
int i, w;
|
||||
struct pico_socket *s = (struct pico_socket *)arg;
|
||||
char buf[1400] = { };
|
||||
char end[4] = "end";
|
||||
static int loop = 0;
|
||||
|
||||
for ( i = 0; i < 3; i++) {
|
||||
w = pico_socket_send(s, buf, 1400);
|
||||
}
|
||||
if (++loop > 1000) {
|
||||
udpnatclient_port_be = 0;
|
||||
for (i = 0; i < 3; i++) {
|
||||
w = pico_socket_send(s, end, 4);
|
||||
if (w <= 0)
|
||||
break;
|
||||
|
||||
printf("End!\n");
|
||||
}
|
||||
if (!pico_timer_add(1000, deferred_exit, NULL)) {
|
||||
printf("Failed to start exit timer, exiting now\n");
|
||||
exit(1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void cb_udpnatclient(uint16_t ev, struct pico_socket *s)
|
||||
{
|
||||
char recvbuf[1400];
|
||||
int r = 0;
|
||||
|
||||
if (ev & PICO_SOCK_EV_RD) {
|
||||
do {
|
||||
r = pico_socket_recv(s, recvbuf, 1400);
|
||||
} while(r > 0);
|
||||
}
|
||||
|
||||
if (ev == PICO_SOCK_EV_ERR) {
|
||||
printf("Socket Error received. Bailing out.\n");
|
||||
exit(7);
|
||||
}
|
||||
|
||||
/* Not closing to test port check */
|
||||
/* pico_socket_close(s); */
|
||||
}
|
||||
|
||||
void udpnatclient_open_socket(pico_time __attribute__((unused)) now, void __attribute__((unused)) *arg)
|
||||
{
|
||||
struct pico_socket *s = NULL;
|
||||
static int loop;
|
||||
|
||||
if (!udpnatclient_port_be)
|
||||
return;
|
||||
|
||||
loop++;
|
||||
picoapp_dbg(">>>>> Loop %d\n", loop);
|
||||
if (!(loop % 100))
|
||||
printf("Created %d sockets\n", loop);
|
||||
|
||||
s = pico_socket_open(PICO_PROTO_IPV4, PICO_PROTO_UDP, &cb_udpnatclient);
|
||||
if (!s)
|
||||
exit(1);
|
||||
|
||||
if (pico_socket_connect(s, &udpnatclient_inaddr_dst, udpnatclient_port_be) != 0)
|
||||
{
|
||||
printf("Error connecting\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
picoapp_dbg("New socket with port %u\n", s->local_port);
|
||||
|
||||
if (!pico_timer_add(25, udpnatclient_send, s)) {
|
||||
printf("Failed to start send timer, exiting now\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!pico_timer_add(25, udpnatclient_open_socket, 0)) {
|
||||
printf("Failed to start open_socket timer, exiting now\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
void app_udpnatclient(char *arg)
|
||||
{
|
||||
struct pico_socket *s;
|
||||
char *daddr, *dport;
|
||||
int port = 0;
|
||||
uint16_t port_be = 0;
|
||||
struct pico_ip4 inaddr_dst = ZERO_IP4;
|
||||
char *nxt;
|
||||
|
||||
nxt = cpy_arg(&daddr, arg);
|
||||
if (!daddr) {
|
||||
fprintf(stderr, " udpnatclient expects the following format: udpnatclient:dest_addr[:dest_port]\n");
|
||||
exit(255);
|
||||
}
|
||||
|
||||
if (nxt) {
|
||||
nxt = cpy_arg(&dport, nxt);
|
||||
if (dport) {
|
||||
port = atoi(dport);
|
||||
if (port > 0)
|
||||
port_be = short_be(port);
|
||||
}
|
||||
}
|
||||
|
||||
if (port == 0) {
|
||||
port_be = short_be(5555);
|
||||
}
|
||||
|
||||
printf("UDP NAT client started. Sending packets to %s:%d\n", daddr, short_be(port_be));
|
||||
|
||||
s = pico_socket_open(PICO_PROTO_IPV4, PICO_PROTO_UDP, &cb_udpnatclient);
|
||||
if (!s)
|
||||
exit(1);
|
||||
|
||||
pico_string_to_ipv4(daddr, &inaddr_dst.addr);
|
||||
|
||||
if (pico_socket_connect(s, &inaddr_dst, port_be) != 0)
|
||||
{
|
||||
printf("Error binding the port \n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
picoapp_dbg("New socket with port %u\n", s->local_port);
|
||||
|
||||
udpnatclient_inaddr_dst = inaddr_dst;
|
||||
udpnatclient_port_be = port_be;
|
||||
|
||||
if (!pico_timer_add(100, udpnatclient_send, s)) {
|
||||
printf("Failed to start send timer, exiting now\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!pico_timer_add(1000, udpnatclient_open_socket, 0)) {
|
||||
printf("Failed to start open_socket timer, exiting now\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
/*** END UDP NAT CLIENT ***/
|
||||
39
kernel/picotcp/test/examples/utils.h
Normal file
39
kernel/picotcp/test/examples/utils.h
Normal file
@@ -0,0 +1,39 @@
|
||||
#ifndef PICO_EXAMPLES_UTILS_H
|
||||
#define PICO_EXAMPLES_UTILS_H
|
||||
#include <pico_stack.h>
|
||||
#define TCPSIZ (1024 * 1024 * 5)
|
||||
extern struct pico_ip4 ZERO_IP4;
|
||||
extern struct pico_ip_mreq ZERO_MREQ;
|
||||
extern struct pico_ip_mreq_source ZERO_MREQ_SRC;
|
||||
extern struct pico_ip6 ZERO_IP6;
|
||||
extern struct pico_ip_mreq ZERO_MREQ_IP6;
|
||||
extern struct pico_ip_mreq_source ZERO_MREQ_SRC_IP6;
|
||||
#define picoapp_dbg(...) do {} while(0)
|
||||
/* #define picoapp_dbg printf */
|
||||
extern int IPV6_MODE;
|
||||
|
||||
|
||||
extern struct pico_ip4 inaddr_any;
|
||||
extern struct pico_ip6 inaddr6_any;
|
||||
|
||||
extern char *cpy_arg(char **dst, char *str);
|
||||
|
||||
extern void deferred_exit(pico_time now, void *arg);
|
||||
|
||||
struct udpclient_pas {
|
||||
struct pico_socket *s;
|
||||
uint8_t loops;
|
||||
uint8_t subloops;
|
||||
uint16_t datasize;
|
||||
uint16_t sport;
|
||||
union pico_address dst;
|
||||
}; /* per application struct */
|
||||
|
||||
struct udpecho_pas {
|
||||
struct pico_socket *s;
|
||||
uint16_t sendto_port; /* big-endian */
|
||||
uint16_t datasize;
|
||||
}; /* per application struct */
|
||||
|
||||
|
||||
#endif
|
||||
104
kernel/picotcp/test/mkunits.sh
Executable file
104
kernel/picotcp/test/mkunits.sh
Executable file
@@ -0,0 +1,104 @@
|
||||
#!/bin/bash
|
||||
# By Daniele.
|
||||
#set -x
|
||||
filename=$1
|
||||
if [ [x$1] == [x] ]; then
|
||||
echo USAGE: $0 filename.c
|
||||
exit 4
|
||||
fi
|
||||
|
||||
#CMOCK="../CMock/lib/cmock.rb"
|
||||
|
||||
bname=`basename $filename`
|
||||
cat $filename |grep static|grep \( | grep \) >/tmp/$bname
|
||||
|
||||
if (test -f ./test/unit/modunit_$bname); then
|
||||
echo The destination file ./test/unit/modunit_$bname already exists. Exiting...
|
||||
exit 0
|
||||
fi
|
||||
|
||||
cat $filename |grep "\#include " > ./test/unit/modunit_$bname
|
||||
MYSELF=`echo $bname | cut -d"." -f1`.h
|
||||
INCLUDES=`cat $filename |grep "\#include \"" |grep -v $MYSELF| cut -d '"' -f 2`
|
||||
|
||||
echo includes are:
|
||||
echo $INCLUDES
|
||||
echo "#include \"$filename\"" >>./test/unit/modunit_$bname
|
||||
echo "#include \"check.h\"" >>./test/unit/modunit_$bname
|
||||
echo >> ./test/unit/modunit_$bname
|
||||
echo >> ./test/unit/modunit_$bname
|
||||
|
||||
while read fn ; do
|
||||
fname=`echo $fn | cut -d "(" -f 1| cut -d" " -f 3`
|
||||
echo "START_TEST(tc_$fname)" >>./test/unit/modunit_$bname
|
||||
echo "{" >>./test/unit/modunit_$bname
|
||||
echo " /* TODO: test this: $fn */" >>./test/unit/modunit_$bname
|
||||
echo "}" >>./test/unit/modunit_$bname
|
||||
echo "END_TEST" >>./test/unit/modunit_$bname
|
||||
done </tmp/$bname
|
||||
|
||||
echo >> ./test/unit/modunit_$bname
|
||||
echo >> ./test/unit/modunit_$bname
|
||||
echo "Suite *pico_suite(void)
|
||||
{
|
||||
Suite *s = suite_create(\"PicoTCP\");
|
||||
" >> ./test/unit/modunit_$bname
|
||||
|
||||
while read fn ; do
|
||||
fname=`echo $fn | cut -d "(" -f 1| cut -d" " -f 3`
|
||||
echo " TCase *TCase_$fname = tcase_create(\"Unit test for $fname\");" >> ./test/unit/modunit_$bname
|
||||
done </tmp/$bname
|
||||
|
||||
echo >> ./test/unit/modunit_$bname
|
||||
echo >> ./test/unit/modunit_$bname
|
||||
|
||||
while read fn ; do
|
||||
fname=`echo $fn | cut -d "(" -f 1| cut -d" " -f 3`
|
||||
echo " tcase_add_test(TCase_$fname, tc_$fname);" >> ./test/unit/modunit_$bname
|
||||
echo " suite_add_tcase(s, TCase_$fname);" >> ./test/unit/modunit_$bname
|
||||
done </tmp/$bname
|
||||
|
||||
echo "return s;">> ./test/unit/modunit_$bname
|
||||
echo "}">> ./test/unit/modunit_$bname
|
||||
|
||||
echo "
|
||||
int main(void)
|
||||
{
|
||||
int fails;
|
||||
Suite *s = pico_suite();
|
||||
SRunner *sr = srunner_create(s);
|
||||
srunner_run_all(sr, CK_NORMAL);
|
||||
fails = srunner_ntests_failed(sr);
|
||||
srunner_free(sr);
|
||||
return fails;
|
||||
}" >>./test/unit/modunit_$bname
|
||||
|
||||
|
||||
echo Gernerated test ./test/unit/modunit_$bname
|
||||
#echo Generating mocks...
|
||||
#mkdir -p mocks
|
||||
#
|
||||
#CFILES=""
|
||||
#for i in $INCLUDES; do
|
||||
# ii=`find -name $i | grep -v build`
|
||||
# ruby $CMOCK $ii
|
||||
# CFILE=`basename $ii |cut -d "." -f 1`.c
|
||||
# CFILES="$CFILES mocks/Mock$CFILE"
|
||||
#done
|
||||
ELF=`echo build/test/modunit_$bname | sed -e "s/\.c/.elf/g"`
|
||||
|
||||
echo
|
||||
echo
|
||||
|
||||
MOCKS=$(gcc -I include/ -I modules/ -I. test/unit/modunit_$bname $CFILES -lcheck -pthread -lm -lrt -o $ELF 2>&1 |grep "undefined reference to" | sed -e "s/.*\`//g" | sed -e "s/'.*$//g" |sort | uniq)
|
||||
|
||||
for m in $MOCKS; do
|
||||
decl=`grep -R $m * |grep -v ");" | grep -v Binary | cut -d ":" -f 2`
|
||||
echo $decl >> ./test/unit/modunit_$bname
|
||||
echo "{" >> ./test/unit/modunit_$bname
|
||||
echo "/* TODO: MOCK ME! */">> ./test/unit/modunit_$bname
|
||||
echo "}" >> ./test/unit/modunit_$bname
|
||||
done
|
||||
gcc -I include/ -I modules/ -I. test/unit/modunit_$bname $CFILES -lcheck -pthread -lm -lrt -o $ELF && echo "Successfully compiled $ELF"
|
||||
|
||||
#echo " /* TODO: MOCKS NEEDED: $MOCKS */ " >>./test/unit/modunit_$bname
|
||||
68
kernel/picotcp/test/olsr_test.sh
Executable file
68
kernel/picotcp/test/olsr_test.sh
Executable file
@@ -0,0 +1,68 @@
|
||||
#!/bin/bash
|
||||
|
||||
sudo vde_switch -t pic0 -s /tmp/pic0.ctl -d
|
||||
sudo vde_switch -s /tmp/pic1.ctl -d
|
||||
sudo vde_switch -s /tmp/pic2.ctl -d
|
||||
sudo vde_switch -s /tmp/pic3.ctl -d
|
||||
|
||||
sudo ifconfig pic0 10.40.0.254/16 up
|
||||
|
||||
./build/test/picoapp.elf \
|
||||
--vde pic0:/tmp/pic0.ctl:10.40.0.8:255.255.0.0: \
|
||||
-a olsr: &
|
||||
|
||||
./build/test/picoapp.elf \
|
||||
--vde pic0:/tmp/pic0.ctl:10.40.0.9:255.255.0.0: \
|
||||
--vde pic1:/tmp/pic1.ctl:10.41.0.9:255.255.0.0: \
|
||||
-a olsr: &
|
||||
|
||||
./build/test/picoapp.elf \
|
||||
--vde pic0:/tmp/pic1.ctl:10.41.0.1:255.255.0.0: \
|
||||
-a olsr: &
|
||||
|
||||
./build/test/picoapp.elf \
|
||||
--vde pic0:/tmp/pic1.ctl:10.41.0.2:255.255.0.0: \
|
||||
-a olsr: &
|
||||
|
||||
./build/test/picoapp.elf \
|
||||
--vde pic0:/tmp/pic1.ctl:10.41.0.3:255.255.0.0: \
|
||||
-a olsr: &
|
||||
|
||||
./build/test/picoapp.elf \
|
||||
--vde pic0:/tmp/pic1.ctl:10.41.0.10:255.255.0.0: \
|
||||
--vde pic1:/tmp/pic2.ctl:10.42.0.10:255.255.0.0: \
|
||||
-a olsr: &
|
||||
|
||||
./build/test/picoapp.elf \
|
||||
--vde pic0:/tmp/pic2.ctl:10.42.0.1:255.255.0.0: \
|
||||
-a olsr: &
|
||||
|
||||
./build/test/picoapp.elf \
|
||||
--vde pic0:/tmp/pic2.ctl:10.42.0.2:255.255.0.0: \
|
||||
-a olsr: &
|
||||
|
||||
./build/test/picoapp.elf \
|
||||
--vde pic0:/tmp/pic1.ctl:10.42.0.3:255.255.0.0: \
|
||||
-a olsr: &
|
||||
|
||||
./build/test/picoapp.elf \
|
||||
--vde pic0:/tmp/pic2.ctl:10.42.0.11:255.255.0.0: \
|
||||
--vde pic1:/tmp/pic3.ctl:10.43.0.11:255.255.0.0: \
|
||||
-a olsr: &
|
||||
|
||||
./build/test/picoapp.elf \
|
||||
--vde pic0:/tmp/pic3.ctl:10.43.0.1:255.255.0.0: \
|
||||
-a olsr: &
|
||||
|
||||
./build/test/picoapp.elf \
|
||||
--vde pic0:/tmp/pic3.ctl:10.43.0.2:255.255.0.0: \
|
||||
-a olsr: &
|
||||
|
||||
./build/test/picoapp.elf \
|
||||
--vde pic0:/tmp/pic3.ctl:10.43.0.3:255.255.0.0: \
|
||||
-a olsr: &
|
||||
|
||||
sleep 5
|
||||
sudo killall olsrd
|
||||
sudo olsrd -i pic0
|
||||
|
||||
26
kernel/picotcp/test/perf.sh
Executable file
26
kernel/picotcp/test/perf.sh
Executable file
@@ -0,0 +1,26 @@
|
||||
#!/bin/bash
|
||||
THRESHOLD=300
|
||||
sh ./test/vde_sock_start_user.sh
|
||||
sleep 2
|
||||
|
||||
(iperf -s >/tmp/iperf.log)&
|
||||
./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
|
||||
killall iperf
|
||||
RES=`cat /tmp/iperf.log |grep Mbits |sed -e "s/.*Bytes//g" |sed -e "s/^[ ]*//g"`
|
||||
SPEED=`echo $RES | cut -d " " -f 1`
|
||||
UNITS=`echo $RES | cut -d " " -f 2`
|
||||
|
||||
if [ ["$UNITS"] != ["Mbits/sec"] ]; then
|
||||
echo "Wrong test result units: expected Mbits/sec, got $UNITS"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if (test $SPEED -lt $THRESHOLD); then
|
||||
echo "Speed too low: expected $THRESHOLD MBits/s, got $SPEED $UNITS"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
echo Test result: $SPEED $UNITS
|
||||
|
||||
rm -f /tmp/iperf.log
|
||||
exit 0
|
||||
29
kernel/picotcp/test/pico_faulty.c
Normal file
29
kernel/picotcp/test/pico_faulty.c
Normal file
@@ -0,0 +1,29 @@
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "pico_faulty.h"
|
||||
|
||||
/* #warning "COMPILING for MEMORY TESTS!" */
|
||||
|
||||
uint32_t mm_failure_count = 0;
|
||||
uint32_t cur_mem, max_mem;
|
||||
|
||||
static int called_atexit = 0;
|
||||
|
||||
|
||||
void memory_stats(void)
|
||||
{
|
||||
fprintf(stderr, " ################ MAX MEMORY USED in this test: %u\n", max_mem);
|
||||
|
||||
}
|
||||
|
||||
int pico_set_mm_failure(uint32_t nxt)
|
||||
{
|
||||
if (!called_atexit) {
|
||||
atexit(memory_stats);
|
||||
called_atexit++;
|
||||
}
|
||||
|
||||
mm_failure_count = nxt;
|
||||
return 0;
|
||||
}
|
||||
134
kernel/picotcp/test/pico_faulty.h
Normal file
134
kernel/picotcp/test/pico_faulty.h
Normal file
@@ -0,0 +1,134 @@
|
||||
/*********************************************************************
|
||||
PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved.
|
||||
See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage.
|
||||
Do not redistribute without a written permission by the Copyright
|
||||
holders.
|
||||
*********************************************************************/
|
||||
|
||||
|
||||
/* This is a test implementation, with a faulty memory manager,
|
||||
* intended to increase test coverage
|
||||
* Warning: not intended for production!
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef PICO_SUPPORT_POSIX
|
||||
#define PICO_SUPPORT_POSIX
|
||||
|
||||
#define PICO_FAULTY
|
||||
|
||||
#define MEM_LIMIT (0)
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
extern uint32_t mm_failure_count;
|
||||
int pico_set_mm_failure(uint32_t nxt);
|
||||
extern uint32_t max_mem;
|
||||
extern uint32_t cur_mem;
|
||||
|
||||
/*
|
||||
#define TIME_PRESCALE
|
||||
*/
|
||||
#define dbg printf
|
||||
|
||||
#define stack_fill_pattern(...) do {} while(0)
|
||||
#define stack_count_free_words(...) do {} while(0)
|
||||
#define stack_get_free_words() (0)
|
||||
|
||||
static inline void mem_stat_store(void)
|
||||
{
|
||||
char fname_mod[] = "/tmp/pico-mem-report-%hu.txt";
|
||||
char fname[200];
|
||||
char buffer[20];
|
||||
int fd;
|
||||
snprintf(fname, 200, fname_mod, getpid());
|
||||
fd = open(fname, O_WRONLY | O_CREAT | O_TRUNC, 0660);
|
||||
if (fd < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
snprintf(buffer, 20, "%d\n", max_mem);
|
||||
write(fd, buffer, strlen(buffer));
|
||||
close(fd);
|
||||
}
|
||||
|
||||
|
||||
static inline void *pico_zalloc(size_t x)
|
||||
{
|
||||
uint32_t *ptr;
|
||||
if (mm_failure_count > 0) {
|
||||
if (--mm_failure_count == 0) {
|
||||
fprintf(stderr, "Malloc failed, for test purposes\n");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
ptr = (uint32_t *)calloc(x + sizeof(uint32_t), 1);
|
||||
*ptr = (uint32_t)x; /* store size of alloc */
|
||||
cur_mem += (uint32_t)x;
|
||||
|
||||
#ifndef DISABLE_MM_STATS
|
||||
if (cur_mem > max_mem) {
|
||||
max_mem = cur_mem;
|
||||
if ((MEM_LIMIT > 0) && (max_mem > MEM_LIMIT))
|
||||
abort();
|
||||
|
||||
mem_stat_store();
|
||||
}
|
||||
|
||||
#endif
|
||||
return (void*)(ptr + 1);
|
||||
}
|
||||
|
||||
static inline void pico_free(void *x)
|
||||
{
|
||||
uint32_t *ptr = (uint32_t*)(((uint8_t *)x) - sizeof(uint32_t)); /* fetch size of the alloc */
|
||||
cur_mem -= *ptr;
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
/* time prescaler */
|
||||
#ifdef TIME_PRESCALE
|
||||
extern int32_t prescale_time;
|
||||
#endif
|
||||
|
||||
static inline uint32_t PICO_TIME(void)
|
||||
{
|
||||
struct timeval t;
|
||||
gettimeofday(&t, NULL);
|
||||
#ifdef TIME_PRESCALE
|
||||
return (prescale_time < 0) ? (uint32_t)(t.tv_sec / 1000 << (-prescale_time)) : \
|
||||
(uint32_t)(t.tv_sec / 1000 >> prescale_time);
|
||||
#else
|
||||
return (uint32_t)t.tv_sec;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline uint32_t PICO_TIME_MS(void)
|
||||
{
|
||||
struct timeval t;
|
||||
gettimeofday(&t, NULL);
|
||||
#ifdef TIME_PRESCALER
|
||||
uint32_t tmp = ((t.tv_sec * 1000) + (t.tv_usec / 1000));
|
||||
return (prescale_time < 0) ? (uint32_t)(tmp / 1000 << (-prescale_time)) : \
|
||||
(uint32_t)(tmp / 1000 >> prescale_time);
|
||||
#else
|
||||
return (uint32_t)((t.tv_sec * 1000) + (t.tv_usec / 1000));
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void PICO_IDLE(void)
|
||||
{
|
||||
usleep(5000);
|
||||
}
|
||||
|
||||
void memory_stats(void);
|
||||
|
||||
#endif /* PICO_SUPPORT_POSIX */
|
||||
|
||||
757
kernel/picotcp/test/picoapp.c
Normal file
757
kernel/picotcp/test/picoapp.c
Normal file
@@ -0,0 +1,757 @@
|
||||
/* PicoTCP Test application */
|
||||
#include <poll.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <getopt.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <libgen.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
#include "pico_stack.h"
|
||||
#include "pico_config.h"
|
||||
#include "pico_dev_vde.h"
|
||||
#include "pico_ipv4.h"
|
||||
#include "pico_ipv6.h"
|
||||
#include "pico_socket.h"
|
||||
#include "pico_dev_tun.h"
|
||||
#include "pico_dev_tap.h"
|
||||
#include "pico_nat.h"
|
||||
#include "pico_icmp4.h"
|
||||
#include "pico_icmp6.h"
|
||||
#include "pico_dns_client.h"
|
||||
#include "pico_dev_loop.h"
|
||||
#include "pico_dhcp_client.h"
|
||||
#include "pico_dhcp_server.h"
|
||||
#include "pico_ipfilter.h"
|
||||
#include "pico_olsr.h"
|
||||
#include "pico_sntp_client.h"
|
||||
#include "pico_mdns.h"
|
||||
#include "pico_tftp.h"
|
||||
#include "pico_dev_radiotest.h"
|
||||
#include "pico_dev_radio_mgr.h"
|
||||
|
||||
#include <poll.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <getopt.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <libgen.h>
|
||||
|
||||
#ifdef FAULTY
|
||||
#include "pico_faulty.h"
|
||||
#endif
|
||||
|
||||
void app_udpecho(char *args);
|
||||
void app_tcpecho(char *args);
|
||||
void app_udpclient(char *args);
|
||||
void app_tcpclient(char *args);
|
||||
void app_tcpbench(char *args);
|
||||
void app_natbox(char *args);
|
||||
void app_udpdnsclient(char *args);
|
||||
void app_udpnatclient(char *args);
|
||||
void app_mcastsend(char *args);
|
||||
void app_mcastreceive_ipv6(char *args);
|
||||
void app_mcastsend_ipv6(char *args);
|
||||
void app_mcastreceive(char *args);
|
||||
void app_ping(char *args);
|
||||
void app_dhcp_server(char *args);
|
||||
void app_dhcp_client(char *args);
|
||||
void app_dns_sd(char *arg, struct pico_ip4 addr);
|
||||
void app_mdns(char *arg, struct pico_ip4 addr);
|
||||
void app_sntp(char *args);
|
||||
void app_tftp(char *args);
|
||||
void app_slaacv4(char *args);
|
||||
void app_udpecho(char *args);
|
||||
void app_sendto_test(char *args);
|
||||
void app_noop(void);
|
||||
|
||||
struct pico_ip4 ZERO_IP4 = {
|
||||
0
|
||||
};
|
||||
struct pico_ip_mreq ZERO_MREQ = {
|
||||
.mcast_group_addr = {{0}},
|
||||
.mcast_link_addr = {{0}}
|
||||
};
|
||||
struct pico_ip_mreq_source ZERO_MREQ_SRC = {
|
||||
.mcast_group_addr.ip4 = {0},
|
||||
.mcast_link_addr.ip4 = {0},
|
||||
.mcast_source_addr.ip4 = {0}
|
||||
};
|
||||
struct pico_ip6 ZERO_IP6 = {
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
|
||||
};
|
||||
struct pico_ip_mreq ZERO_MREQ_IP6 = {
|
||||
.mcast_group_addr.ip6 = {{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }},
|
||||
.mcast_link_addr.ip6 = {{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }}
|
||||
};
|
||||
struct pico_ip_mreq_source ZERO_MREQ_SRC_IP6 = {
|
||||
.mcast_group_addr.ip6 = {{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }},
|
||||
.mcast_link_addr.ip6 = {{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }},
|
||||
.mcast_source_addr.ip6 = {{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }}
|
||||
};
|
||||
|
||||
/* #define INFINITE_TCPTEST */
|
||||
#define picoapp_dbg(...) do {} while(0)
|
||||
/* #define picoapp_dbg printf */
|
||||
|
||||
/* #define PICOAPP_IPFILTER 1 */
|
||||
|
||||
int IPV6_MODE;
|
||||
|
||||
|
||||
struct pico_ip4 inaddr_any = {
|
||||
0
|
||||
};
|
||||
struct pico_ip6 inaddr6_any = {{0}};
|
||||
|
||||
char *cpy_arg(char **dst, char *str);
|
||||
|
||||
void deferred_exit(pico_time __attribute__((unused)) now, void *arg)
|
||||
{
|
||||
if (arg) {
|
||||
free(arg);
|
||||
arg = NULL;
|
||||
}
|
||||
|
||||
printf("%s: quitting\n", __FUNCTION__);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** From now on, parsing the command line **/
|
||||
#define NXT_MAC(x) ++ x[5]
|
||||
|
||||
/* Copy a string until the separator,
|
||||
terminate it and return the next index,
|
||||
or NULL if it encounters a EOS */
|
||||
char *cpy_arg(char **dst, char *str)
|
||||
{
|
||||
char *p, *nxt = NULL;
|
||||
char *start = str;
|
||||
char *end = start + strlen(start);
|
||||
char sep = ':';
|
||||
|
||||
if (IPV6_MODE)
|
||||
sep = ',';
|
||||
|
||||
p = str;
|
||||
while (p) {
|
||||
if ((*p == sep) || (*p == '\0')) {
|
||||
*p = (char)0;
|
||||
nxt = p + 1;
|
||||
if ((*nxt == 0) || (nxt >= end))
|
||||
nxt = 0;
|
||||
|
||||
printf("dup'ing %s\n", start);
|
||||
*dst = strdup(start);
|
||||
break;
|
||||
}
|
||||
|
||||
p++;
|
||||
}
|
||||
return nxt;
|
||||
}
|
||||
|
||||
static void __wakeup(uint16_t __attribute__((unused)) ev, struct pico_socket __attribute__((unused)) *s)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void usage(char *arg0)
|
||||
{
|
||||
printf("Usage: %s [--vde name:sock:address:netmask[:gateway]] [--vde ...] [--tun name:address:netmask[:gateway]] [--tun ...] [--app name[:args]]\n\n\n", arg0);
|
||||
printf("\tall arguments can be repeated, e.g. to run on multiple links or applications\n");
|
||||
printf("\t* --app arguments must be at the end *\n");
|
||||
exit(255);
|
||||
}
|
||||
|
||||
#define IF_APPNAME(x) if(strcmp(x, name) == 0)
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
unsigned char macaddr[6] = {
|
||||
0, 0, 0, 0xa, 0xb, 0x0
|
||||
};
|
||||
uint16_t *macaddr_low = (uint16_t *) (macaddr + 2);
|
||||
struct pico_device *dev = NULL;
|
||||
struct pico_ip4 addr4 = {
|
||||
0
|
||||
};
|
||||
struct pico_ip4 bcastAddr = ZERO_IP4;
|
||||
|
||||
struct option long_options[] = {
|
||||
{"help", 0, 0, 'h'},
|
||||
{"vde", 1, 0, 'v'},
|
||||
{"barevde", 1, 0, 'b'},
|
||||
{"tun", 1, 0, 't'},
|
||||
{"tap", 1, 0, 'T'},
|
||||
{"route", 1, 0, 'r'},
|
||||
{"app", 1, 0, 'a'},
|
||||
{"dns", 1, 0, 'd'},
|
||||
{"loop", 0, 0, 'l'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
int option_idx = 0;
|
||||
int c;
|
||||
char *app = NULL, *p = argv[0];
|
||||
/* parse till we find the name of the executable */
|
||||
while (p) {
|
||||
if (*p == '/')
|
||||
app = p + 1;
|
||||
else if (*p == '\0')
|
||||
break;
|
||||
else
|
||||
{} /* do nothing */
|
||||
|
||||
p++;
|
||||
}
|
||||
if (strcmp(app, "picoapp6.elf") == 0)
|
||||
IPV6_MODE = 1;
|
||||
|
||||
*macaddr_low = (uint16_t)(*macaddr_low ^ (uint16_t)((uint16_t)getpid() & (uint16_t)0xFFFFU));
|
||||
printf("My macaddr base is: %02x %02x\n", macaddr[2], macaddr[3]);
|
||||
printf("My macaddr is: %02x %02x %02x %02x %02x %02x\n", macaddr[0], macaddr[1], macaddr[2], macaddr[3], macaddr[4], macaddr[5]);
|
||||
|
||||
#ifdef PICO_SUPPORT_MM
|
||||
pico_mem_init(128 * 1024);
|
||||
#endif
|
||||
pico_stack_init();
|
||||
/* Parse args */
|
||||
while(1) {
|
||||
c = getopt_long(argc, argv, "6:v:b:t:T:a:r:hl", long_options, &option_idx);
|
||||
if (c < 0)
|
||||
break;
|
||||
|
||||
switch(c) {
|
||||
case 'h':
|
||||
usage(argv[0]);
|
||||
break;
|
||||
case 'T':
|
||||
{
|
||||
char *nxt, *name = NULL, *addr = NULL, *nm = NULL, *gw = NULL;
|
||||
struct pico_ip4 ipaddr, netmask, gateway, zero = ZERO_IP4;
|
||||
do {
|
||||
nxt = cpy_arg(&name, optarg);
|
||||
if (!nxt) break;
|
||||
|
||||
nxt = cpy_arg(&addr, nxt);
|
||||
if (!nxt) break;
|
||||
|
||||
nxt = cpy_arg(&nm, nxt);
|
||||
if (!nxt) break;
|
||||
|
||||
cpy_arg(&gw, nxt);
|
||||
} while(0);
|
||||
if (!nm) {
|
||||
fprintf(stderr, "Tun: bad configuration...\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
dev = pico_tap_create(name);
|
||||
if (!dev) {
|
||||
perror("Creating tap");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
pico_string_to_ipv4(addr, &ipaddr.addr);
|
||||
pico_string_to_ipv4(nm, &netmask.addr);
|
||||
pico_ipv4_link_add(dev, ipaddr, netmask);
|
||||
bcastAddr.addr = (ipaddr.addr) | (~netmask.addr);
|
||||
if (gw && *gw) {
|
||||
pico_string_to_ipv4(gw, &gateway.addr);
|
||||
printf("Adding default route via %08x\n", gateway.addr);
|
||||
pico_ipv4_route_add(zero, zero, gateway, 1, NULL);
|
||||
}
|
||||
|
||||
#ifdef PICO_SUPPORT_IPV6
|
||||
if (IPV6_MODE) {
|
||||
struct pico_ip6 ipaddr6 = {{0}}, netmask6 = {{0}}, gateway6 = {{0}}, zero6 = {{0}};
|
||||
pico_string_to_ipv6(addr, ipaddr6.addr);
|
||||
pico_string_to_ipv6(nm, netmask6.addr);
|
||||
pico_ipv6_link_add(dev, ipaddr6, netmask6);
|
||||
if (gw && *gw) {
|
||||
pico_string_to_ipv6(gw, gateway6.addr);
|
||||
pico_ipv6_route_add(zero6, zero6, gateway6, 1, NULL);
|
||||
}
|
||||
|
||||
pico_ipv6_dev_routing_enable(dev);
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case 't':
|
||||
{
|
||||
char *nxt, *name = NULL, *addr = NULL, *nm = NULL, *gw = NULL;
|
||||
struct pico_ip4 ipaddr, netmask, gateway, zero = ZERO_IP4;
|
||||
do {
|
||||
nxt = cpy_arg(&name, optarg);
|
||||
if (!nxt) break;
|
||||
|
||||
nxt = cpy_arg(&addr, nxt);
|
||||
if (!nxt) break;
|
||||
|
||||
nxt = cpy_arg(&nm, nxt);
|
||||
if (!nxt) break;
|
||||
|
||||
cpy_arg(&gw, nxt);
|
||||
} while(0);
|
||||
if (!nm) {
|
||||
fprintf(stderr, "Tun: bad configuration...\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
dev = pico_tun_create(name);
|
||||
if (!dev) {
|
||||
perror("Creating tun");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
pico_string_to_ipv4(addr, &ipaddr.addr);
|
||||
pico_string_to_ipv4(nm, &netmask.addr);
|
||||
pico_ipv4_link_add(dev, ipaddr, netmask);
|
||||
bcastAddr.addr = (ipaddr.addr) | (~netmask.addr);
|
||||
if (gw && *gw) {
|
||||
pico_string_to_ipv4(gw, &gateway.addr);
|
||||
printf("Adding default route via %08x\n", gateway.addr);
|
||||
pico_ipv4_route_add(zero, zero, gateway, 1, NULL);
|
||||
}
|
||||
|
||||
#ifdef PICO_SUPPORT_IPV6
|
||||
if (IPV6_MODE) {
|
||||
struct pico_ip6 ipaddr6 = {{0}}, netmask6 = {{0}}, gateway6 = {{0}}, zero6 = {{0}};
|
||||
pico_string_to_ipv6(addr, ipaddr6.addr);
|
||||
pico_string_to_ipv6(nm, netmask6.addr);
|
||||
pico_ipv6_link_add(dev, ipaddr6, netmask6);
|
||||
if (gw && *gw) {
|
||||
pico_string_to_ipv6(gw, gateway6.addr);
|
||||
pico_ipv6_route_add(zero6, zero6, gateway6, 1, NULL);
|
||||
}
|
||||
|
||||
pico_ipv6_dev_routing_enable(dev);
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case 'v':
|
||||
{
|
||||
char *nxt, *name = NULL, *sock = NULL, *addr = NULL, *nm = NULL, *gw = NULL, *addr6 = NULL, *nm6 = NULL, *gw6 = NULL, *loss_in = NULL, *loss_out = NULL;
|
||||
struct pico_ip4 ipaddr, netmask, gateway, zero = ZERO_IP4;
|
||||
uint32_t i_pc = 0, o_pc = 0;
|
||||
printf("+++ OPTARG %s\n", optarg);
|
||||
do {
|
||||
nxt = cpy_arg(&name, optarg);
|
||||
if (!nxt) break;
|
||||
|
||||
nxt = cpy_arg(&sock, nxt);
|
||||
if (!nxt) break;
|
||||
|
||||
if (!IPV6_MODE) {
|
||||
nxt = cpy_arg(&addr, nxt);
|
||||
if (!nxt) break;
|
||||
|
||||
nxt = cpy_arg(&nm, nxt);
|
||||
if (!nxt) break;
|
||||
|
||||
nxt = cpy_arg(&gw, nxt);
|
||||
if (!nxt) break;
|
||||
|
||||
nxt = cpy_arg(&loss_in, nxt);
|
||||
if (!nxt) break;
|
||||
|
||||
nxt = cpy_arg(&loss_out, nxt);
|
||||
if (!nxt) break;
|
||||
} else {
|
||||
nxt = cpy_arg(&addr6, nxt);
|
||||
if (!nxt) break;
|
||||
|
||||
printf("addr6: %s\n", addr6);
|
||||
|
||||
nxt = cpy_arg(&nm6, nxt);
|
||||
if (!nxt) break;
|
||||
|
||||
nxt = cpy_arg(&gw6, nxt);
|
||||
if (!nxt) break;
|
||||
|
||||
nxt = cpy_arg(&loss_in, nxt);
|
||||
if (!nxt) break;
|
||||
|
||||
nxt = cpy_arg(&loss_out, nxt);
|
||||
if (!nxt) break;
|
||||
}
|
||||
} while(0);
|
||||
if (!nm && !nm6) {
|
||||
fprintf(stderr, "Vde: bad configuration...\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
macaddr[4] ^= (uint8_t)(getpid() >> 8);
|
||||
macaddr[5] ^= (uint8_t) (getpid() & 0xFF);
|
||||
dev = pico_vde_create(sock, name, macaddr);
|
||||
NXT_MAC(macaddr);
|
||||
if (!dev) {
|
||||
perror("Creating vde");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf("Vde created.\n");
|
||||
|
||||
if (!IPV6_MODE) {
|
||||
pico_string_to_ipv4(addr, &ipaddr.addr);
|
||||
pico_string_to_ipv4(nm, &netmask.addr);
|
||||
pico_ipv4_link_add(dev, ipaddr, netmask);
|
||||
addr4 = ipaddr;
|
||||
bcastAddr.addr = (ipaddr.addr) | (~netmask.addr);
|
||||
if (gw && *gw) {
|
||||
pico_string_to_ipv4(gw, &gateway.addr);
|
||||
pico_ipv4_route_add(zero, zero, gateway, 1, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef PICO_SUPPORT_IPV6
|
||||
if (IPV6_MODE) {
|
||||
struct pico_ip6 ipaddr6 = {{0}}, netmask6 = {{0}}, gateway6 = {{0}}, zero6 = {{0}};
|
||||
printf("SETTING UP IPV6 ADDRESS\n");
|
||||
pico_string_to_ipv6(addr6, ipaddr6.addr);
|
||||
pico_string_to_ipv6(nm6, netmask6.addr);
|
||||
pico_ipv6_link_add(dev, ipaddr6, netmask6);
|
||||
if (gw6 && *gw6) {
|
||||
pico_string_to_ipv6(gw6, gateway6.addr);
|
||||
pico_ipv6_route_add(zero6, zero6, gateway6, 1, NULL);
|
||||
}
|
||||
|
||||
pico_ipv6_dev_routing_enable(dev);
|
||||
}
|
||||
|
||||
#endif
|
||||
if (loss_in && (strlen(loss_in) > 0)) {
|
||||
i_pc = (uint32_t)atoi(loss_in);
|
||||
}
|
||||
|
||||
if (loss_out && (strlen(loss_out) > 0)) {
|
||||
o_pc = (uint32_t)atoi(loss_out);
|
||||
}
|
||||
|
||||
if (i_pc || o_pc) {
|
||||
printf(" ---------- >Setting vde packet loss %u:%u\n", i_pc, o_pc);
|
||||
pico_vde_set_packetloss(dev, i_pc, o_pc);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case '6':
|
||||
{
|
||||
char *nxt, *name = NULL, *area0 = NULL, *area1 = NULL, *dump = NULL;
|
||||
const char pan_addr[] = "2aaa:abcd::0";
|
||||
uint8_t n_id, n_area0, n_area1;
|
||||
struct pico_ip6 pan;
|
||||
|
||||
/* Copy required command line arguments */
|
||||
nxt = cpy_arg(&name, optarg);
|
||||
if (!nxt)
|
||||
goto check;
|
||||
nxt = cpy_arg(&area0, nxt);
|
||||
if (!nxt)
|
||||
goto check;
|
||||
nxt = cpy_arg(&area1, nxt);
|
||||
if (!nxt)
|
||||
goto check;
|
||||
|
||||
/* Check required arguments */
|
||||
check: if (!name || !area0 || !area1) {
|
||||
fprintf(stderr, "Usage: -6,id,area\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
n_id = (uint8_t) atoi(name);
|
||||
n_area0 = (uint8_t) atoi(area0);
|
||||
n_area1 = (uint8_t) atoi(area1);
|
||||
|
||||
if (nxt) {
|
||||
nxt = cpy_arg(&dump, nxt);
|
||||
}
|
||||
|
||||
printf("%d:%d:%d\n", n_id, n_area0, n_area1);
|
||||
|
||||
if (!n_id) {
|
||||
printf("Starting radio-network...\n");
|
||||
pico_radio_mgr_start();
|
||||
} else {
|
||||
dev = pico_radiotest_create(n_id, n_area0, n_area1, 0, dump);
|
||||
if (!dev) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf("Radiotest created.\n");
|
||||
|
||||
/* Add a routable link */
|
||||
pico_string_to_ipv6(pan_addr, pan.addr);
|
||||
pico_ipv6_link_add_local(dev, &pan);
|
||||
|
||||
/* Enable routing on first device */
|
||||
if (n_id == 1) {
|
||||
pico_ipv6_dev_routing_enable(dev);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'b':
|
||||
{
|
||||
char *nxt, *name = NULL, *sock = NULL;
|
||||
printf("+++ OPTARG %s\n", optarg);
|
||||
do {
|
||||
nxt = cpy_arg(&name, optarg);
|
||||
if (!nxt) break;
|
||||
|
||||
nxt = cpy_arg(&sock, nxt);
|
||||
} while(0);
|
||||
if (!sock) {
|
||||
fprintf(stderr, "Vde: bad configuration...\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
macaddr[4] ^= (uint8_t)(getpid() >> 8);
|
||||
macaddr[5] ^= (uint8_t)(getpid() & 0xFF);
|
||||
dev = pico_vde_create(sock, name, macaddr);
|
||||
NXT_MAC(macaddr);
|
||||
if (!dev) {
|
||||
if (sock)
|
||||
free(sock);
|
||||
|
||||
if (name)
|
||||
free(name);
|
||||
|
||||
perror("Creating vde");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (sock)
|
||||
free(sock);
|
||||
|
||||
if (name)
|
||||
free(name);
|
||||
|
||||
printf("Vde created.\n");
|
||||
}
|
||||
break;
|
||||
case 'l':
|
||||
{
|
||||
struct pico_ip4 ipaddr, netmask;
|
||||
|
||||
dev = pico_loop_create();
|
||||
if (!dev) {
|
||||
perror("Creating loop");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
pico_string_to_ipv4("127.0.0.1", &ipaddr.addr);
|
||||
pico_string_to_ipv4("255.0.0.0", &netmask.addr);
|
||||
pico_ipv4_link_add(dev, ipaddr, netmask);
|
||||
printf("Loopback created\n");
|
||||
#ifdef PICO_SUPPORT_IPV6
|
||||
if (IPV6_MODE) {
|
||||
struct pico_ip6 ipaddr6 = {{0}}, netmask6 = {{0}};
|
||||
pico_string_to_ipv6("::1", ipaddr6.addr);
|
||||
pico_string_to_ipv6("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", netmask6.addr);
|
||||
pico_ipv6_link_add(dev, ipaddr6, netmask6);
|
||||
}
|
||||
|
||||
pico_ipv6_dev_routing_enable(dev);
|
||||
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case 'r':
|
||||
{
|
||||
char *nxt, *addr, *nm, *gw;
|
||||
struct pico_ip4 ipaddr, netmask, gateway;
|
||||
/* XXX adjust for IPv6 */
|
||||
addr = NULL, nm = NULL, gw = NULL;
|
||||
printf("+++ ROUTEOPTARG %s\n", optarg);
|
||||
do {
|
||||
nxt = cpy_arg(&addr, optarg);
|
||||
if (!nxt) break;
|
||||
|
||||
nxt = cpy_arg(&nm, nxt);
|
||||
if (!nxt) break;
|
||||
|
||||
nxt = cpy_arg(&gw, nxt);
|
||||
} while(0);
|
||||
if (!addr || !nm || !gw) {
|
||||
fprintf(stderr, "--route expects addr:nm:gw:\n");
|
||||
usage(argv[0]);
|
||||
}
|
||||
|
||||
pico_string_to_ipv4(addr, &ipaddr.addr);
|
||||
pico_string_to_ipv4(nm, &netmask.addr);
|
||||
pico_string_to_ipv4(gw, &gateway.addr);
|
||||
if (pico_ipv4_route_add(ipaddr, netmask, gateway, 1, NULL) == 0)
|
||||
fprintf(stderr, "ROUTE ADDED *** to %s via %s\n", addr, gw);
|
||||
else
|
||||
fprintf(stderr, "ROUTE ADD: ERROR %s \n", strerror(pico_err));
|
||||
|
||||
break;
|
||||
}
|
||||
case 'd':
|
||||
{
|
||||
/* Add a DNS nameserver IP address */
|
||||
char *straddr;
|
||||
struct pico_ip4 ipaddr;
|
||||
printf("DNS nameserver address = %s\n", optarg);
|
||||
cpy_arg(&straddr, optarg);
|
||||
pico_string_to_ipv4(straddr, &ipaddr.addr);
|
||||
pico_dns_client_nameserver(&ipaddr, PICO_DNS_NS_ADD);
|
||||
break;
|
||||
}
|
||||
case 'a':
|
||||
{
|
||||
char *name = NULL, *args = NULL;
|
||||
printf("+++ OPTARG %s\n", optarg);
|
||||
args = cpy_arg(&name, optarg);
|
||||
|
||||
printf("+++ NAME: %s ARGS: %s\n", name, args);
|
||||
IF_APPNAME("udpecho") {
|
||||
app_udpecho(args);
|
||||
} else IF_APPNAME("tcpecho") {
|
||||
app_tcpecho(args);
|
||||
} else IF_APPNAME("udpclient") {
|
||||
app_udpclient(args);
|
||||
} else IF_APPNAME("tcpclient") {
|
||||
app_tcpclient(args);
|
||||
} else IF_APPNAME("tcpbench") {
|
||||
app_tcpbench(args);
|
||||
} else IF_APPNAME("natbox") {
|
||||
app_natbox(args);
|
||||
} else IF_APPNAME("udpdnsclient") {
|
||||
app_udpdnsclient(args);
|
||||
} else IF_APPNAME("udpnatclient") {
|
||||
app_udpnatclient(args);
|
||||
} else IF_APPNAME("mcastsend") {
|
||||
#ifndef PICO_SUPPORT_MCAST
|
||||
return 0;
|
||||
#endif
|
||||
app_mcastsend(args);
|
||||
} else IF_APPNAME("mcastreceive") {
|
||||
#ifndef PICO_SUPPORT_MCAST
|
||||
return 0;
|
||||
#endif
|
||||
app_mcastreceive(args);
|
||||
}
|
||||
else IF_APPNAME("mcastsend_ipv6") {
|
||||
#ifndef PICO_SUPPORT_MCAST
|
||||
return 0;
|
||||
#endif
|
||||
app_mcastsend_ipv6(args);
|
||||
} else IF_APPNAME("mcastreceive_ipv6") {
|
||||
#ifndef PICO_SUPPORT_MCAST
|
||||
return 0;
|
||||
#endif
|
||||
app_mcastreceive_ipv6(args);
|
||||
}
|
||||
|
||||
#ifdef PICO_SUPPORT_PING
|
||||
else IF_APPNAME("ping") {
|
||||
app_ping(args);
|
||||
}
|
||||
#endif
|
||||
else IF_APPNAME("dhcpserver") {
|
||||
#ifndef PICO_SUPPORT_DHCPD
|
||||
return 0;
|
||||
#else
|
||||
app_dhcp_server(args);
|
||||
#endif
|
||||
} else IF_APPNAME("dhcpclient") {
|
||||
#ifndef PICO_SUPPORT_DHCPC
|
||||
return 0;
|
||||
#else
|
||||
app_dhcp_client(args);
|
||||
#endif
|
||||
} else IF_APPNAME("dns_sd") {
|
||||
#ifndef PICO_SUPPORT_DNS_SD
|
||||
return 0;
|
||||
#else
|
||||
app_dns_sd(args, addr4);
|
||||
#endif
|
||||
} else IF_APPNAME("mdns") {
|
||||
#ifndef PICO_SUPPORT_MDNS
|
||||
return 0;
|
||||
#else
|
||||
app_mdns(args, addr4);
|
||||
#endif
|
||||
#ifdef PICO_SUPPORT_SNTP_CLIENT
|
||||
} else IF_APPNAME("sntp") {
|
||||
app_sntp(args);
|
||||
#endif
|
||||
} else IF_APPNAME("bcast") {
|
||||
struct pico_ip4 any = {
|
||||
.addr = 0xFFFFFFFFu
|
||||
};
|
||||
|
||||
struct pico_socket *s = pico_socket_open(PICO_PROTO_IPV4, PICO_PROTO_UDP, &__wakeup);
|
||||
pico_socket_sendto(s, "abcd", 5u, &any, 1000);
|
||||
|
||||
pico_socket_sendto(s, "abcd", 5u, &bcastAddr, 1000);
|
||||
#ifdef PICO_SUPPORT_TFTP
|
||||
} else IF_APPNAME("tftp") {
|
||||
app_tftp(args);
|
||||
#endif
|
||||
} else IF_APPNAME("noop") {
|
||||
app_noop();
|
||||
#ifdef PICO_SUPPORT_OLSR
|
||||
} else IF_APPNAME("olsr") {
|
||||
dev = pico_get_device("pic0");
|
||||
if(dev) {
|
||||
pico_olsr_add(dev);
|
||||
}
|
||||
|
||||
dev = pico_get_device("pic1");
|
||||
if(dev) {
|
||||
pico_olsr_add(dev);
|
||||
}
|
||||
|
||||
app_noop();
|
||||
#endif
|
||||
} else IF_APPNAME("slaacv4") {
|
||||
#ifndef PICO_SUPPORT_SLAACV4
|
||||
return 0;
|
||||
#else
|
||||
app_slaacv4(args);
|
||||
#endif
|
||||
} else IF_APPNAME("udp_sendto_test") {
|
||||
app_sendto_test(args);
|
||||
} else {
|
||||
fprintf(stderr, "Unknown application %s\n", name);
|
||||
usage(argv[0]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!dev) {
|
||||
printf("nodev");
|
||||
usage(argv[0]);
|
||||
}
|
||||
|
||||
#ifdef FAULTY
|
||||
atexit(memory_stats);
|
||||
#endif
|
||||
printf("%s: launching PicoTCP loop\n", __FUNCTION__);
|
||||
while(1) {
|
||||
pico_stack_tick();
|
||||
usleep(2000);
|
||||
}
|
||||
}
|
||||
193
kernel/picotcp/test/ppp.c
Normal file
193
kernel/picotcp/test/ppp.c
Normal file
@@ -0,0 +1,193 @@
|
||||
#include <pico_stack.h>
|
||||
#include <pico_dev_ppp.h>
|
||||
#include <signal.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <termios.h>
|
||||
#include <pico_icmp4.h>
|
||||
#include <pico_ipv4.h>
|
||||
#include <pico_md5.h>
|
||||
#include <pico_socket.h>
|
||||
#ifdef PICO_SUPPORT_POLARSSL
|
||||
#include <polarssl/md5.h>
|
||||
#endif
|
||||
#ifdef PICO_SUPPORT_CYASSL
|
||||
#include <cyassl/ctaocrypt/md5.h>
|
||||
#endif
|
||||
#define MODEM "/dev/ttyUSB0"
|
||||
#define SPEED 236800
|
||||
/* #define APN "gprs.base.be" */
|
||||
#define APN "web.be"
|
||||
#define PASSWD "web"
|
||||
#define USERNAME "altran"
|
||||
/* #define DEBUG_FLOW */
|
||||
static int fd = -1;
|
||||
static int idx;
|
||||
static int ping_on = 0;
|
||||
static struct pico_device *ppp = NULL;
|
||||
|
||||
static void sigusr1_hdl(int signo)
|
||||
{
|
||||
fprintf(stderr, "SIGUSR1: Connecting!\n");
|
||||
if (ppp)
|
||||
pico_ppp_connect(ppp);
|
||||
}
|
||||
|
||||
static void sigusr2_hdl(int signo)
|
||||
{
|
||||
fprintf(stderr, "SIGUSR2/SIGINT: Disconnecting!\n");
|
||||
if (ppp)
|
||||
pico_ppp_disconnect(ppp);
|
||||
|
||||
if (signo == SIGINT)
|
||||
exit(0);
|
||||
}
|
||||
|
||||
#ifdef PICO_SUPPORT_POLARSSL
|
||||
static void md5sum(uint8_t *dst, const uint8_t *src, size_t len)
|
||||
{
|
||||
md5(src, len, dst);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef PICO_SUPPORT_CYASSL
|
||||
static void md5sum(uint8_t *dst, const uint8_t *src, size_t len)
|
||||
{
|
||||
Md5 md5;
|
||||
InitMd5(&md5);
|
||||
Md5Update(&md5, src, len);
|
||||
Md5Final(&md5, dst);
|
||||
}
|
||||
#endif
|
||||
|
||||
int modem_read(struct pico_device *dev, void *data, int len)
|
||||
{
|
||||
int r;
|
||||
r = read(fd, data, len);
|
||||
#ifdef DEBUG_FLOW
|
||||
if (r > 0) {
|
||||
printf(" <<< ");
|
||||
for(idx = 0; idx < r; idx++) {
|
||||
printf(" %02x", ((uint8_t*)data)[idx]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int modem_write(struct pico_device *dev, const void *data, int len)
|
||||
{
|
||||
int r;
|
||||
#ifdef DEBUG_FLOW
|
||||
printf(" >>> ");
|
||||
for(idx = 0; idx < len; idx++) {
|
||||
printf(" %02x", ((uint8_t*)data)[idx]);
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
r = write(fd, data, len);
|
||||
return r;
|
||||
}
|
||||
|
||||
int modem_set_speed(struct pico_device *dev, uint32_t speed)
|
||||
{
|
||||
struct termios term;
|
||||
if (tcgetattr(fd, &term) != 0)
|
||||
return 6;
|
||||
|
||||
if (cfsetspeed(&term, B115200) != 0)
|
||||
return 7;
|
||||
|
||||
if (tcsetattr(fd, TCSANOW, &term) != 0)
|
||||
return 8;
|
||||
|
||||
printf("Speed set to 115200.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void cb_ping(struct pico_icmp4_stats *s)
|
||||
{
|
||||
char host[30];
|
||||
pico_ipv4_to_string(host, s->dst.addr);
|
||||
if (s->err == 0) {
|
||||
dbg("%lu bytes from %s: icmp_req=%lu ttl=64 time=%lu ms\n", s->size, host, s->seq, s->time);
|
||||
} else {
|
||||
dbg("PING %lu to %s: Error %d\n", s->seq, host, s->err);
|
||||
}
|
||||
}
|
||||
|
||||
static void cb_sock(uint16_t ev, struct pico_socket *s)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static void ping(void)
|
||||
{
|
||||
struct pico_socket *s;
|
||||
struct pico_ip4 dst;
|
||||
|
||||
pico_string_to_ipv4("80.68.95.85", &dst.addr);
|
||||
s = pico_socket_open(PICO_PROTO_IPV4, PICO_PROTO_TCP, cb_sock);
|
||||
pico_socket_connect(s, &dst, short_be(80));
|
||||
pico_icmp4_ping("80.68.95.85", 10, 1000, 4000, 8, cb_ping);
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, const char *argv[])
|
||||
{
|
||||
const char *path = MODEM;
|
||||
const char *apn = APN;
|
||||
const char *passwd = PASSWD;
|
||||
const char *username = USERNAME;
|
||||
|
||||
if (argc > 1)
|
||||
path = argv[1];
|
||||
|
||||
if (argc > 2)
|
||||
apn = argv[2];
|
||||
|
||||
if (argc > 3)
|
||||
passwd = argv[3];
|
||||
|
||||
fd = open(path, O_RDWR);
|
||||
if (fd < 0)
|
||||
return 1;
|
||||
|
||||
fcntl(fd, F_SETFL, O_NONBLOCK);
|
||||
|
||||
signal(SIGUSR1, sigusr1_hdl);
|
||||
signal(SIGUSR2, sigusr2_hdl);
|
||||
signal(SIGINT, sigusr2_hdl);
|
||||
|
||||
pico_stack_init();
|
||||
|
||||
#if defined PICO_SUPPORT_POLARSSL || defined PICO_SUPPORT_CYASSL
|
||||
pico_register_md5sum(md5sum);
|
||||
#endif
|
||||
|
||||
ppp = pico_ppp_create();
|
||||
if (!ppp)
|
||||
return 2;
|
||||
|
||||
pico_ppp_set_serial_read(ppp, modem_read);
|
||||
pico_ppp_set_serial_write(ppp, modem_write);
|
||||
pico_ppp_set_serial_set_speed(ppp, modem_set_speed);
|
||||
|
||||
pico_ppp_set_apn(ppp, apn);
|
||||
pico_ppp_set_password(ppp, passwd);
|
||||
pico_ppp_set_username(ppp, username);
|
||||
|
||||
pico_ppp_connect(ppp);
|
||||
|
||||
while(1 < 2) {
|
||||
pico_stack_tick();
|
||||
usleep(1000);
|
||||
if (ppp->link_state(ppp) && !ping_on) {
|
||||
ping_on++;
|
||||
ping();
|
||||
}
|
||||
}
|
||||
}
|
||||
36
kernel/picotcp/test/python/dhcp.py
Executable file
36
kernel/picotcp/test/python/dhcp.py
Executable file
@@ -0,0 +1,36 @@
|
||||
#!/usr/bin/python
|
||||
# dhcp.py
|
||||
# Butterfly-like topology test for dhcp
|
||||
# One DHCP server, serving on two interface
|
||||
# Eigth DHCP clients, four on each network
|
||||
#
|
||||
# s1----@ @----r1
|
||||
# s2-----\__ DHCP __/-----r2
|
||||
# s3-----/ \-----r3
|
||||
# s4----@ @----r4
|
||||
#
|
||||
|
||||
|
||||
from topology import *
|
||||
|
||||
T = Topology()
|
||||
net1 = Network(T, "pyt1")
|
||||
net2 = Network(T, "pyt2")
|
||||
|
||||
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")
|
||||
|
||||
s1 = Host(T, net1, args="dhcpclient:eth1")
|
||||
s2 = Host(T, net1, args="dhcpclient:eth1")
|
||||
s3 = Host(T, net1, args="dhcpclient:eth1")
|
||||
s4 = Host(T, net1, args="dhcpclient:eth1")
|
||||
r1 = Host(T, net2, args="dhcpclient:eth1")
|
||||
r2 = Host(T, net2, args="dhcpclient:eth1")
|
||||
r3 = Host(T, net2, args="dhcpclient:eth1")
|
||||
r4 = Host(T, net2, args="dhcpclient:eth1")
|
||||
|
||||
raw_input("Press enter to continue ...")
|
||||
start(T)
|
||||
|
||||
wait(server)
|
||||
|
||||
cleanup()
|
||||
48
kernel/picotcp/test/python/fairness.py
Executable file
48
kernel/picotcp/test/python/fairness.py
Executable file
@@ -0,0 +1,48 @@
|
||||
#!/usr/bin/python
|
||||
# fairness.py
|
||||
# A complex test for butterly-like topology,
|
||||
# using 3 TCP connections and 3 ping flows.
|
||||
#
|
||||
# s1---. .---r1
|
||||
# s2----\ /
|
||||
# s3-----\__.R1---R2.__/__.--r2
|
||||
# s4-----/ \
|
||||
# s5----/ \_.--r3
|
||||
# s6---^
|
||||
#
|
||||
|
||||
from topology import *
|
||||
|
||||
T = Topology()
|
||||
net1 = Network(T)
|
||||
net2 = Network(T)
|
||||
net3 = Network(T)
|
||||
|
||||
#router1 = Host(T, net1, net2, "natbox:172.16.2.1:")
|
||||
#router2 = Host(T, net2, net3, "natbox:172.16.3.1:")
|
||||
router1 = Host(T, net1, net2)
|
||||
router2 = Host(T, net2, net3)
|
||||
|
||||
send1 = Host(T, net1, args="tcpbench:t:172.16.3.2:")
|
||||
send2 = Host(T, net1, args="tcpbench:t:172.16.3.3:")
|
||||
send3 = Host(T, net1, args="tcpbench:t:172.16.3.4:")
|
||||
|
||||
send4 = Host(T, net1, args="ping:172.16.3.2:")
|
||||
send5 = Host(T, net1, args="ping:172.16.3.3:")
|
||||
send6 = Host(T, net1, args="ping:172.16.3.4:")
|
||||
|
||||
|
||||
recv1 = Host(T, net3, args="tcpbench:r:")
|
||||
recv2 = Host(T, net3, args="tcpbench:r:")
|
||||
recv3 = Host(T, net3, args="tcpbench:r:")
|
||||
recv4 = Host(T, net3, args="tcpbench:r:")
|
||||
|
||||
|
||||
sleep(1)
|
||||
start(T)
|
||||
|
||||
wait(send1)
|
||||
wait(send2)
|
||||
wait(send3)
|
||||
|
||||
cleanup()
|
||||
47
kernel/picotcp/test/python/fairness_bottleneck.py
Executable file
47
kernel/picotcp/test/python/fairness_bottleneck.py
Executable file
@@ -0,0 +1,47 @@
|
||||
#!/usr/bin/python
|
||||
# fairness.py
|
||||
# A complex test for butterly-like topology,
|
||||
# using 3 TCP connections and 3 ping flows.
|
||||
#
|
||||
# Bottleneck of 4 Mbit/300 ms overall delay is added.
|
||||
#
|
||||
# s1---. .---r1
|
||||
# s2----\ /
|
||||
# s3-----\__.R1---R2.__/__.--r2
|
||||
# s4-----/ \
|
||||
# s5----/ \_.--r3
|
||||
# s6---^
|
||||
#
|
||||
|
||||
from topology import *
|
||||
|
||||
T = Topology()
|
||||
net1 = Network(T)
|
||||
net2 = Network(T)
|
||||
net3 = Network(T)
|
||||
|
||||
router1 = Host(T, net1, net2, delay2="150", bw2="20M")
|
||||
router2 = Host(T, net2, net3)
|
||||
|
||||
send1 = Host(T, net1, args="tcpbench:t:172.16.3.2:")
|
||||
send2 = Host(T, net1, args="tcpbench:t:172.16.3.3:")
|
||||
send3 = Host(T, net1, args="tcpbench:t:172.16.3.4:")
|
||||
|
||||
send4 = Host(T, net1, args="ping:172.16.3.2:")
|
||||
send5 = Host(T, net1, args="ping:172.16.3.3:")
|
||||
send6 = Host(T, net1, args="ping:172.16.3.4:")
|
||||
|
||||
|
||||
recv1 = Host(T, net3, args="tcpbench:r:")
|
||||
recv2 = Host(T, net3, args="tcpbench:r:")
|
||||
recv3 = Host(T, net3, args="tcpbench:r:")
|
||||
|
||||
|
||||
sleep(1)
|
||||
start(T)
|
||||
|
||||
wait(send1)
|
||||
wait(send2)
|
||||
wait(send3)
|
||||
|
||||
cleanup()
|
||||
47
kernel/picotcp/test/python/fairness_bottleneck_linux.py
Executable file
47
kernel/picotcp/test/python/fairness_bottleneck_linux.py
Executable file
@@ -0,0 +1,47 @@
|
||||
#!/usr/bin/python
|
||||
# fairness.py
|
||||
# A complex test for butterly-like topology,
|
||||
# using 3 TCP connections and 3 ping flows.
|
||||
#
|
||||
# Bottleneck of 4 Mbit/300 ms overall delay is added.
|
||||
#
|
||||
# s1---. .---r1
|
||||
# s2----\ /
|
||||
# s3-----\__.R1---R2.__/__.--r2
|
||||
# s4-----/ \
|
||||
# s5----/ \_.--r3
|
||||
# s6---^
|
||||
#
|
||||
|
||||
from topology import *
|
||||
|
||||
T = Topology()
|
||||
net1 = Network(T)
|
||||
net2 = Network(T, "pyt0")
|
||||
net3 = Network(T)
|
||||
|
||||
router1 = Host(T, net1, net2, delay2="150", bw2="4M")
|
||||
router2 = Host(T, net2, net3)
|
||||
|
||||
send1 = Host(T, net1, args="tcpbench:t:172.16.3.2:")
|
||||
send2 = Host(T, net1, args="tcpbench:t:172.16.3.3:")
|
||||
send3 = Host(T, net1, args="tcpbench:t:172.16.3.4:")
|
||||
|
||||
send4 = Host(T, net1, args="ping:172.16.3.2:")
|
||||
send5 = Host(T, net1, args="ping:172.16.3.3:")
|
||||
send6 = Host(T, net1, args="ping:172.16.3.4:")
|
||||
|
||||
|
||||
recv1 = Host(T, net3, args="tcpbench:r:")
|
||||
recv2 = Host(T, net3, args="tcpbench:r:")
|
||||
recv3 = Host(T, net3, args="tcpbench:r:")
|
||||
|
||||
|
||||
sleep(1)
|
||||
start(T)
|
||||
|
||||
wait(send1)
|
||||
wait(send2)
|
||||
wait(send3)
|
||||
|
||||
cleanup()
|
||||
60
kernel/picotcp/test/python/fragmentation.py
Executable file
60
kernel/picotcp/test/python/fragmentation.py
Executable file
@@ -0,0 +1,60 @@
|
||||
#!/usr/bin/python
|
||||
#
|
||||
# fragmentation.py
|
||||
#
|
||||
# Fragmentation test with PicoTCP sending and Linux receiving
|
||||
#
|
||||
# (sender) (Receiver)
|
||||
# PicoTCP ------------------------ Linux
|
||||
#
|
||||
# An udpclient is started which will give DATASIZE bytes in one go
|
||||
# to the socket. This data will be fragmented and send over to the
|
||||
# Linux, where it is reassembled and received in one piece.
|
||||
#
|
||||
|
||||
from topology import *
|
||||
import socket, random, string
|
||||
|
||||
SRC_ADDR = ''
|
||||
DST_ADDR = '172.16.1.1'
|
||||
SRC_PORT = 6667
|
||||
SENDTO_PORT = 6667
|
||||
LISTEN_PORT = 6667
|
||||
DATASIZE = 4000
|
||||
LOOPS = 4
|
||||
SUBLOOPS = 1
|
||||
UDPCLIENT = "udpclient:" + str(DST_ADDR) + ":" + str(SENDTO_PORT) + ":" + str(LISTEN_PORT) + ":" + str(DATASIZE) + ":" + str(LOOPS) + ":" + str(SUBLOOPS)
|
||||
|
||||
print UDPCLIENT
|
||||
|
||||
T = Topology()
|
||||
net1 = Network(T, "pyt0")
|
||||
h1 = Host(T, net1, args=UDPCLIENT)
|
||||
|
||||
s_udp = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
s_udp.bind((SRC_ADDR, SRC_PORT))
|
||||
s_udp.settimeout(5);
|
||||
|
||||
raw_input("Press enter to continue ...")
|
||||
start(T)
|
||||
|
||||
while True:
|
||||
data, addr = s_udp.recvfrom(DATASIZE)
|
||||
#print data
|
||||
if len(data) == DATASIZE:
|
||||
print '\n\n'
|
||||
print '+++++++++++++++++++++++++++++++++++++++++++++'
|
||||
print '+++++ fragmentation test IS successful +++++'
|
||||
print '+++++++++++++++++++++++++++++++++++++++++++++'
|
||||
print '\n\n'
|
||||
cleanup()
|
||||
exit(0)
|
||||
|
||||
print '\n\n'
|
||||
print '+++++++++++++++++++++++++++++++++++++++++++++'
|
||||
print '+++++ fragmentation test NOT successful ++++'
|
||||
print '+++++++++++++++++++++++++++++++++++++++++++++'
|
||||
print '\n\n'
|
||||
cleanup()
|
||||
exit(1)
|
||||
|
||||
135
kernel/picotcp/test/python/howto.py
Normal file
135
kernel/picotcp/test/python/howto.py
Normal file
@@ -0,0 +1,135 @@
|
||||
#PicoTCP topology test environment.
|
||||
#Guidelines to prepare test scenarios.
|
||||
#
|
||||
#The interface is simple, it has three objects:
|
||||
# * Topology
|
||||
# * Network
|
||||
# * Host
|
||||
#
|
||||
#And a handful of helping routines, such as:
|
||||
# * start()
|
||||
# * loop()
|
||||
# * sleep()
|
||||
# * wait()
|
||||
#
|
||||
#
|
||||
########################################################################
|
||||
#== Create a test scenario ==#
|
||||
########################################################################
|
||||
# Every script file will start with: "#!/usr/bin/python" in the first
|
||||
# line, and will have execution permissions. This script is an exception
|
||||
# because it is not intended to be run, as it is in fact a walkthrough to
|
||||
# all the functionalities.
|
||||
|
||||
# Importing the topology objects is mandatory, so add:
|
||||
from topology import *
|
||||
|
||||
# A Topology must be created to use all other objects:
|
||||
T = Topology()
|
||||
|
||||
# Now, we can create "Network" objects. The networks will have address
|
||||
# 172.16.X.0/24, where 'X' is the order of creation, starting from 1.
|
||||
#
|
||||
|
||||
network1 = Network(T)
|
||||
network2 = Network(T)
|
||||
# The two networks are separated and using different address pools:
|
||||
#
|
||||
# ## ### ## ## ## ### ## ##
|
||||
# # network1 # # network2 #
|
||||
# # 172.16.1.0 # # 172.16.2.0 #
|
||||
# ## ## ###### ## ## ######
|
||||
#
|
||||
|
||||
# If you are running your test as root, you can also add a tun-tap connection
|
||||
# to the network, which will be automatically configured:
|
||||
networkLocal = Network(T,'tap0')
|
||||
|
||||
|
||||
# In the same way ad networks, you can create a PicoTCP Host that connects to a
|
||||
# network as follows:
|
||||
host1_1 = Host(T, network1)
|
||||
|
||||
# Also, you can specify a role for the application/host, by using picoapp's
|
||||
# args format for '--app'. For example, the machine below will ping the previously
|
||||
# created one:
|
||||
host1_2 = Host(T, network1, args ="ping:172.16.1.1:")
|
||||
#
|
||||
# ## ### ## ## ## ### ## ##
|
||||
# host1.1--# network1 # # network2 #
|
||||
# # 172.16.1.0 # # 172.16.2.0 #
|
||||
# ## ## ###### ## ## ######
|
||||
# /
|
||||
# host1.2___/
|
||||
# (ping host1.1)
|
||||
#
|
||||
|
||||
# At this point, a picoTCP host with two network cards can connect
|
||||
# the two networks like this:
|
||||
router1 = Host(T, network1, network2)
|
||||
#
|
||||
# ## ### ## ## router1 ## ### ## ##
|
||||
# host1.1--# network1 #__/ \__ # network2 #
|
||||
# # 172.16.1.0 # # 172.16.2.0 #
|
||||
# ## ## ###### ## ## ######
|
||||
# /
|
||||
# host1.2___/
|
||||
# (ping host1.1)
|
||||
|
||||
# Now, we can attach an host to the second network too:
|
||||
# Connection to the host can be an emulated channel, i.e.
|
||||
# it is possible to add bidirectional delay and limited
|
||||
# bandwidth in the link between the host and the network:
|
||||
#
|
||||
|
||||
host2_2 = Host(network2, delay1="100", bw1="500K")
|
||||
#
|
||||
# ## ### ## ## router1 ## ### ## ##
|
||||
# host1.1--# network1 #__/ \__ # network2 #
|
||||
# # 172.16.1.0 # # 172.16.2.0 #
|
||||
# ## ## ###### ## ## ######
|
||||
# / *
|
||||
# host1.2.__/ \._*_*_host2.2
|
||||
# (ping host1.1)
|
||||
|
||||
## Since the routes will be automatically added before the test starts,
|
||||
# all the hosts in the networks will be reachable to each other:
|
||||
# all the picoapps will have their static routes populated automatically
|
||||
# by the topology tool, no matter how complex the network is. The only
|
||||
# requirement is that all the networks share at least one router.
|
||||
#
|
||||
# For this reason, we can create a host that pings across the network:
|
||||
host1_4 = Host(T, network1, args="ping:172.16.2.2:")
|
||||
#
|
||||
# host1.4.
|
||||
# (ping 2.2) \
|
||||
# \## ### ## ## router1 ## ### ## ##
|
||||
# host1.1--# network1 #__/ \__ # network2 #
|
||||
# # 172.16.1.0 # # 172.16.2.0 #
|
||||
# ## ## ###### ## ## ######
|
||||
# / *
|
||||
# host1.2.__/ \._*_*_host2.2
|
||||
# (ping host1.1)
|
||||
|
||||
########################################################################
|
||||
#== Start the test ==#
|
||||
########################################################################
|
||||
# All the host will be connected and activated when you call:
|
||||
start()
|
||||
|
||||
# At this point you may want to define your exit strategy. Valid commands
|
||||
# are:
|
||||
|
||||
loop() # Loop forever, until the test is interrupted (e.g. by ctrl+c)
|
||||
|
||||
sleep(N) # Sleep N seconds
|
||||
|
||||
wait(host1_4) # Wait for application running on host 1.4, and return only if
|
||||
# it has terminated
|
||||
|
||||
|
||||
########################################################################
|
||||
#== End the test ==#
|
||||
########################################################################
|
||||
# Always call:
|
||||
cleanup()
|
||||
13
kernel/picotcp/test/python/http_server_linux.py
Executable file
13
kernel/picotcp/test/python/http_server_linux.py
Executable file
@@ -0,0 +1,13 @@
|
||||
#!/usr/bin/python
|
||||
from topology import *
|
||||
|
||||
T = Topology()
|
||||
net1 = Network(T, "pyt0")
|
||||
|
||||
h2 = Host(T, net1, args="httpd")
|
||||
|
||||
sleep(1)
|
||||
start(T)
|
||||
|
||||
wait(h2)
|
||||
cleanup()
|
||||
64
kernel/picotcp/test/python/multicast_recv.py
Executable file
64
kernel/picotcp/test/python/multicast_recv.py
Executable file
@@ -0,0 +1,64 @@
|
||||
#!/usr/bin/python
|
||||
# multicast_recv.py
|
||||
#
|
||||
# Multicast test with PicoTCP receiving and Linux sending
|
||||
#
|
||||
# (sender) (Receiver)
|
||||
# Linux ------------------------ PicoTCP
|
||||
# mcast to 224.7.7.7
|
||||
#
|
||||
from topology import *
|
||||
import socket, random, string
|
||||
|
||||
IF_ADDR = '172.16.1.1'
|
||||
LINK_ADDR = '172.16.1.2'
|
||||
MCAST_ADDR = '224.7.7.7'
|
||||
SRC_PORT = 5555
|
||||
LISTEN_PORT = 6667
|
||||
SENDTO_PORT = 6667
|
||||
MCASTRECV = "mcastreceive:" + str(LINK_ADDR) + ":" + str(MCAST_ADDR) + ":" + str(LISTEN_PORT) + ":" + str(SENDTO_PORT)
|
||||
|
||||
print MCASTRECV
|
||||
|
||||
T = Topology()
|
||||
net1 = Network(T, "pyt0")
|
||||
h1 = Host(T, net1, args=MCASTRECV)
|
||||
|
||||
# sending socket
|
||||
s_udp = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
s_udp.bind((IF_ADDR, SRC_PORT))
|
||||
s_udp.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||
s_udp.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)
|
||||
s_udp.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_IF, socket.inet_aton(str(IF_ADDR)))
|
||||
|
||||
# receiving socket
|
||||
s_udp_recv = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
s_udp_recv.bind((IF_ADDR, LISTEN_PORT))
|
||||
s_udp_recv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||
s_udp_recv.settimeout(5);
|
||||
|
||||
raw_input("Press enter to continue ...")
|
||||
start(T)
|
||||
sleep(1)
|
||||
|
||||
while True:
|
||||
s_udp.sendto("multicast test succeeded", (str(MCAST_ADDR), LISTEN_PORT))
|
||||
data = s_udp_recv.recv(4096)
|
||||
#print data
|
||||
if 'succeeded' in data:
|
||||
print '\n\n'
|
||||
print '+++++++++++++++++++++++++++++++++++++++++++++'
|
||||
print '+++++ multicast_recv test IS successful +++++'
|
||||
print '+++++++++++++++++++++++++++++++++++++++++++++'
|
||||
print '\n\n'
|
||||
cleanup()
|
||||
exit(0)
|
||||
|
||||
print '\n\n'
|
||||
print '+++++++++++++++++++++++++++++++++++++++++++++'
|
||||
print '+++++ multicast_recv test NOT successful ++++'
|
||||
print '+++++++++++++++++++++++++++++++++++++++++++++'
|
||||
print '\n\n'
|
||||
cleanup()
|
||||
exit(1)
|
||||
|
||||
58
kernel/picotcp/test/python/multicast_send.py
Executable file
58
kernel/picotcp/test/python/multicast_send.py
Executable file
@@ -0,0 +1,58 @@
|
||||
#!/usr/bin/python
|
||||
#
|
||||
# multicast_send.py
|
||||
#
|
||||
# Multicast test with PicoTCP sending and Linux receiving
|
||||
#
|
||||
# (sender) (Receiver)
|
||||
# PicoTCP ------------------------ Linux
|
||||
# mcast to 224.7.7.7
|
||||
#
|
||||
|
||||
from topology import *
|
||||
import socket, random, string, struct
|
||||
|
||||
IF_ADDR = '172.16.1.1'
|
||||
LINK_ADDR = '172.16.1.2'
|
||||
MCAST_ADDR = '224.7.7.7'
|
||||
LISTEN_PORT = 6667
|
||||
SENDTO_PORT = 6667
|
||||
MCASTSEND = "mcastsend:" + str(LINK_ADDR) + ":" + str(MCAST_ADDR) + ":" + str(SENDTO_PORT) + ":" + str(LISTEN_PORT)
|
||||
|
||||
print MCASTSEND
|
||||
|
||||
T = Topology()
|
||||
net1 = Network(T, "pyt0")
|
||||
h1 = Host(T, net1, args=MCASTSEND)
|
||||
|
||||
s_udp = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
s_udp.bind((MCAST_ADDR, LISTEN_PORT))
|
||||
s_udp.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||
s_udp.settimeout(5);
|
||||
|
||||
mreq = struct.pack("=4s4s", socket.inet_aton(str(MCAST_ADDR)), socket.inet_aton(str(IF_ADDR)))
|
||||
s_udp.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)
|
||||
|
||||
raw_input("Press enter to continue ...")
|
||||
start(T)
|
||||
sleep(1)
|
||||
|
||||
while True:
|
||||
data = s_udp.recv(4096)
|
||||
#print data
|
||||
if 'end' in data:
|
||||
print '\n\n'
|
||||
print '+++++++++++++++++++++++++++++++++++++++++++++'
|
||||
print '+++++ multicast_send test IS successful +++++'
|
||||
print '+++++++++++++++++++++++++++++++++++++++++++++'
|
||||
print '\n\n'
|
||||
cleanup()
|
||||
exit(0)
|
||||
|
||||
print '\n\n'
|
||||
print '+++++++++++++++++++++++++++++++++++++++++++++'
|
||||
print '+++++ multicast_send test NOT successful ++++'
|
||||
print '+++++++++++++++++++++++++++++++++++++++++++++'
|
||||
print '\n\n'
|
||||
cleanup()
|
||||
exit(1)
|
||||
14
kernel/picotcp/test/python/noop.py
Executable file
14
kernel/picotcp/test/python/noop.py
Executable file
@@ -0,0 +1,14 @@
|
||||
#!/usr/bin/python
|
||||
from topology import *
|
||||
|
||||
T = Topology()
|
||||
net1 = Network(T, "pyt0")
|
||||
|
||||
#h1 = Host(T, net1)
|
||||
h2 = Host(T, net1, args="noop")
|
||||
|
||||
sleep(1)
|
||||
start(T)
|
||||
|
||||
wait(h2)
|
||||
cleanup()
|
||||
14
kernel/picotcp/test/python/ping.py
Executable file
14
kernel/picotcp/test/python/ping.py
Executable file
@@ -0,0 +1,14 @@
|
||||
#!/usr/bin/python
|
||||
from topology import *
|
||||
|
||||
T = Topology()
|
||||
net1 = Network(T)
|
||||
|
||||
h1 = Host(T, net1)
|
||||
h2 = Host(T, net1, args="ping:172.16.1.1:")
|
||||
|
||||
sleep(1)
|
||||
start(T)
|
||||
|
||||
wait(h2)
|
||||
cleanup()
|
||||
14
kernel/picotcp/test/python/ping_delay.py
Executable file
14
kernel/picotcp/test/python/ping_delay.py
Executable file
@@ -0,0 +1,14 @@
|
||||
#!/usr/bin/python
|
||||
from topology import *
|
||||
|
||||
T = Topology()
|
||||
net1 = Network(T)
|
||||
|
||||
h1 = Host(T, net1, delay1="200")
|
||||
h2 = Host(T, net1, args="ping:172.16.1.1:")
|
||||
|
||||
sleep(1)
|
||||
start(T)
|
||||
|
||||
wait(h2)
|
||||
cleanup()
|
||||
14
kernel/picotcp/test/python/ping_linux.py
Executable file
14
kernel/picotcp/test/python/ping_linux.py
Executable file
@@ -0,0 +1,14 @@
|
||||
#!/usr/bin/python
|
||||
from topology import *
|
||||
|
||||
T = Topology()
|
||||
net1 = Network(T, "pyt0")
|
||||
|
||||
#h1 = Host(T, net1)
|
||||
h2 = Host(T, net1, args="ping:172.16.1.1:")
|
||||
|
||||
sleep(1)
|
||||
start(T)
|
||||
|
||||
wait(h2)
|
||||
cleanup()
|
||||
17
kernel/picotcp/test/python/ping_nat.py
Executable file
17
kernel/picotcp/test/python/ping_nat.py
Executable file
@@ -0,0 +1,17 @@
|
||||
#!/usr/bin/python
|
||||
from topology import *
|
||||
|
||||
T = Topology()
|
||||
net1 = Network(T, 'nat0')
|
||||
net2 = Network(T)
|
||||
|
||||
|
||||
h1 = Host(T, net1, args="ping:172.16.2.1:")
|
||||
h2 = Host(T, net2)
|
||||
router1 = Host(T, net1, net2, args="natbox:172.16.2.2:")
|
||||
|
||||
sleep(1)
|
||||
start(T)
|
||||
|
||||
wait(h1)
|
||||
cleanup()
|
||||
62
kernel/picotcp/test/python/reassembly.py
Executable file
62
kernel/picotcp/test/python/reassembly.py
Executable file
@@ -0,0 +1,62 @@
|
||||
#!/usr/bin/python
|
||||
#
|
||||
# reassemby.py
|
||||
#
|
||||
# Reassemly test with PicoTCP receiving and Linux sending
|
||||
#
|
||||
# (receiver) (Sender)
|
||||
# PicoTCP ------------------------ Linux
|
||||
#
|
||||
# An udpecho is started which will receive DATASIZE bytes in one go
|
||||
# from the socket. The Linux will send DATASIZE bytes in one go to the
|
||||
# udpecho, this data will be sent fragmented. The udpecho is to reassemble
|
||||
# this data and echo it back.
|
||||
#
|
||||
|
||||
from topology import *
|
||||
import socket, random, string
|
||||
|
||||
SRC_ADDR = ''
|
||||
LINK_ADDR = '172.16.1.2'
|
||||
SRC_PORT = 5555
|
||||
LISTEN_PORT = 6667
|
||||
SENDTO_PORT = 5555
|
||||
DATASIZE = 3400
|
||||
UDPECHO = "udpecho:" + str(LINK_ADDR) + ":" + str(LISTEN_PORT) + ":" + str(SENDTO_PORT) + ":" + str(DATASIZE)
|
||||
|
||||
print UDPECHO
|
||||
|
||||
T = Topology()
|
||||
net1 = Network(T, "pyt0")
|
||||
h1 = Host(T, net1, args=UDPECHO)
|
||||
|
||||
str_send = ''.join(random.choice(string.ascii_lowercase) for x in range(DATASIZE))
|
||||
#print str_send
|
||||
s_udp = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
s_udp.bind((SRC_ADDR, SRC_PORT))
|
||||
s_udp.settimeout(5);
|
||||
|
||||
raw_input("Press enter to continue ...")
|
||||
start(T)
|
||||
|
||||
while True:
|
||||
s_udp.sendto(str_send, (LINK_ADDR, LISTEN_PORT))
|
||||
data = s_udp.recv(DATASIZE)
|
||||
#print len(data)
|
||||
if len(data) == DATASIZE:
|
||||
print '\n\n'
|
||||
print '+++++++++++++++++++++++++++++++++++++++++++++'
|
||||
print '+++++ reassembly test IS successful +++++'
|
||||
print '+++++++++++++++++++++++++++++++++++++++++++++'
|
||||
print '\n\n'
|
||||
cleanup()
|
||||
exit(0)
|
||||
|
||||
print '\n\n'
|
||||
print '+++++++++++++++++++++++++++++++++++++++++++++'
|
||||
print '+++++ reassembly test NOT successful ++++'
|
||||
print '+++++++++++++++++++++++++++++++++++++++++++++'
|
||||
print '\n\n'
|
||||
cleanup()
|
||||
exit(1)
|
||||
|
||||
18
kernel/picotcp/test/python/tcpbench-delay.py
Executable file
18
kernel/picotcp/test/python/tcpbench-delay.py
Executable file
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/python
|
||||
#
|
||||
|
||||
from topology import *
|
||||
|
||||
T = Topology()
|
||||
net1 = Network(T, "vde0")
|
||||
|
||||
send1 = Host(T, net1, args="tcpbench:t:172.16.1.3:7770:")
|
||||
recv1 = Host(T, net1, args="tcpbench:r:7770:", delay1="30", loss1="1")
|
||||
|
||||
|
||||
sleep(1)
|
||||
raw_input("Press enter to continue ...")
|
||||
|
||||
start(T)
|
||||
wait(send1)
|
||||
cleanup()
|
||||
17
kernel/picotcp/test/python/tcpbench-tap.py
Executable file
17
kernel/picotcp/test/python/tcpbench-tap.py
Executable file
@@ -0,0 +1,17 @@
|
||||
#!/usr/bin/python
|
||||
#
|
||||
|
||||
from topology import *
|
||||
|
||||
T = Topology()
|
||||
net1 = Network(T, "pyt0")
|
||||
send1 = Host(T, net1, args="tcpbench:t:172.16.1.3:7770:")
|
||||
recv1 = Host(T, net1, args="tcpbench:r:7770:")
|
||||
|
||||
|
||||
sleep(1)
|
||||
raw_input("Press enter to continue ...")
|
||||
|
||||
start(T)
|
||||
wait(send1)
|
||||
cleanup()
|
||||
17
kernel/picotcp/test/python/tcpbench.py
Executable file
17
kernel/picotcp/test/python/tcpbench.py
Executable file
@@ -0,0 +1,17 @@
|
||||
#!/usr/bin/python
|
||||
#
|
||||
|
||||
from topology import *
|
||||
|
||||
T = Topology()
|
||||
net1 = Network(T)
|
||||
send1 = Host(T, net1, args="tcpbench:t:172.16.1.2:7770:")
|
||||
recv1 = Host(T, net1, args="tcpbench:r:7770:")
|
||||
|
||||
|
||||
sleep(1)
|
||||
#raw_input("Press enter to continue ...")
|
||||
|
||||
start(T)
|
||||
wait(send1)
|
||||
cleanup()
|
||||
14
kernel/picotcp/test/python/tcpbench_rx_linux.py
Executable file
14
kernel/picotcp/test/python/tcpbench_rx_linux.py
Executable file
@@ -0,0 +1,14 @@
|
||||
#!/usr/bin/python
|
||||
from topology import *
|
||||
|
||||
T = Topology()
|
||||
net1 = Network(T, "pyt0")
|
||||
|
||||
h2 = Host(T, net1, args="tcpbench:r:6660:")
|
||||
|
||||
sleep(1)
|
||||
raw_input("Press enter to continue ...")
|
||||
start(T)
|
||||
|
||||
wait(h2)
|
||||
cleanup()
|
||||
15
kernel/picotcp/test/python/tcpbench_tx_linux.py
Executable file
15
kernel/picotcp/test/python/tcpbench_tx_linux.py
Executable file
@@ -0,0 +1,15 @@
|
||||
#!/usr/bin/python
|
||||
from topology import *
|
||||
|
||||
T = Topology()
|
||||
net1 = Network(T, "pyt0")
|
||||
|
||||
#h1 = Host(T, net1)
|
||||
h3 = Host(T, net1, args="tcpbench:t:172.16.1.1:6660:")
|
||||
|
||||
sleep(1)
|
||||
raw_input("Press enter to continue ...")
|
||||
start(T)
|
||||
|
||||
wait(h3)
|
||||
cleanup()
|
||||
16
kernel/picotcp/test/python/tcpecho_linux.py
Executable file
16
kernel/picotcp/test/python/tcpecho_linux.py
Executable file
@@ -0,0 +1,16 @@
|
||||
#!/usr/bin/python
|
||||
from topology import *
|
||||
|
||||
T = Topology()
|
||||
net1 = Network(T, "pyt0")
|
||||
|
||||
#h1 = Host(T, net1)
|
||||
h2 = Host(T, net1, args="tcpecho:8888", delay1="20", loss1="0.01")
|
||||
#h3 = Host(T, net1, args="tcpbench:t:172.16.1.1:")
|
||||
|
||||
sleep(1)
|
||||
start(T)
|
||||
|
||||
#wait(h3)
|
||||
wait(h2)
|
||||
cleanup()
|
||||
223
kernel/picotcp/test/python/topology.py
Executable file
223
kernel/picotcp/test/python/topology.py
Executable file
@@ -0,0 +1,223 @@
|
||||
#!/usr/bin/python
|
||||
# Python classes definition for the picoTCP
|
||||
# topology test environment
|
||||
#
|
||||
# Copyright (c) 2013-2017 Altran Intelligent Systems. See LICENSE for usage.
|
||||
|
||||
import sys, os, subprocess, time, re
|
||||
|
||||
def test_tuntap():
|
||||
if not os.geteuid()==0:
|
||||
sys.exit("\nOnly root can use real devices contained in this script\n")
|
||||
|
||||
class Topology:
|
||||
def __init__(self):
|
||||
self.nets = []
|
||||
self.nodes = []
|
||||
self.nextn = 1
|
||||
self.hosts = []
|
||||
|
||||
|
||||
class Network:
|
||||
def __init__(self, topology, real=''):
|
||||
self.n = topology.nextn
|
||||
topology.nextn += 1
|
||||
self.nodes = []
|
||||
self.topology = topology
|
||||
self.topology.nets.append(self)
|
||||
self.sock = "/tmp/topology/net"+`self.n`
|
||||
self.nextn = 1
|
||||
vdecmd = ["vde_switch", "-x" , "-s", self.sock, "-m", self.sock+".mgmt"]
|
||||
if real != '':
|
||||
test_tuntap()
|
||||
vdecmd.append('-t')
|
||||
vdecmd.append(real)
|
||||
vdecmd.append('-x')
|
||||
self.pop = subprocess.Popen(vdecmd, stdin=subprocess.PIPE)
|
||||
self.hosts = []
|
||||
print ""
|
||||
print vdecmd
|
||||
print "Created network "+self.sock
|
||||
if real != '':
|
||||
subprocess.call(["ifconfig",real,"172.16."+`self.n`+".1", "netmask", "255.255.255.0", "up"])
|
||||
self.nextn = 2
|
||||
|
||||
class Node:
|
||||
def __init__(self,topology, network = None):
|
||||
if (network is None):
|
||||
network = Network(topology)
|
||||
self.net = network
|
||||
self.n = network.nextn
|
||||
network.nextn += 1
|
||||
self.net.nodes.append(self)
|
||||
self.topology = topology
|
||||
self.topology.nodes.append(self)
|
||||
|
||||
class Host:
|
||||
def add_routes(self, topology):
|
||||
for eth in [self.eth1, self.eth2]:
|
||||
if eth and not self.args.startswith("dhcpclient"):
|
||||
net = eth.net
|
||||
for h in topology.hosts:
|
||||
if h.eth1 and h.eth2:
|
||||
dst=""
|
||||
gw=""
|
||||
routing=False
|
||||
if (h.eth2.net.n == net.n) and (self not in h.eth1.net.hosts):
|
||||
if h.eth1.net.n > net.n or h.nat == False:
|
||||
print "FOUND route to net "+`h.eth1.net.n`
|
||||
dst_net = h.eth1.net.n
|
||||
gw_net = h.eth2.net.n
|
||||
gw_n = h.eth2.n
|
||||
routing=True
|
||||
elif (h.eth1.net.n == net.n) and (self not in h.eth2.net.hosts):
|
||||
if h.eth2.net.n > net.n or h.nat == False:
|
||||
print "FOUND route to net "+`h.eth2.net.n`
|
||||
dst_net = h.eth2.net.n
|
||||
gw_net = h.eth1.net.n
|
||||
gw_n = h.eth1.n
|
||||
routing=True
|
||||
|
||||
if (routing):
|
||||
dst = "172.16."+`dst_net`+".0"
|
||||
gw = "172.16."+`gw_net`+"."+`gw_n`
|
||||
self.routes.append("-r")
|
||||
self.routes.append(dst+":255.255.255.0:"+gw+":")
|
||||
if (routing and gw_net > dst_net and h.nat == False):
|
||||
dst_net -= 1
|
||||
while(dst_net > 0):
|
||||
dst = "172.16."+`dst_net`+".0"
|
||||
self.routes.append("-r")
|
||||
self.routes.append(dst+":255.255.255.0:"+gw+":")
|
||||
dst_net -= 1
|
||||
elif (routing and gw_net != None and gw_net < dst_net):
|
||||
dst_net += 1
|
||||
while(dst_net < net.topology.nextn):
|
||||
dst = "172.16."+`dst_net`+".0"
|
||||
self.routes.append("-r")
|
||||
self.routes.append(dst+":255.255.255.0:"+gw+":")
|
||||
dst_net += 1
|
||||
def parse_options(self, eth, delay, bw, loss):
|
||||
if (delay != "" or bw != ""):
|
||||
mysock = eth.net.sock + "__" + `eth.n`
|
||||
wirecmd = ['wirefilter', '-v']
|
||||
wirecmd.append(mysock +":" + eth.net.sock)
|
||||
if (delay != ''):
|
||||
wirecmd.append("-d")
|
||||
wirecmd.append(delay)
|
||||
if (bw != ''):
|
||||
wirecmd.append("-b")
|
||||
wirecmd.append(bw)
|
||||
if (loss != ''):
|
||||
wirecmd.append("-l")
|
||||
wirecmd.append(loss)
|
||||
print wirecmd
|
||||
subprocess.Popen(['vde_switch', '-s', mysock], stdin=subprocess.PIPE)
|
||||
subprocess.Popen(wirecmd, stdin=subprocess.PIPE)
|
||||
else:
|
||||
mysock = eth.net.sock
|
||||
return mysock
|
||||
|
||||
def __init__(self, topology, net1=None, net2=None, gw=None, args="tcpecho:5555", delay1="", bw1="", delay2="", bw2="", loss1="", loss2=""):
|
||||
if net1:
|
||||
self.eth1 = Node(topology, net1)
|
||||
net1.hosts.append(self)
|
||||
else:
|
||||
self.eth1 = None
|
||||
if net2:
|
||||
self.eth2 = Node(topology, net2)
|
||||
net2.hosts.append(self)
|
||||
else:
|
||||
self.eth2 = None
|
||||
self.cmd = ["./build/test/picoapp.elf"]
|
||||
self.gw = gw
|
||||
if args.startswith("nat"):
|
||||
self.nat = True
|
||||
else:
|
||||
self.nat = False
|
||||
|
||||
|
||||
if (net1):
|
||||
mysock = self.parse_options(self.eth1, delay1, bw1, loss1)
|
||||
if (args.startswith("dhcpclient")):
|
||||
self.cmd.append("--barevde")
|
||||
vdeline = "eth1:"+mysock+':'
|
||||
else:
|
||||
self.cmd.append("--vde")
|
||||
vdeline = "eth1:"+mysock+':'+"172.16."+`self.eth1.net.n`+"."+`self.eth1.n`+":255.255.255.0:"
|
||||
if (self.gw and re.search("172\.16\."+`self.eth1.net`, self.gw)):
|
||||
vdeline +=self.gw+":"
|
||||
self.cmd.append(vdeline)
|
||||
if (net2):
|
||||
mysock = self.parse_options(self.eth2, delay2, bw2, loss2)
|
||||
if (args.startswith("dhcpclient")):
|
||||
self.cmd.append("--barevde")
|
||||
vdeline = "eth2:"+mysock+':'
|
||||
else:
|
||||
self.cmd.append("--vde")
|
||||
vdeline = "eth2:"+mysock+':'+"172.16."+`self.eth2.net.n`+"."+`self.eth2.n`+":255.255.255.0:"
|
||||
if (self.gw and re.search("172\.16\."+`self.eth2.net`+".", self.gw)):
|
||||
vdeline +=self.gw+":"
|
||||
self.cmd.append(vdeline)
|
||||
self.args = args
|
||||
self.pop = None
|
||||
topology.hosts.append(self)
|
||||
self.routes = []
|
||||
|
||||
|
||||
def start(self):
|
||||
if self.pop:
|
||||
return
|
||||
for r in self.routes:
|
||||
self.cmd.append(r)
|
||||
self.cmd.append("-a")
|
||||
self.cmd.append(self.args)
|
||||
print self.cmd
|
||||
self.pop = subprocess.Popen(self.cmd)
|
||||
|
||||
|
||||
|
||||
def cleanup():
|
||||
try:
|
||||
subprocess.call(["killall","vde_switch"])
|
||||
subprocess.call(["killall","picoapp.elf"])
|
||||
subprocess.call(["killall","wirefilter"])
|
||||
os.unlink("/tmp/topology")
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
|
||||
def loop():
|
||||
while(True):
|
||||
time.sleep(1)
|
||||
sys.exit(0)
|
||||
|
||||
def sleep(n):
|
||||
time.sleep(n)
|
||||
|
||||
def wait(x):
|
||||
if (x is None):
|
||||
print("start failed: "+x.cmd)
|
||||
sys.exit(1)
|
||||
while (x.pop.poll() == None):
|
||||
time.sleep(1)
|
||||
print "Goodbye"
|
||||
sys.exit(0)
|
||||
|
||||
def start(T):
|
||||
print "Calculating routes.."
|
||||
for n in T.nets:
|
||||
for h in n.hosts:
|
||||
h.add_routes(T)
|
||||
print "Done!"
|
||||
print "Starting up..."
|
||||
for n in T.nets:
|
||||
for h in n.hosts:
|
||||
h.start()
|
||||
|
||||
try:
|
||||
os.mkdir("/tmp/topology/")
|
||||
except:
|
||||
pass
|
||||
cleanup()
|
||||
45
kernel/picotcp/test/python/traceroute_from_linux.py
Executable file
45
kernel/picotcp/test/python/traceroute_from_linux.py
Executable file
@@ -0,0 +1,45 @@
|
||||
#!/usr/bin/python
|
||||
from topology import *
|
||||
|
||||
'''
|
||||
Add route to 172.16.0.0/16 gw 172.16.1.2 on your host machine.
|
||||
|
||||
Should result in something like:
|
||||
~$ traceroute 172.16.8.2
|
||||
traceroute to 172.16.8.2 (172.16.8.2), 30 hops max, 60 byte packets
|
||||
1 172.16.1.2 (172.16.1.2) 0.481 ms 0.473 ms 0.467 ms
|
||||
2 172.16.2.2 (172.16.2.2) 4.680 ms 4.702 ms 4.700 ms
|
||||
3 172.16.3.2 (172.16.3.2) 8.759 ms 8.768 ms 8.766 ms
|
||||
4 172.16.4.2 (172.16.4.2) 10.791 ms 10.789 ms 10.786 ms
|
||||
5 172.16.5.2 (172.16.5.2) 12.826 ms 12.825 ms 12.821 ms
|
||||
6 172.16.6.2 (172.16.6.2) 14.844 ms 17.858 ms 17.857 ms
|
||||
7 172.16.7.2 (172.16.7.2) 17.858 ms 14.000 ms 13.999 ms
|
||||
8 172.16.8.2 (172.16.8.2) 18.032 ms 18.029 ms 18.023 ms
|
||||
|
||||
'''
|
||||
|
||||
|
||||
T = Topology()
|
||||
net1 = Network(T, 'nat0')
|
||||
net2 = Network(T)
|
||||
net3 = Network(T)
|
||||
net4 = Network(T)
|
||||
net5 = Network(T)
|
||||
net6 = Network(T)
|
||||
net7 = Network(T)
|
||||
net8 = Network(T)
|
||||
|
||||
router1 = Host(T, net1, net2)
|
||||
router2 = Host(T, net2, net3)
|
||||
router3 = Host(T, net3, net4)
|
||||
router4 = Host(T, net4, net5)
|
||||
router5 = Host(T, net5, net6)
|
||||
router6 = Host(T, net6, net7)
|
||||
router7 = Host(T, net7, net8)
|
||||
|
||||
h1 = Host(T, net8)
|
||||
|
||||
sleep(1)
|
||||
start(T)
|
||||
loop()
|
||||
cleanup()
|
||||
45
kernel/picotcp/test/python/traceroute_nat_from_linux.py
Executable file
45
kernel/picotcp/test/python/traceroute_nat_from_linux.py
Executable file
@@ -0,0 +1,45 @@
|
||||
#!/usr/bin/python
|
||||
from topology import *
|
||||
|
||||
'''
|
||||
Add route to 172.16.0.0/16 gw 172.16.1.2 on your host machine.
|
||||
|
||||
Should result in something like:
|
||||
~$ traceroute 172.16.8.2
|
||||
traceroute to 172.16.8.2 (172.16.8.2), 30 hops max, 60 byte packets
|
||||
1 172.16.1.2 (172.16.1.2) 0.481 ms 0.473 ms 0.467 ms
|
||||
2 172.16.2.2 (172.16.2.2) 4.680 ms 4.702 ms 4.700 ms
|
||||
3 172.16.3.2 (172.16.3.2) 8.759 ms 8.768 ms 8.766 ms
|
||||
4 172.16.4.2 (172.16.4.2) 10.791 ms 10.789 ms 10.786 ms
|
||||
5 172.16.5.2 (172.16.5.2) 12.826 ms 12.825 ms 12.821 ms
|
||||
6 172.16.6.2 (172.16.6.2) 14.844 ms 17.858 ms 17.857 ms
|
||||
7 172.16.7.2 (172.16.7.2) 17.858 ms 14.000 ms 13.999 ms
|
||||
8 172.16.8.2 (172.16.8.2) 18.032 ms 18.029 ms 18.023 ms
|
||||
|
||||
'''
|
||||
|
||||
|
||||
T = Topology()
|
||||
net1 = Network(T, 'nat0')
|
||||
net2 = Network(T)
|
||||
net3 = Network(T)
|
||||
net4 = Network(T)
|
||||
net5 = Network(T)
|
||||
net6 = Network(T)
|
||||
net7 = Network(T)
|
||||
net8 = Network(T)
|
||||
|
||||
router1 = Host(T, net1, net2, args="natbox:172.16.2.1")
|
||||
router2 = Host(T, net2, net3, args="natbox:172.16.3.1")
|
||||
router3 = Host(T, net3, net4, args="natbox:172.16.4.1")
|
||||
router4 = Host(T, net4, net5, args="natbox:172.16.5.1")
|
||||
router5 = Host(T, net5, net6, args="natbox:172.16.6.1")
|
||||
router6 = Host(T, net6, net7, args="natbox:172.16.7.1")
|
||||
router7 = Host(T, net7, net8, args="natbox:172.16.8.1")
|
||||
|
||||
h1 = Host(T, net8)
|
||||
|
||||
sleep(1)
|
||||
start(T)
|
||||
loop()
|
||||
cleanup()
|
||||
16
kernel/picotcp/test/python/udpecho.py
Executable file
16
kernel/picotcp/test/python/udpecho.py
Executable file
@@ -0,0 +1,16 @@
|
||||
#!/usr/bin/python
|
||||
#
|
||||
|
||||
from topology import *
|
||||
|
||||
T = Topology()
|
||||
net1 = Network(T,"udp0")
|
||||
echo = Host(T, net1, args="udpecho:172.16.1.2:7770:7770:1400:")
|
||||
|
||||
|
||||
sleep(1)
|
||||
raw_input("Press enter to continue ...")
|
||||
|
||||
start(T)
|
||||
wait(echo)
|
||||
cleanup()
|
||||
34
kernel/picotcp/test/python/zmq_linux.py
Executable file
34
kernel/picotcp/test/python/zmq_linux.py
Executable file
@@ -0,0 +1,34 @@
|
||||
#!/usr/bin/python
|
||||
from topology import *
|
||||
import zmq
|
||||
import sys
|
||||
|
||||
T = Topology()
|
||||
net1 = Network(T, "pyt0")
|
||||
|
||||
#h1 = Host(T, net1)
|
||||
h2 = Host(T, net1, args="zeromq_prod:")
|
||||
|
||||
sleep(1)
|
||||
raw_input("Press enter to continue ...")
|
||||
start(T)
|
||||
|
||||
# Zeromq part
|
||||
ctx = zmq.Context()
|
||||
z = ctx.socket(zmq.SUB)
|
||||
z.setsockopt(zmq.SUBSCRIBE, "")
|
||||
z.connect("tcp://172.16.1.2:1207")
|
||||
print "In the loop..."
|
||||
for i in range(20):
|
||||
if z.poll(20000) == 0:
|
||||
print "Timeout!!!"
|
||||
cleanup()
|
||||
sys.exit(1)
|
||||
else:
|
||||
msg = z.recv()
|
||||
print "Recvd msg len=%d content: %s" % (len(msg), msg)
|
||||
|
||||
|
||||
|
||||
|
||||
cleanup()
|
||||
244
kernel/picotcp/test/test_tftp_app_client.c
Normal file
244
kernel/picotcp/test/test_tftp_app_client.c
Normal file
@@ -0,0 +1,244 @@
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <inttypes.h>
|
||||
#include "pico_stack.h"
|
||||
#include "pico_config.h"
|
||||
#include "pico_ipv4.h"
|
||||
#include "pico_icmp4.h"
|
||||
#include "pico_socket.h"
|
||||
#include "pico_stack.h"
|
||||
#include "pico_device.h"
|
||||
#include "pico_dev_vde.h"
|
||||
#include "pico_tftp.h"
|
||||
|
||||
static struct pico_device *pico_dev;
|
||||
|
||||
int32_t get_filesize(const char *filename)
|
||||
{
|
||||
int ret;
|
||||
struct stat buf;
|
||||
|
||||
ret = stat(filename, &buf);
|
||||
if (ret)
|
||||
return -1;
|
||||
|
||||
return buf.st_size;
|
||||
}
|
||||
|
||||
void start_rx(struct pico_tftp_session *session, int *synchro, const char *filename, int options)
|
||||
{
|
||||
int ret;
|
||||
int fd;
|
||||
int32_t len;
|
||||
uint8_t buf[PICO_TFTP_PAYLOAD_SIZE];
|
||||
int left = 1000;
|
||||
int countdown = 0;
|
||||
|
||||
printf("Start receiving file %s with options set to %d\n", filename, options);
|
||||
|
||||
if (options) {
|
||||
ret = pico_tftp_set_option(session, PICO_TFTP_OPTION_FILE, 0);
|
||||
if (ret) {
|
||||
fprintf(stderr, "Error in pico_tftp_set_option\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
ret = pico_tftp_app_start_rx(session, filename);
|
||||
if (ret) {
|
||||
fprintf(stderr, "Error in pico_tftp_app_start_rx\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
fd = open(filename, O_WRONLY | O_EXCL | O_CREAT, 0664);
|
||||
if (!fd) {
|
||||
fprintf(stderr, "Error in open\n");
|
||||
countdown = 1;
|
||||
}
|
||||
|
||||
for(; left; left -= countdown) {
|
||||
usleep(2000); /* PICO_IDLE(); */
|
||||
pico_stack_tick();
|
||||
if (countdown)
|
||||
continue;
|
||||
|
||||
if (*synchro) {
|
||||
len = pico_tftp_get(session, buf, PICO_TFTP_PAYLOAD_SIZE);
|
||||
if (len < 0) {
|
||||
fprintf(stderr, "Failure in pico_tftp_get\n");
|
||||
close(fd);
|
||||
countdown = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
ret = write(fd, buf, len);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error in write\n");
|
||||
pico_tftp_abort(session, TFTP_ERR_EXCEEDED, "File write error");
|
||||
close(fd);
|
||||
countdown = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
printf("Written %" PRId32 " bytes to file (synchro=%d)\n", len, *synchro);
|
||||
|
||||
if (len != PICO_TFTP_PAYLOAD_SIZE) {
|
||||
close(fd);
|
||||
printf("Transfer complete!\n");
|
||||
countdown = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void start_tx(struct pico_tftp_session *session, int *synchro, const char *filename, int options)
|
||||
{
|
||||
int ret;
|
||||
int fd;
|
||||
int32_t len;
|
||||
uint8_t buf[PICO_TFTP_PAYLOAD_SIZE];
|
||||
int left = 1000;
|
||||
int countdown = 0;
|
||||
|
||||
printf("Start sending file %s with options set to %d\n", filename, options);
|
||||
|
||||
if (options) {
|
||||
ret = get_filesize(filename);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error in get_filesize\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ret = pico_tftp_set_option(session, PICO_TFTP_OPTION_FILE, ret);
|
||||
if (ret) {
|
||||
fprintf(stderr, "Error in pico_tftp_set_option\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
ret = pico_tftp_app_start_tx(session, filename);
|
||||
if (ret) {
|
||||
fprintf(stderr, "Error in pico_tftp_app_start_rx\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
fd = open(filename, O_RDONLY, 0444);
|
||||
if (!fd) {
|
||||
fprintf(stderr, "Error in open\n");
|
||||
pico_tftp_abort(session, TFTP_ERR_EACC, "Error opening file");
|
||||
countdown = 1;
|
||||
}
|
||||
|
||||
for(; left; left -= countdown) {
|
||||
usleep(2000); /* PICO_IDLE(); */
|
||||
pico_stack_tick();
|
||||
if (countdown)
|
||||
continue;
|
||||
|
||||
if (*synchro) {
|
||||
ret = read(fd, buf, PICO_TFTP_PAYLOAD_SIZE);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error in read\n");
|
||||
pico_tftp_abort(session, TFTP_ERR_EACC, "File read error");
|
||||
close(fd);
|
||||
countdown = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
printf("Read %" PRId32 " bytes from file (synchro=%d)\n", len, *synchro);
|
||||
|
||||
len = pico_tftp_put(session, buf, ret);
|
||||
if (len < 0) {
|
||||
fprintf(stderr, "Failure in pico_tftp_put\n");
|
||||
close(fd);
|
||||
countdown = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (len != PICO_TFTP_PAYLOAD_SIZE) {
|
||||
close(fd);
|
||||
printf("Transfer complete!\n");
|
||||
countdown = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void usage(const char *text)
|
||||
{
|
||||
fprintf(stderr, "%s\nArguments must be <filename> <mode>\n"
|
||||
"<mode> can be:\n"
|
||||
"\tg => GET request without options\n"
|
||||
"\tG => GET request WITH options\n"
|
||||
"\tp => PUT request without options\n"
|
||||
"\tP => PUT request WITH options\n\n",
|
||||
text);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int main(int argc, char**argv)
|
||||
{
|
||||
struct pico_ip4 my_ip;
|
||||
union pico_address server_address;
|
||||
struct pico_ip4 netmask;
|
||||
struct pico_tftp_session *session;
|
||||
int synchro;
|
||||
int options = 0;
|
||||
void (*operation)(struct pico_tftp_session *session, int *synchro, const char *filename, int options);
|
||||
|
||||
unsigned char macaddr[6] = {
|
||||
0, 0, 0, 0xa, 0xb, 0x0
|
||||
};
|
||||
|
||||
uint16_t *macaddr_low = (uint16_t *) (macaddr + 2);
|
||||
*macaddr_low = *macaddr_low ^ (uint16_t)((uint16_t)getpid() & (uint16_t)0xFFFFU);
|
||||
macaddr[4] ^= (uint8_t)(getpid() >> 8);
|
||||
macaddr[5] ^= (uint8_t) (getpid() & 0xFF);
|
||||
|
||||
pico_string_to_ipv4("10.40.0.10", &my_ip.addr);
|
||||
pico_string_to_ipv4("255.255.255.0", &netmask.addr);
|
||||
pico_string_to_ipv4("10.40.0.2", &server_address.ip4.addr);
|
||||
|
||||
if (argc != 3) {
|
||||
usage("Invalid number or arguments");
|
||||
}
|
||||
|
||||
switch (argv[2][0]) {
|
||||
case 'G':
|
||||
options = 1;
|
||||
case 'g':
|
||||
operation = start_rx;
|
||||
break;
|
||||
case 'P':
|
||||
options = 1;
|
||||
case 'p':
|
||||
operation = start_tx;
|
||||
break;
|
||||
default:
|
||||
usage("Invalid mode");
|
||||
}
|
||||
|
||||
printf("%s start!\n", argv[0]);
|
||||
pico_stack_init();
|
||||
pico_dev = (struct pico_device *) pico_vde_create("/tmp/vde_switch", "tap0", macaddr);
|
||||
|
||||
if(!pico_dev) {
|
||||
fprintf(stderr, "Error creating pico device, got enough privileges? Exiting...\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
pico_ipv4_link_add(pico_dev, my_ip, netmask);
|
||||
printf("Starting picoTCP loop\n");
|
||||
|
||||
session = pico_tftp_app_setup(&server_address, short_be(PICO_TFTP_PORT), PICO_PROTO_IPV4, &synchro);
|
||||
if (!session) {
|
||||
fprintf(stderr, "Error in pico_tftp_app_setup\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf("synchro %d\n", synchro);
|
||||
|
||||
operation(session, &synchro, argv[1], options);
|
||||
}
|
||||
1634
kernel/picotcp/test/unit/modunit_pico_6lowpan.c
Normal file
1634
kernel/picotcp/test/unit/modunit_pico_6lowpan.c
Normal file
File diff suppressed because it is too large
Load Diff
556
kernel/picotcp/test/unit/modunit_pico_802154.c
Normal file
556
kernel/picotcp/test/unit/modunit_pico_802154.c
Normal file
@@ -0,0 +1,556 @@
|
||||
#include "pico_addressing.h"
|
||||
#include "pico_ipv6_nd.h"
|
||||
#include "pico_stack.h"
|
||||
#include "pico_frame.h"
|
||||
#include "pico_ipv6.h"
|
||||
#include "pico_6lowpan.h"
|
||||
#include "modules/pico_802154.c"
|
||||
#include "check.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/*******************************************************************************
|
||||
* MACROS
|
||||
******************************************************************************/
|
||||
|
||||
#define STARTING() \
|
||||
printf("*********************** STARTING %s ***\n", __func__); \
|
||||
fflush(stdout)
|
||||
#define TRYING(s, ...) \
|
||||
printf("Trying %s: " s, __func__, ##__VA_ARGS__); \
|
||||
fflush(stdout)
|
||||
#define CHECKING(i) \
|
||||
printf("Checking the results of test %2d in %s...", (i)++, \
|
||||
__func__); \
|
||||
fflush(stdout)
|
||||
#define FAIL_UNLESS(cond, s, ...) \
|
||||
if ((cond)) { \
|
||||
printf(" SUCCESS\n"); \
|
||||
} else { \
|
||||
printf(" FAILED\n"); \
|
||||
} \
|
||||
fail_unless((cond), s, ##__VA_ARGS__)
|
||||
#define FAIL_IF(cond, s, ...) \
|
||||
if (!(cond)) { \
|
||||
printf(" SUCCESS\n"); \
|
||||
} else { \
|
||||
printf(" FAILED\n"); \
|
||||
} \
|
||||
fail_if((cond), s, ##__VA_ARGS__)
|
||||
#define ENDING(i) \
|
||||
printf("*********************** ENDING %s *** NUMBER OF TESTS: %d\n",\
|
||||
__func__, ((i)-1)); \
|
||||
fflush(stdout)
|
||||
#define DBG(s, ...) \
|
||||
printf(s, ##__VA_ARGS__); \
|
||||
fflush(stdout)
|
||||
|
||||
/*******************************************************************************
|
||||
* HELPER FUNCTIONS
|
||||
******************************************************************************/
|
||||
|
||||
static void dbg_addr_ext(const char *msg, uint8_t a[SIZE_6LOWPAN_EXT])
|
||||
{
|
||||
DBG("%s: (64-bit extended address): ", msg);
|
||||
DBG("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
|
||||
a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7]);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* ADDRESSES
|
||||
******************************************************************************/
|
||||
|
||||
START_TEST(tc_swap)
|
||||
{
|
||||
int test = 1;
|
||||
uint8_t a = 5;
|
||||
uint8_t b = 1;
|
||||
|
||||
STARTING();
|
||||
|
||||
// TEST 1
|
||||
TRYING("With a = %d and b = %d\n", a, b);
|
||||
pico_swap(&a, &b);
|
||||
CHECKING(test);
|
||||
FAIL_IF(1 != a && b != 5, "Failed swapping numbers\n");
|
||||
|
||||
ENDING(test);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_802154_to_ietf)
|
||||
{
|
||||
int test = 1;
|
||||
struct pico_802154 a = {
|
||||
.addr.data = { 1,2,3,4,5,6,7,8 },
|
||||
.mode = AM_6LOWPAN_EXT
|
||||
};
|
||||
uint8_t buf[] = {8,7,6,5,4,3,2,1};
|
||||
|
||||
STARTING();
|
||||
|
||||
// TEST 1
|
||||
TRYING("Extended address mode\n");
|
||||
addr_802154_to_ietf(&a);
|
||||
dbg_addr_ext("After", a.addr.data);
|
||||
CHECKING(test);
|
||||
FAIL_UNLESS(0 == memcmp(a.addr.data, buf, SIZE_6LOWPAN_EXT),
|
||||
"Failed converting to IETF endianness\n");
|
||||
|
||||
// TEST 2
|
||||
TRYING("Short address mode\n");
|
||||
a.mode = AM_6LOWPAN_SHORT;
|
||||
addr_802154_to_ietf(&a);
|
||||
dbg_addr_ext("After", a.addr.data);
|
||||
CHECKING(test);
|
||||
FAIL_UNLESS(a.addr._short.addr == short_be(0x0708),
|
||||
"Failed converting short to IETF endianness\n");
|
||||
|
||||
// TEST 3
|
||||
TRYING("Wrong address mode\n");
|
||||
a.mode = AM_6LOWPAN_NONE;
|
||||
addr_802154_to_ietf(&a);
|
||||
dbg_addr_ext("After", a.addr.data);
|
||||
buf[0] = 7;
|
||||
buf[1] = 8;
|
||||
CHECKING(test);
|
||||
FAIL_UNLESS(0 == memcmp(a.addr.data, buf, SIZE_6LOWPAN_EXT),
|
||||
"Should've done nothing\n");
|
||||
|
||||
ENDING(test);
|
||||
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_802154_ll_src)
|
||||
{
|
||||
int test = 1;
|
||||
struct pico_ip6 ip = {
|
||||
.addr = {0,0,0,0,0,0,0,0, 3,2,3,4,5,6,7,8}
|
||||
};
|
||||
struct pico_ip6 ip2 = {
|
||||
.addr = {0,0,0,0,0,0,0,0, 0,0,0,0xff,0xfe,0,0x12,0x34}
|
||||
};
|
||||
struct pico_6lowpan_info info = {
|
||||
.addr_short.addr = short_be(0x1234),
|
||||
.addr_ext.addr = {3,2,3,4,5,6,7,8}
|
||||
};
|
||||
struct pico_device dev;
|
||||
struct pico_802154 addr;
|
||||
struct pico_frame *f = pico_frame_alloc(sizeof(struct pico_ipv6_hdr));
|
||||
struct pico_ipv6_hdr *hdr = (struct pico_ipv6_hdr *)f->buffer;
|
||||
|
||||
STARTING();
|
||||
|
||||
dev.eth = (struct pico_ethdev *)&info;
|
||||
f->net_hdr = f->buffer;
|
||||
f->dev = &dev;
|
||||
dev.hostvars.lowpan_flags = PICO_6LP_FLAG_LOWPAN;
|
||||
|
||||
// TEST 3
|
||||
TRYING("With an IPv6 address that is derived from MAC short address\n");
|
||||
info.addr_short.addr = short_be(0x1234);
|
||||
hdr->src = ip2;
|
||||
addr = addr_802154_ll_src(f);
|
||||
CHECKING(test);
|
||||
FAIL_UNLESS(AM_6LOWPAN_SHORT == addr.mode,
|
||||
"Should've returned device's short address \n");
|
||||
CHECKING(test);
|
||||
FAIL_UNLESS(short_be(0x1234) == addr.addr._short.addr,
|
||||
"Should've copied the short address from the device\n");
|
||||
|
||||
// TEST 4
|
||||
TRYING("With an IPv6 address that is derived from MAC extended address\n");
|
||||
ip.addr[8] = 1;
|
||||
hdr->src = ip;
|
||||
addr = addr_802154_ll_src(f);
|
||||
CHECKING(test);
|
||||
FAIL_UNLESS(AM_6LOWPAN_EXT == addr.mode,
|
||||
"Should've returned device's extended address\n");
|
||||
CHECKING(test);
|
||||
FAIL_UNLESS(0 == memcmp(info.addr_ext.addr, addr.addr._ext.addr, SIZE_6LOWPAN_EXT),
|
||||
"Should've copied device's extended address\n");
|
||||
|
||||
ENDING(test);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_802154_ll_dst)
|
||||
{
|
||||
int test = 1;
|
||||
struct pico_ip6 ip;
|
||||
struct pico_ip6 local;
|
||||
struct pico_ip6 local2;
|
||||
struct pico_802154 addr;
|
||||
struct pico_frame *f = pico_frame_alloc(sizeof(struct pico_ipv6_hdr));
|
||||
struct pico_ipv6_hdr *hdr = (struct pico_ipv6_hdr *)f->buffer;
|
||||
struct pico_device dev;
|
||||
uint8_t buf[] = {3,2,3,4,5,6,7,8};
|
||||
pico_string_to_ipv6("ff00:0:0:0:0:0:e801:100", ip.addr);
|
||||
pico_string_to_ipv6("fe80:0:0:0:0102:0304:0506:0708", local.addr);
|
||||
pico_string_to_ipv6("fe80:0:0:0:0:0ff:fe00:1234", local2.addr);
|
||||
|
||||
STARTING();
|
||||
|
||||
f->net_hdr = f->buffer;
|
||||
f->dev = &dev;
|
||||
dev.hostvars.lowpan_flags = PICO_6LP_FLAG_LOWPAN;
|
||||
|
||||
// TEST 1
|
||||
TRYING("With a MCAST IPv6 address, should return 0xFFFF\n");
|
||||
hdr->dst = ip;
|
||||
addr = addr_802154_ll_dst(f);
|
||||
CHECKING(test);
|
||||
FAIL_UNLESS(AM_6LOWPAN_SHORT == addr.mode,
|
||||
"Should've set address mode to SHORT\n");
|
||||
CHECKING(test);
|
||||
FAIL_UNLESS(short_be(ADDR_802154_BCAST) == addr.addr._short.addr,
|
||||
"Should've set address to BCAST\n");
|
||||
|
||||
// TEST 2
|
||||
TRYING("With a link local IPv6 address derived from an extended L2 address\n");
|
||||
hdr->dst = local;
|
||||
addr = addr_802154_ll_dst(f);
|
||||
dbg_addr_ext("After:", addr.addr._ext.addr);
|
||||
CHECKING(test);
|
||||
FAIL_UNLESS(AM_6LOWPAN_EXT == addr.mode,
|
||||
"Should've set address mode to EXTENDED\n");
|
||||
CHECKING(test);
|
||||
FAIL_UNLESS(0 == memcmp(buf, addr.addr._ext.addr, SIZE_6LOWPAN_EXT),
|
||||
"Should've copied the extended address from the IP address\n");
|
||||
|
||||
// TEST 3
|
||||
TRYING("With a link local IPv6 address derived from a short L2 address\n");
|
||||
hdr->dst = local2;
|
||||
addr = addr_802154_ll_dst(f);
|
||||
CHECKING(test);
|
||||
FAIL_UNLESS(AM_6LOWPAN_SHORT == addr.mode,
|
||||
"Should've set address mode to SHORT\n");
|
||||
CHECKING(test);
|
||||
FAIL_UNLESS(short_be(0x1234) == addr.addr._short.addr,
|
||||
"Should've copied the short address from the IP address\n");
|
||||
|
||||
/* TODO: Test getting address from neighbour table */
|
||||
|
||||
ENDING(test);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* FRAME
|
||||
******************************************************************************/
|
||||
|
||||
/* Frame (123 bytes) */
|
||||
static uint8_t pkt[] = {
|
||||
0x41, 0xcc, 0xa6, 0xff, 0xff, 0x8a, /* A..... */
|
||||
0x18, 0x00, 0xff, 0xff, 0xda, 0x1c, 0x00, 0x88, /* ........ */
|
||||
0x18, 0x00, 0xff, 0xff, 0xda, 0x1c, 0x00, 0xc1, /* ........ */
|
||||
0x09, 0x00, 0x02, 0x42, 0xfa, 0x40, 0x04, 0x01, /* ...B.@.. */
|
||||
0xf0, 0xb1, 0x01, 0x06, 0x6f, 0xaf, 0x48, 0x65, /* ....o.He */
|
||||
0x6c, 0x6c, 0x6f, 0x20, 0x30, 0x30, 0x36, 0x20, /* llo 006 */
|
||||
0x30, 0x78, 0x46, 0x46, 0x33, 0x43, 0x0a, 0x00, /* 0xFF3C.. */
|
||||
0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, /* ........ */
|
||||
0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, /* ...... ! */
|
||||
0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, /* "#$%&'() */
|
||||
0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, /* *+,-./01 */
|
||||
0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, /* 23456789 */
|
||||
0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, /* :;<=>?@A */
|
||||
0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, /* BCDEFGHI */
|
||||
0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, /* JKLMNOPQ */
|
||||
0x52, 0x53, 0x54, 0x68, 0x79 /* RSThy */
|
||||
};
|
||||
|
||||
START_TEST(tc_dst_am)
|
||||
{
|
||||
int test = 1;
|
||||
int ret = 0;
|
||||
|
||||
STARTING();
|
||||
|
||||
// TEST 1
|
||||
TRYING("Trying to determine AM of destination addr from buffer \n");
|
||||
ret = dst_am((struct pico_802154_hdr *)pkt);
|
||||
DBG("ret = %d\n", ret);
|
||||
CHECKING(test);
|
||||
FAIL_UNLESS(AM_6LOWPAN_EXT == ret,
|
||||
"Should've returned the AM of an extended address\n");
|
||||
|
||||
ENDING(test);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_src_am)
|
||||
{
|
||||
int test = 1;
|
||||
int ret = 0;
|
||||
|
||||
STARTING();
|
||||
|
||||
// TEST 1
|
||||
TRYING("Trying to determine AM of source addr from buffer \n");
|
||||
ret = src_am((struct pico_802154_hdr *)pkt);
|
||||
DBG("ret = %d\n", ret);
|
||||
CHECKING(test);
|
||||
FAIL_UNLESS(AM_6LOWPAN_EXT == ret,
|
||||
"Should've returned the AM of an extended address\n");
|
||||
|
||||
ENDING(test);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_802154_hdr_len)
|
||||
{
|
||||
int test = 1;
|
||||
int ret = 0;
|
||||
|
||||
STARTING();
|
||||
|
||||
// TEST 1
|
||||
TRYING("Trying to determine length of the header from buffer\n");
|
||||
ret = frame_802154_hdr_len((struct pico_802154_hdr *)pkt);
|
||||
DBG("ret = %d\n", ret);
|
||||
CHECKING(test);
|
||||
FAIL_UNLESS(21 == ret,
|
||||
"Should've returned the correct length of the header\n");
|
||||
|
||||
ENDING(test);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_802154_src)
|
||||
{
|
||||
int test = 1;
|
||||
struct pico_802154_hdr *hdr;
|
||||
struct pico_802154 addr;
|
||||
uint8_t src[] = {0x00, 0x1C, 0xDA, 0xFF, 0xFF, 0x00, 0x18, 0x88};
|
||||
STARTING();
|
||||
|
||||
hdr = (struct pico_802154_hdr *)pkt;
|
||||
|
||||
// TEST 1
|
||||
TRYING("To receive the source address from a mapped buffer\n");
|
||||
addr = frame_802154_src(hdr);
|
||||
CHECKING(test);
|
||||
FAIL_UNLESS(AM_6LOWPAN_EXT == addr.mode,
|
||||
"Should've returned an extended address\n");
|
||||
CHECKING(test);
|
||||
FAIL_UNLESS(0 == memcmp(src, addr.addr._ext.addr, SIZE_6LOWPAN_EXT),
|
||||
"Should've copied the extended source address\n");
|
||||
|
||||
ENDING(test);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_802154_dst)
|
||||
{
|
||||
int test = 1;
|
||||
struct pico_802154_hdr *hdr;
|
||||
struct pico_802154 addr;
|
||||
uint8_t dst[] = {0x00, 0x1C, 0xDA, 0xFF, 0xFF, 0x00, 0x18, 0x8a};
|
||||
|
||||
STARTING();
|
||||
hdr = (struct pico_802154_hdr *)pkt;
|
||||
|
||||
// TEST 1
|
||||
TRYING("To receive the source address from a mapped buffer\n");
|
||||
addr = frame_802154_dst(hdr);
|
||||
CHECKING(test);
|
||||
FAIL_UNLESS(AM_6LOWPAN_EXT == addr.mode,
|
||||
"Should've returned an extended address\n");
|
||||
CHECKING(test);
|
||||
FAIL_UNLESS(0 == memcmp(dst, addr.addr._ext.addr, SIZE_6LOWPAN_EXT),
|
||||
"Should've copied the extended source address\n");
|
||||
|
||||
ENDING(test);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_802154_format)
|
||||
{
|
||||
int test = 1;
|
||||
struct pico_802154 src = {
|
||||
.addr.data = {0x00, 0x1C, 0xDA, 0xFF, 0xFF, 0x00, 0x18, 0x88},
|
||||
.mode = AM_6LOWPAN_EXT
|
||||
};
|
||||
struct pico_802154 dst = {
|
||||
.addr.data = {0x00, 0x1C, 0xDA, 0xFF, 0xFF, 0x00, 0x18, 0x8a},
|
||||
.mode = AM_6LOWPAN_EXT
|
||||
};
|
||||
struct pico_6lowpan_short pan = { .addr = short_be(0xffff) };
|
||||
uint8_t buf[127] = {0};
|
||||
int i = 0;
|
||||
|
||||
STARTING();
|
||||
|
||||
// TEST 1
|
||||
TRYING("To format a frame like sample capture\n");
|
||||
frame_802154_format(buf, 166, FCF_INTRA_PAN, FCF_NO_ACK_REQ,
|
||||
FCF_NO_SEC, pan, src, dst);
|
||||
printf("Buffer:");
|
||||
for (i = 0; i < 21; i++) {
|
||||
if (i % 8 != 0)
|
||||
printf("%02x ", buf[i]);
|
||||
else {
|
||||
printf("\n%02x ", buf[i]);
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
CHECKING(test);
|
||||
FAIL_UNLESS(21 == frame_802154_hdr_len((struct pico_802154_hdr *)buf),
|
||||
"Failed to correctly set the frame header, the length isn't right\n");
|
||||
CHECKING(test);
|
||||
FAIL_UNLESS(0 == memcmp(pkt, buf, 21),
|
||||
"Failed to correctly format IEEE802.15.4 frame\n");
|
||||
|
||||
ENDING(test);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_802154_process_out)
|
||||
{
|
||||
int i = 0;
|
||||
int ret = 0;
|
||||
int test = 1;
|
||||
struct pico_802154 src = {
|
||||
.addr.data = {3,2,3,4,5,6,7,8},
|
||||
.mode = AM_6LOWPAN_EXT
|
||||
};
|
||||
struct pico_802154 dst = {
|
||||
.addr.data = {0x00, 0x1C, 0xDA, 0xFF, 0xFF, 0x00, 0x18, 0x8a},
|
||||
.mode = AM_6LOWPAN_EXT
|
||||
};
|
||||
struct pico_frame *f = pico_frame_alloc(0);
|
||||
struct pico_6lowpan_info info = {
|
||||
.addr_short.addr = short_be(0x1234),
|
||||
.addr_ext.addr = {3,2,3,4,5,6,7,8},
|
||||
.pan_id.addr = short_be(0x1234)
|
||||
};
|
||||
struct pico_device dev;
|
||||
uint8_t buf[] = {0x41,0xcc,0x00,0x34,0x12,0x8a,0x18,0x00,
|
||||
0xff,0xff,0xda,0x1c,0x00,0x08,0x07,0x06,
|
||||
0x05,0x04,0x03,0x02,0x03};
|
||||
dev.eth = (struct pico_ethdev *)&info;
|
||||
dev.q_out = PICO_ZALLOC(sizeof(struct pico_queue));
|
||||
f->dev = &dev;
|
||||
dev.hostvars.lowpan_flags = PICO_6LP_FLAG_LOWPAN;
|
||||
|
||||
STARTING();
|
||||
pico_stack_init();
|
||||
|
||||
// TEST 1
|
||||
TRYING("Trying with bare frame\n");
|
||||
f->src.pan = src;
|
||||
f->dst.pan = dst;
|
||||
ret = pico_802154_process_out(f);
|
||||
printf("Buffer:");
|
||||
for (i = 0; i < 21; i++) {
|
||||
if (i % 8 != 0)
|
||||
printf("%02x ", f->datalink_hdr[i]);
|
||||
else {
|
||||
printf("\n%02x ", f->datalink_hdr[i]);
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
CHECKING(test);
|
||||
FAIL_UNLESS(0 < ret, "Shouldn't have returned an error\n");
|
||||
CHECKING(test);
|
||||
FAIL_UNLESS(0 == memcmp(buf, f->datalink_hdr, 21),
|
||||
"Frame isn't correctly formatted\n");
|
||||
|
||||
pico_frame_discard(f);
|
||||
|
||||
ENDING(test);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_802154_process_in)
|
||||
{
|
||||
int ret = 0;
|
||||
int test = 1;
|
||||
struct pico_802154 src = {
|
||||
.addr.data = {3,2,3,4,5,6,7,8},
|
||||
.mode = AM_6LOWPAN_EXT
|
||||
};
|
||||
struct pico_802154 dst = {
|
||||
.addr.data = {0x00, 0x1C, 0xDA, 0xFF, 0xFF, 0x00, 0x18, 0x8a},
|
||||
.mode = AM_6LOWPAN_EXT
|
||||
};
|
||||
struct pico_frame *f = pico_frame_alloc(22);
|
||||
uint8_t buf[] = {0x41,0xcc,0x00,0x34,0x12,0x8a,0x18,0x00,
|
||||
0xff,0xff,0xda,0x1c,0x00,0x08,0x07,0x06,
|
||||
0x05,0x04,0x03,0x02,0x03,0x60};
|
||||
memcpy(f->buffer, buf, 22);
|
||||
f->src.pan = src;
|
||||
f->dst.pan = dst;
|
||||
|
||||
STARTING();
|
||||
pico_stack_init();
|
||||
|
||||
TRYING("Apply processing function on predefined buffer\n");
|
||||
ret = pico_802154_process_in(f);
|
||||
CHECKING(test);
|
||||
FAIL_UNLESS(0 < ret, "Should not return failure\n");
|
||||
}
|
||||
END_TEST
|
||||
static Suite *pico_suite(void)
|
||||
{
|
||||
Suite *s = suite_create("PicoTCP");
|
||||
|
||||
TCase *TCase_swap = tcase_create("Unit test for pico_swap");
|
||||
TCase *TCase_802154_to_ietf = tcase_create("Unit test for 802154_to_ietf");
|
||||
TCase *TCase_802154_ll_src = tcase_create("Unit test for 802154_ll_src");
|
||||
TCase *TCase_802154_ll_dst = tcase_create("Unit test for 802154_ll_dst");
|
||||
TCase *TCase_802154_hdr_len = tcase_create("Unit test for 802154_hdr_len");
|
||||
TCase *TCase_src_am = tcase_create("Unit test for src_am");
|
||||
TCase *TCase_dst_am = tcase_create("Unit test for dst_am");
|
||||
TCase *TCase_802154_src = tcase_create("Unit test for 802154_src");
|
||||
TCase *TCase_802154_dst = tcase_create("Unit test for 802154_dst");
|
||||
TCase *TCase_802154_format = tcase_create("Unit test for 802154_format");
|
||||
TCase *TCase_802154_process_out = tcase_create("Unit test for 802154_process_out");
|
||||
TCase *TCase_802154_process_in = tcase_create("Unit test for 802154_process_in");
|
||||
|
||||
/*******************************************************************************
|
||||
* ADDRESSES
|
||||
******************************************************************************/
|
||||
tcase_add_test(TCase_swap, tc_swap);
|
||||
suite_add_tcase(s, TCase_swap);
|
||||
tcase_add_test(TCase_802154_to_ietf, tc_802154_to_ietf);
|
||||
suite_add_tcase(s, TCase_802154_to_ietf);
|
||||
tcase_add_test(TCase_802154_ll_src, tc_802154_ll_src);
|
||||
suite_add_tcase(s, TCase_802154_ll_src);
|
||||
tcase_add_test(TCase_802154_ll_dst, tc_802154_ll_dst);
|
||||
suite_add_tcase(s, TCase_802154_ll_dst);
|
||||
|
||||
/*******************************************************************************
|
||||
* FRAME
|
||||
******************************************************************************/
|
||||
tcase_add_test(TCase_802154_hdr_len, tc_802154_hdr_len);
|
||||
suite_add_tcase(s, TCase_802154_hdr_len);
|
||||
tcase_add_test(TCase_src_am, tc_src_am);
|
||||
suite_add_tcase(s, TCase_src_am);
|
||||
tcase_add_test(TCase_dst_am, tc_dst_am);
|
||||
suite_add_tcase(s, TCase_dst_am);
|
||||
tcase_add_test(TCase_802154_src, tc_802154_src);
|
||||
suite_add_tcase(s, TCase_802154_src);
|
||||
tcase_add_test(TCase_802154_dst, tc_802154_dst);
|
||||
suite_add_tcase(s, TCase_802154_dst);
|
||||
tcase_add_test(TCase_802154_format, tc_802154_format);
|
||||
suite_add_tcase(s, TCase_802154_format);
|
||||
tcase_add_test(TCase_802154_process_out, tc_802154_process_out);
|
||||
suite_add_tcase(s, TCase_802154_process_out);
|
||||
tcase_add_test(TCase_802154_process_in, tc_802154_process_in);
|
||||
suite_add_tcase(s, TCase_802154_process_in);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int fails;
|
||||
Suite *s = pico_suite();
|
||||
SRunner *sr = srunner_create(s);
|
||||
srunner_run_all(sr, CK_NORMAL);
|
||||
fails = srunner_ntests_failed(sr);
|
||||
srunner_free(sr);
|
||||
return fails;
|
||||
}
|
||||
545
kernel/picotcp/test/unit/modunit_pico_aodv.c
Normal file
545
kernel/picotcp/test/unit/modunit_pico_aodv.c
Normal file
@@ -0,0 +1,545 @@
|
||||
#include <pico_stack.h>
|
||||
#include <pico_tree.h>
|
||||
#include <pico_socket.h>
|
||||
#include <pico_aodv.h>
|
||||
#include <pico_device.h>
|
||||
#include <pico_ipv4.h>
|
||||
#include "modules/pico_aodv.c"
|
||||
#include "check.h"
|
||||
|
||||
|
||||
Suite *pico_suite(void);
|
||||
|
||||
START_TEST(tc_aodv_node_compare)
|
||||
{
|
||||
struct pico_aodv_node a, b;
|
||||
a.dest.ip4.addr = long_be(1);
|
||||
b.dest.ip4.addr = long_be(2);
|
||||
|
||||
fail_if(aodv_node_compare(&a, &b) >= 0);
|
||||
a.dest.ip4.addr = long_be(3);
|
||||
fail_if(aodv_node_compare(&a, &b) <= 0);
|
||||
b.dest.ip4.addr = long_be(3);
|
||||
fail_if(aodv_node_compare(&a, &b) != 0);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_aodv_dev_cmp)
|
||||
{
|
||||
struct pico_device a, b;
|
||||
a.hash = 1;
|
||||
b.hash = 2;
|
||||
fail_if(aodv_dev_cmp(&a, &b) >= 0);
|
||||
a.hash = 3;
|
||||
fail_if(aodv_dev_cmp(&a, &b) <= 0);
|
||||
b.hash = 3;
|
||||
fail_if(aodv_dev_cmp(&a, &b) != 0);
|
||||
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_get_node_by_addr)
|
||||
{
|
||||
struct pico_aodv_node a;
|
||||
union pico_address test;
|
||||
a.dest.ip4.addr = long_be(10);
|
||||
test.ip4.addr = long_be(10);
|
||||
|
||||
pico_tree_insert(&aodv_nodes, &a);
|
||||
|
||||
fail_if(get_node_by_addr(&test) != &a);
|
||||
pico_tree_delete(&aodv_nodes, &a);
|
||||
fail_if(get_node_by_addr(&test) != NULL);
|
||||
|
||||
}
|
||||
END_TEST
|
||||
|
||||
static int set_bcast_link_called = 0;
|
||||
void pico_ipv4_route_set_bcast_link(struct pico_ipv4_link *link)
|
||||
{
|
||||
IGNORE_PARAMETER(link);
|
||||
set_bcast_link_called++;
|
||||
}
|
||||
|
||||
START_TEST(tc_pico_aodv_set_dev)
|
||||
{
|
||||
struct pico_device *dev = NULL;
|
||||
pico_aodv_set_dev(dev);
|
||||
fail_if(set_bcast_link_called != 1);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_aodv_peer_refresh)
|
||||
{
|
||||
/* TODO: test this: static int aodv_peer_refresh(struct pico_aodv_node *node, uint32_t seq) */
|
||||
struct pico_aodv_node node;
|
||||
memset(&node, 0, sizeof(node));
|
||||
node.dseq = 0xFFFF;
|
||||
fail_if(aodv_peer_refresh(&node, 10) != 0); /* should succeed, because SYNC flag is not yet set... */
|
||||
fail_if((node.flags & PICO_AODV_NODE_SYNC) == 0); /* Flag should be set after last call... */
|
||||
fail_if(aodv_peer_refresh(&node, 5) == 0); /* should FAIL, because seq number is lower... */
|
||||
fail_if(aodv_peer_refresh(&node, 10) == 0); /* should FAIL, because seq number is still the same... */
|
||||
fail_if(aodv_peer_refresh(&node, 15) != 0); /* should succeed, because seq number is now bigger... */
|
||||
fail_if(node.dseq != 15);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
static int called_route_add = 0;
|
||||
static uint32_t route_add_gw = 0u;
|
||||
static int route_add_metric = 0;
|
||||
int pico_ipv4_route_add(struct pico_ip4 address, struct pico_ip4 netmask, struct pico_ip4 gateway, int metric, struct pico_ipv4_link *link)
|
||||
{
|
||||
IGNORE_PARAMETER(link);
|
||||
IGNORE_PARAMETER(netmask);
|
||||
IGNORE_PARAMETER(address);
|
||||
called_route_add++;
|
||||
route_add_gw = gateway.addr;
|
||||
route_add_metric = metric;
|
||||
return 0;
|
||||
}
|
||||
|
||||
START_TEST(tc_aodv_elect_route)
|
||||
{
|
||||
struct pico_aodv_node node;
|
||||
union pico_address gateway;
|
||||
memset(&node, 0, sizeof(node));
|
||||
gateway.ip4.addr = 0x55555555;
|
||||
|
||||
called_route_add = 0;
|
||||
aodv_elect_route(&node, NULL, 150, NULL);
|
||||
fail_if(called_route_add != 1); /* Not active, should succeed */
|
||||
fail_if(route_add_gw != 0u);
|
||||
fail_if(route_add_metric != 1);
|
||||
|
||||
called_route_add = 0;
|
||||
route_add_metric = 0;
|
||||
route_add_gw = 0u;
|
||||
node.flags = PICO_AODV_NODE_ROUTE_DOWN | PICO_AODV_NODE_ROUTE_UP;
|
||||
aodv_elect_route(&node, &gateway, 150, NULL);
|
||||
fail_if(called_route_add != 0); /* Already active, existing metric is lower */
|
||||
|
||||
called_route_add = 0;
|
||||
route_add_metric = 0;
|
||||
route_add_gw = 0u;
|
||||
node.metric = 22;
|
||||
aodv_elect_route(&node, &gateway, 15, NULL);
|
||||
fail_if(called_route_add != 1); /* Already active, existing metric is higher */
|
||||
fail_if(route_add_metric != 16);
|
||||
fail_if(route_add_gw != 0x55555555);
|
||||
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_aodv_peer_new)
|
||||
{
|
||||
union pico_address addr;
|
||||
struct pico_aodv_node *new;
|
||||
addr.ip4.addr = 0x44444444;
|
||||
new = aodv_peer_new(&addr);
|
||||
fail_if(!new);
|
||||
fail_if(!get_node_by_addr(&addr));
|
||||
pico_set_mm_failure(1);
|
||||
new = aodv_peer_new(&addr);
|
||||
fail_if(new);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_aodv_peer_eval)
|
||||
{
|
||||
union pico_address addr;
|
||||
struct pico_aodv_node *node = NULL;
|
||||
/* Case 0: Creation */
|
||||
addr.ip4.addr = 0x11224433;
|
||||
node = aodv_peer_eval(&addr, 0, 0);
|
||||
fail_if(!node);
|
||||
fail_if((node->flags & PICO_AODV_NODE_SYNC) != 0); /* Not synced! */
|
||||
|
||||
/* Case 1: retrieve, unsynced */
|
||||
node->metric = 42;
|
||||
node = aodv_peer_eval(&addr, 0, 0); /* Should get existing node! */
|
||||
fail_if(!node);
|
||||
fail_if(node->metric != 42);
|
||||
fail_if((node->flags & PICO_AODV_NODE_SYNC) != 0); /* Not synced! */
|
||||
|
||||
|
||||
/* Case 2: new node, invalid allocation */
|
||||
addr.ip4.addr = 0x11224455;
|
||||
pico_set_mm_failure(1);
|
||||
node = aodv_peer_eval(&addr, long_be(10), 1);
|
||||
fail_if(node);
|
||||
|
||||
/* Case 3: existing node, setting the new sequence */
|
||||
addr.ip4.addr = 0x11224433;
|
||||
node = aodv_peer_eval(&addr, long_be(10), 1); /* Should get existing node! */
|
||||
fail_if(node->metric != 42);
|
||||
fail_if((node->flags & PICO_AODV_NODE_SYNC) == 0);
|
||||
fail_if(node->dseq != 10);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_aodv_lifetime)
|
||||
{
|
||||
struct pico_aodv_node node;
|
||||
pico_time now = PICO_TIME_MS();
|
||||
memset(&node, 0, sizeof(node));
|
||||
fail_if(aodv_lifetime(&node) == 0);
|
||||
fail_if(node.last_seen < now);
|
||||
node.last_seen = now - AODV_ACTIVE_ROUTE_TIMEOUT;
|
||||
fail_if(aodv_lifetime(&node) != 0);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
static uint8_t sent_pkt_type = 0xFF;
|
||||
static uint32_t dest_addr = 0;
|
||||
static int pico_socket_sendto_called = 0;
|
||||
static int pico_socket_sendto_extended_called = 0;
|
||||
uint32_t expected_dseq = 0;
|
||||
int pico_socket_sendto(struct pico_socket *s, const void *buf, const int len, void *dst, uint16_t remote_port)
|
||||
{
|
||||
uint8_t *pkt = (uint8_t *)(uintptr_t)buf;
|
||||
printf("Sendto called!\n");
|
||||
pico_socket_sendto_called++;
|
||||
fail_if(remote_port != short_be(PICO_AODV_PORT));
|
||||
fail_if (s != aodv_socket);
|
||||
fail_if(pkt[0] > 4);
|
||||
fail_if(pkt[0] < 1);
|
||||
sent_pkt_type = pkt[0];
|
||||
dest_addr = ((union pico_address *)dst)->ip4.addr;
|
||||
if (sent_pkt_type == AODV_TYPE_RREQ) {
|
||||
/* struct pico_aodv_rreq *req = (struct pico_aodv_rreq *)(uintptr_t)buf; */
|
||||
fail_if(len != sizeof(struct pico_aodv_rreq));
|
||||
}
|
||||
else if (sent_pkt_type == AODV_TYPE_RREP) {
|
||||
struct pico_aodv_rrep *rep = (struct pico_aodv_rrep *)(uintptr_t)buf;
|
||||
fail_if(len != sizeof(struct pico_aodv_rrep));
|
||||
fail_if(rep->dest != 0x11111111);
|
||||
fail_if(rep->orig != 0x22222222);
|
||||
printf("rep->dseq= %08x, exp: %08x\n", rep->dseq, expected_dseq);
|
||||
fail_if(rep->dseq != expected_dseq);
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
int pico_socket_sendto_extended(struct pico_socket *s, const void *buf, const int len,
|
||||
void *dst, uint16_t remote_port, struct pico_msginfo *msginfo)
|
||||
{
|
||||
IGNORE_PARAMETER(msginfo);
|
||||
pico_socket_sendto_extended_called++;
|
||||
return pico_socket_sendto(s, buf, len, dst, remote_port);
|
||||
}
|
||||
|
||||
START_TEST(tc_aodv_send_reply)
|
||||
{
|
||||
struct pico_aodv_node node;
|
||||
struct pico_aodv_rreq req;
|
||||
struct pico_msginfo info;
|
||||
union pico_address addr;
|
||||
addr.ip4.addr = 0x22222222;
|
||||
memset(&node, 0, sizeof(node));
|
||||
memset(&req, 0, sizeof(req));
|
||||
memset(&info, 0, sizeof(info));
|
||||
|
||||
req.dest = 0x11111111;
|
||||
req.orig = addr.ip4.addr;
|
||||
req.dseq = 99;
|
||||
|
||||
aodv_send_reply(&node, &req, 1, &info);
|
||||
fail_if(pico_socket_sendto_called != 0); /* Call should have no effect, due to non-existing origin node */
|
||||
|
||||
/* Creating origin... */
|
||||
fail_if(aodv_peer_new(&addr) == NULL);
|
||||
aodv_send_reply(&node, &req, 0, &info);
|
||||
fail_if(pico_socket_sendto_called != 0); /* Call should have no effect, node non-local, non sync'd */
|
||||
|
||||
expected_dseq = long_be(pico_aodv_local_id + 1);
|
||||
aodv_send_reply(&node, &req, 1, &info);
|
||||
fail_if(pico_socket_sendto_called != 1); /* Call should succeed */
|
||||
pico_socket_sendto_called = 0;
|
||||
|
||||
node.flags = PICO_AODV_NODE_SYNC;
|
||||
node.dseq = 42;
|
||||
expected_dseq = long_be(42);
|
||||
aodv_send_reply(&node, &req, 0, &info);
|
||||
fail_if(pico_socket_sendto_called != 1); /* Call should succeed */
|
||||
pico_socket_sendto_called = 0;
|
||||
}
|
||||
END_TEST
|
||||
|
||||
static struct pico_ipv4_link global_link;
|
||||
struct pico_ipv4_link *pico_ipv4_link_by_dev(struct pico_device *dev)
|
||||
{
|
||||
IGNORE_PARAMETER(dev);
|
||||
if (!global_link.address.addr)
|
||||
return NULL;
|
||||
|
||||
printf("Setting link!\n");
|
||||
return &global_link;
|
||||
}
|
||||
|
||||
static struct pico_device global_dev;
|
||||
static int link_find_success = 0;
|
||||
struct pico_device *pico_ipv4_link_find(struct pico_ip4 *ip4)
|
||||
{
|
||||
IGNORE_PARAMETER(ip4);
|
||||
if (link_find_success)
|
||||
return &global_dev;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int timer_set = 0;
|
||||
uint32_t pico_timer_add(pico_time expire, void (*timer)(pico_time, void *), void *arg)
|
||||
{
|
||||
IGNORE_PARAMETER(arg);
|
||||
IGNORE_PARAMETER(timer);
|
||||
IGNORE_PARAMETER(expire);
|
||||
printf("Timer set!\n");
|
||||
timer_set++;
|
||||
return (uint32_t ) 0x99999999;
|
||||
|
||||
}
|
||||
|
||||
START_TEST(tc_aodv_send_req)
|
||||
{
|
||||
struct pico_aodv_node node;
|
||||
struct pico_device d;
|
||||
aodv_socket = NULL;
|
||||
|
||||
memset(&node, 0, sizeof(node));
|
||||
node.flags = PICO_AODV_NODE_ROUTE_DOWN | PICO_AODV_NODE_ROUTE_UP;
|
||||
fail_if(aodv_send_req(&node) != 0); /* Should fail: node already active */
|
||||
fail_if(pico_socket_sendto_called != 0);
|
||||
fail_if(pico_socket_sendto_extended_called != 0);
|
||||
|
||||
node.flags = 0;
|
||||
fail_if(aodv_send_req(&node) != 0); /* Should fail: no devices in tree */
|
||||
fail_if(pico_socket_sendto_called != 0);
|
||||
fail_if(pico_socket_sendto_extended_called != 0);
|
||||
|
||||
pico_tree_insert(&aodv_devices, &d);
|
||||
fail_if(aodv_send_req(&node) != -1); /* Should fail: aodv_socket == NULL */
|
||||
fail_if(pico_err != PICO_ERR_EINVAL);
|
||||
fail_if(pico_socket_sendto_called != 0);
|
||||
fail_if(pico_socket_sendto_extended_called != 0);
|
||||
|
||||
|
||||
/* No valid link, timer is set, call does not send packets */
|
||||
aodv_socket = (struct pico_socket*) 1;
|
||||
global_link.address.addr = 0;
|
||||
fail_if(aodv_send_req(&node) != 0);
|
||||
fail_if(pico_socket_sendto_called != 0);
|
||||
fail_if(pico_socket_sendto_extended_called != 0);
|
||||
fail_if(timer_set != 1);
|
||||
timer_set = 0;
|
||||
|
||||
|
||||
/* One valid link, timer is set, one packet is sent */
|
||||
global_link.address.addr = 0xFEFEFEFE;
|
||||
fail_if(aodv_send_req(&node) != 1);
|
||||
fail_if(pico_socket_sendto_called != 1);
|
||||
fail_if(pico_socket_sendto_extended_called != 1);
|
||||
fail_if(timer_set != 1);
|
||||
pico_socket_sendto_called = 0;
|
||||
pico_socket_sendto_extended_called = 0;
|
||||
timer_set = 0;
|
||||
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_aodv_reverse_path_discover)
|
||||
{
|
||||
struct pico_aodv_node node;
|
||||
memset(&node, 0, sizeof(node));
|
||||
aodv_reverse_path_discover(0, &node);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_aodv_recv_valid_rreq)
|
||||
{
|
||||
struct pico_aodv_node node;
|
||||
struct pico_aodv_rreq req;
|
||||
struct pico_msginfo info;
|
||||
union pico_address addr;
|
||||
memset(&node, 0, sizeof(node));
|
||||
memset(&req, 0, sizeof(req));
|
||||
memset(&info, 0, sizeof(info));
|
||||
|
||||
addr.ip4.addr = 0x22222222;
|
||||
|
||||
link_find_success = 0;
|
||||
aodv_recv_valid_rreq(&node, &req, &info);
|
||||
fail_if(pico_socket_sendto_called > 0);
|
||||
|
||||
/* link not local, but active node, set to send reply, no timer */
|
||||
link_find_success = 0;
|
||||
fail_if(aodv_peer_new(&addr) == NULL);
|
||||
global_link.address.addr = 0x44444444;
|
||||
req.orig = addr.ip4.addr;
|
||||
req.dest = 0x11111111;
|
||||
node.flags = PICO_AODV_NODE_SYNC | PICO_AODV_NODE_ROUTE_UP | PICO_AODV_NODE_ROUTE_DOWN;
|
||||
node.dseq = 42;
|
||||
expected_dseq = long_be(42);
|
||||
aodv_recv_valid_rreq(&node, &req, &info);
|
||||
fail_if(pico_socket_sendto_called < 1);
|
||||
fail_if(timer_set > 0);
|
||||
pico_socket_sendto_called = 0;
|
||||
|
||||
/* link local, active node. Full send + set timer. */
|
||||
link_find_success = 1;
|
||||
expected_dseq = long_be(pico_aodv_local_id + 1);
|
||||
aodv_peer_new(&addr);
|
||||
aodv_recv_valid_rreq(&node, &req, &info);
|
||||
fail_if(pico_socket_sendto_called < 1);
|
||||
fail_if(timer_set < 1);
|
||||
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_aodv_parse_rreq)
|
||||
{
|
||||
/* TODO: test this: static void aodv_parse_rreq(union pico_address *from, uint8_t *buf, int len, struct pico_msginfo *msginfo) */
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_aodv_parse_rrep)
|
||||
{
|
||||
/* TODO: test this: static void aodv_parse_rrep(union pico_address *from, uint8_t *buf, int len, struct pico_msginfo *msginfo) */
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_aodv_parse_rerr)
|
||||
{
|
||||
/* TODO: test this: static void aodv_parse_rerr(union pico_address *from, uint8_t *buf, int len, struct pico_msginfo *msginfo) */
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_aodv_parse_rack)
|
||||
{
|
||||
aodv_parse_rack(NULL, NULL, 0, NULL);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_pico_aodv_parse)
|
||||
{
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_pico_aodv_socket_callback)
|
||||
{
|
||||
/* TODO: test this: static void pico_aodv_socket_callback(uint16_t ev, struct pico_socket *s) */
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_aodv_make_rreq)
|
||||
{
|
||||
/* TODO: test this: static void aodv_make_rreq(struct pico_aodv_node *node, struct pico_aodv_rreq *req) */
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_aodv_retrans_rreq)
|
||||
{
|
||||
/* TODO: test this: static void aodv_retrans_rreq(pico_time now, void *arg) */
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_pico_aodv_expired)
|
||||
{
|
||||
/* TODO: test this: static void pico_aodv_expired(struct pico_aodv_node *node) */
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_pico_aodv_collector)
|
||||
{
|
||||
/* TODO: test this: static void pico_aodv_collector(pico_time now, void *arg) */
|
||||
}
|
||||
END_TEST
|
||||
|
||||
|
||||
Suite *pico_suite(void)
|
||||
{
|
||||
Suite *s = suite_create("PicoTCP");
|
||||
|
||||
TCase *TCase_aodv_node_compare = tcase_create("Unit test for aodv_node_compare");
|
||||
TCase *TCase_aodv_dev_cmp = tcase_create("Unit test for aodv_dev_cmp");
|
||||
TCase *TCase_get_node_by_addr = tcase_create("Unit test for get_node_by_addr");
|
||||
TCase *TCase_pico_aodv_set_dev = tcase_create("Unit test for pico_aodv_set_dev");
|
||||
TCase *TCase_aodv_peer_refresh = tcase_create("Unit test for aodv_peer_refresh");
|
||||
TCase *TCase_aodv_elect_route = tcase_create("Unit test for aodv_elect_route");
|
||||
TCase *TCase_aodv_peer_new = tcase_create("Unit test for aodv_peer_new");
|
||||
TCase *TCase_aodv_peer_eval = tcase_create("Unit test for aodv_peer_eval");
|
||||
TCase *TCase_aodv_lifetime = tcase_create("Unit test for aodv_lifetime");
|
||||
TCase *TCase_aodv_send_reply = tcase_create("Unit test for aodv_send_reply");
|
||||
TCase *TCase_aodv_send_req = tcase_create("Unit test for aodv_send_req");
|
||||
TCase *TCase_aodv_reverse_path_discover = tcase_create("Unit test for aodv_reverse_path_discover");
|
||||
TCase *TCase_aodv_recv_valid_rreq = tcase_create("Unit test for aodv_recv_valid_rreq");
|
||||
TCase *TCase_aodv_parse_rreq = tcase_create("Unit test for aodv_parse_rreq");
|
||||
TCase *TCase_aodv_parse_rrep = tcase_create("Unit test for aodv_parse_rrep");
|
||||
TCase *TCase_aodv_parse_rerr = tcase_create("Unit test for aodv_parse_rerr");
|
||||
TCase *TCase_aodv_parse_rack = tcase_create("Unit test for aodv_parse_rack");
|
||||
TCase *TCase_pico_aodv_parse = tcase_create("Unit test for pico_aodv_parse");
|
||||
TCase *TCase_pico_aodv_socket_callback = tcase_create("Unit test for pico_aodv_socket_callback");
|
||||
TCase *TCase_aodv_make_rreq = tcase_create("Unit test for aodv_make_rreq");
|
||||
TCase *TCase_aodv_retrans_rreq = tcase_create("Unit test for aodv_retrans_rreq");
|
||||
TCase *TCase_pico_aodv_expired = tcase_create("Unit test for pico_aodv_expired");
|
||||
TCase *TCase_pico_aodv_collector = tcase_create("Unit test for pico_aodv_collector");
|
||||
|
||||
|
||||
tcase_add_test(TCase_aodv_node_compare, tc_aodv_node_compare);
|
||||
suite_add_tcase(s, TCase_aodv_node_compare);
|
||||
tcase_add_test(TCase_aodv_dev_cmp, tc_aodv_dev_cmp);
|
||||
suite_add_tcase(s, TCase_aodv_dev_cmp);
|
||||
tcase_add_test(TCase_get_node_by_addr, tc_get_node_by_addr);
|
||||
suite_add_tcase(s, TCase_get_node_by_addr);
|
||||
tcase_add_test(TCase_pico_aodv_set_dev, tc_pico_aodv_set_dev);
|
||||
suite_add_tcase(s, TCase_pico_aodv_set_dev);
|
||||
tcase_add_test(TCase_aodv_peer_refresh, tc_aodv_peer_refresh);
|
||||
suite_add_tcase(s, TCase_aodv_peer_refresh);
|
||||
tcase_add_test(TCase_aodv_elect_route, tc_aodv_elect_route);
|
||||
suite_add_tcase(s, TCase_aodv_elect_route);
|
||||
tcase_add_test(TCase_aodv_peer_new, tc_aodv_peer_new);
|
||||
suite_add_tcase(s, TCase_aodv_peer_new);
|
||||
tcase_add_test(TCase_aodv_peer_eval, tc_aodv_peer_eval);
|
||||
suite_add_tcase(s, TCase_aodv_peer_eval);
|
||||
tcase_add_test(TCase_aodv_lifetime, tc_aodv_lifetime);
|
||||
suite_add_tcase(s, TCase_aodv_lifetime);
|
||||
tcase_add_test(TCase_aodv_send_reply, tc_aodv_send_reply);
|
||||
suite_add_tcase(s, TCase_aodv_send_reply);
|
||||
tcase_add_test(TCase_aodv_send_req, tc_aodv_send_req);
|
||||
suite_add_tcase(s, TCase_aodv_send_req);
|
||||
tcase_add_test(TCase_aodv_reverse_path_discover, tc_aodv_reverse_path_discover);
|
||||
suite_add_tcase(s, TCase_aodv_reverse_path_discover);
|
||||
tcase_add_test(TCase_aodv_recv_valid_rreq, tc_aodv_recv_valid_rreq);
|
||||
suite_add_tcase(s, TCase_aodv_recv_valid_rreq);
|
||||
tcase_add_test(TCase_aodv_parse_rreq, tc_aodv_parse_rreq);
|
||||
suite_add_tcase(s, TCase_aodv_parse_rreq);
|
||||
tcase_add_test(TCase_aodv_parse_rrep, tc_aodv_parse_rrep);
|
||||
suite_add_tcase(s, TCase_aodv_parse_rrep);
|
||||
tcase_add_test(TCase_aodv_parse_rerr, tc_aodv_parse_rerr);
|
||||
suite_add_tcase(s, TCase_aodv_parse_rerr);
|
||||
tcase_add_test(TCase_aodv_parse_rack, tc_aodv_parse_rack);
|
||||
suite_add_tcase(s, TCase_aodv_parse_rack);
|
||||
tcase_add_test(TCase_pico_aodv_parse, tc_pico_aodv_parse);
|
||||
suite_add_tcase(s, TCase_pico_aodv_parse);
|
||||
tcase_add_test(TCase_pico_aodv_socket_callback, tc_pico_aodv_socket_callback);
|
||||
suite_add_tcase(s, TCase_pico_aodv_socket_callback);
|
||||
tcase_add_test(TCase_aodv_make_rreq, tc_aodv_make_rreq);
|
||||
suite_add_tcase(s, TCase_aodv_make_rreq);
|
||||
tcase_add_test(TCase_aodv_retrans_rreq, tc_aodv_retrans_rreq);
|
||||
suite_add_tcase(s, TCase_aodv_retrans_rreq);
|
||||
tcase_add_test(TCase_pico_aodv_expired, tc_pico_aodv_expired);
|
||||
suite_add_tcase(s, TCase_pico_aodv_expired);
|
||||
tcase_add_test(TCase_pico_aodv_collector, tc_pico_aodv_collector);
|
||||
suite_add_tcase(s, TCase_pico_aodv_collector);
|
||||
return s;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int fails;
|
||||
Suite *s = pico_suite();
|
||||
SRunner *sr = srunner_create(s);
|
||||
srunner_run_all(sr, CK_NORMAL);
|
||||
fails = srunner_ntests_failed(sr);
|
||||
srunner_free(sr);
|
||||
return fails;
|
||||
}
|
||||
97
kernel/picotcp/test/unit/modunit_pico_dev_loop.c
Normal file
97
kernel/picotcp/test/unit/modunit_pico_dev_loop.c
Normal file
@@ -0,0 +1,97 @@
|
||||
#include "modules/pico_dev_loop.c"
|
||||
#include "check.h"
|
||||
static int called = 0;
|
||||
static int fail = 0;
|
||||
|
||||
Suite *pico_suite(void);
|
||||
|
||||
int pico_device_init(struct pico_device __attribute__((unused)) *dev, const char __attribute__((unused)) *name, const uint8_t __attribute__((unused)) *mac)
|
||||
{
|
||||
if (fail)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void pico_device_destroy(struct pico_device *dev)
|
||||
{
|
||||
dev = dev;
|
||||
}
|
||||
|
||||
int32_t pico_stack_recv(struct pico_device __attribute__((unused)) *dev, uint8_t __attribute__((unused)) *buffer, uint32_t __attribute__((unused)) len)
|
||||
{
|
||||
called = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
START_TEST(tc_pico_loop_send)
|
||||
{
|
||||
uint8_t buf[LOOP_MTU + 1] = {};
|
||||
fail_if(pico_loop_send(NULL, buf, LOOP_MTU + 1) != 0);
|
||||
|
||||
/* First send: OK */
|
||||
fail_if(pico_loop_send(NULL, buf, LOOP_MTU) != LOOP_MTU);
|
||||
|
||||
/* Second: buffer busy */
|
||||
fail_if(pico_loop_send(NULL, buf, LOOP_MTU) != 0);
|
||||
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_pico_loop_poll)
|
||||
{
|
||||
uint8_t buf[LOOP_MTU + 1] = {};
|
||||
fail_if(pico_loop_poll(NULL, 0) != 0);
|
||||
called = 0;
|
||||
/* First send: OK */
|
||||
fail_if(pico_loop_send(NULL, buf, LOOP_MTU) != LOOP_MTU);
|
||||
fail_if(pico_loop_poll(NULL, 1) != 0);
|
||||
fail_if(called == 0);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_pico_loop_create)
|
||||
{
|
||||
|
||||
#ifdef PICO_FAULTY
|
||||
printf("Testing with faulty memory in pico_loop_create (1)\n");
|
||||
pico_set_mm_failure(1);
|
||||
fail_if(pico_loop_create() != NULL);
|
||||
#endif
|
||||
fail = 1;
|
||||
fail_if(pico_loop_create() != NULL);
|
||||
fail = 0;
|
||||
fail_if(pico_loop_create() == NULL);
|
||||
|
||||
}
|
||||
END_TEST
|
||||
|
||||
|
||||
Suite *pico_suite(void)
|
||||
{
|
||||
Suite *s = suite_create("PicoTCP");
|
||||
|
||||
TCase *TCase_pico_loop_send = tcase_create("Unit test for pico_loop_send");
|
||||
TCase *TCase_pico_loop_poll = tcase_create("Unit test for pico_loop_poll");
|
||||
TCase *TCase_pico_loop_create = tcase_create("Unit test for pico_loop_create");
|
||||
|
||||
|
||||
tcase_add_test(TCase_pico_loop_send, tc_pico_loop_send);
|
||||
suite_add_tcase(s, TCase_pico_loop_send);
|
||||
tcase_add_test(TCase_pico_loop_poll, tc_pico_loop_poll);
|
||||
suite_add_tcase(s, TCase_pico_loop_poll);
|
||||
tcase_add_test(TCase_pico_loop_create, tc_pico_loop_create);
|
||||
suite_add_tcase(s, TCase_pico_loop_create);
|
||||
return s;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int fails;
|
||||
Suite *s = pico_suite();
|
||||
SRunner *sr = srunner_create(s);
|
||||
srunner_run_all(sr, CK_NORMAL);
|
||||
fails = srunner_ntests_failed(sr);
|
||||
srunner_free(sr);
|
||||
return fails;
|
||||
}
|
||||
1387
kernel/picotcp/test/unit/modunit_pico_dev_ppp.c
Normal file
1387
kernel/picotcp/test/unit/modunit_pico_dev_ppp.c
Normal file
File diff suppressed because it is too large
Load Diff
229
kernel/picotcp/test/unit/modunit_pico_dns_client.c
Normal file
229
kernel/picotcp/test/unit/modunit_pico_dns_client.c
Normal file
@@ -0,0 +1,229 @@
|
||||
#include "pico_config.h"
|
||||
#include "pico_stack.h"
|
||||
#include "pico_addressing.h"
|
||||
#include "pico_socket.h"
|
||||
#include "pico_ipv4.h"
|
||||
#include "pico_ipv6.h"
|
||||
#include "pico_dns_client.h"
|
||||
#include "pico_tree.h"
|
||||
#include "pico_udp.h"
|
||||
#include "modules/pico_dns_client.c"
|
||||
#include "check.h"
|
||||
|
||||
Suite *pico_suite(void);
|
||||
|
||||
START_TEST(tc_pico_dns_client_callback)
|
||||
{
|
||||
struct pico_socket *s = pico_udp_open();
|
||||
s->proto = &pico_proto_udp;
|
||||
|
||||
fail_if(!s);
|
||||
|
||||
/* Test with ERR */
|
||||
pico_dns_client_callback(PICO_SOCK_EV_ERR, s);
|
||||
|
||||
/* Test with failing RD */
|
||||
pico_dns_client_callback(PICO_SOCK_EV_RD, s);
|
||||
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_dns_client_retransmission)
|
||||
{
|
||||
/* TODO: test this: static void pico_dns_client_retransmission(pico_time now, void *arg); */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_dns_ns_cmp)
|
||||
{
|
||||
/* TODO: test this: static int dns_ns_cmp(void *ka, void *kb) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_dns_query_cmp)
|
||||
{
|
||||
/* TODO: test this: static int dns_query_cmp(void *ka, void *kb) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_dns_client_del_ns)
|
||||
{
|
||||
/* TODO: test this: static int pico_dns_client_del_ns(struct pico_ip4 *ns_addr) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_dns_ns)
|
||||
{
|
||||
/* TODO: test this: static struct pico_dns_ns *pico_dns_client_add_ns(struct pico_ip4 *ns_addr) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_dns_client_del_query)
|
||||
{
|
||||
/* TODO: test this: static int pico_dns_client_del_query(uint16_t id) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_dns_query)
|
||||
{
|
||||
/* TODO: test this: static struct pico_dns_query *pico_dns_client_find_query(uint16_t id) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_dns_client_strlen)
|
||||
{
|
||||
/* TODO: test this: static uint16_t pico_dns_client_strlen(const char *url) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_dns_client_seek)
|
||||
{
|
||||
/* TODO: test this: static char *pico_dns_client_seek(char *ptr) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_dns_client_mirror)
|
||||
{
|
||||
/* TODO: test this: static int8_t pico_dns_client_mirror(char *ptr) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_dns_client_query_prefix)
|
||||
{
|
||||
/* TODO: test this: static int pico_dns_client_query_prefix(struct pico_dns_prefix *pre) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_dns_client_query_suffix)
|
||||
{
|
||||
/* TODO: test this: static int pico_dns_client_query_suffix(struct pico_dns_query_suffix *suf, uint16_t type, uint16_t class) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_dns_client_query_domain)
|
||||
{
|
||||
/* TODO: test this: static int pico_dns_client_query_domain(char *ptr) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_dns_client_answer_domain)
|
||||
{
|
||||
/* TODO: test this: static int pico_dns_client_answer_domain(char *ptr) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_dns_client_check_prefix)
|
||||
{
|
||||
/* TODO: test this: static int pico_dns_client_check_prefix(struct pico_dns_prefix *pre) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_dns_client_check_qsuffix)
|
||||
{
|
||||
/* TODO: test this: static int pico_dns_client_check_qsuffix(struct pico_dns_query_suffix *suf, struct pico_dns_query *q) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_dns_client_check_asuffix)
|
||||
{
|
||||
/* TODO: test this: static int pico_dns_client_check_asuffix(struct pico_dns_answer_suffix *suf, struct pico_dns_query *q) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_dns_client_seek_suffix)
|
||||
{
|
||||
/* TODO: test this: static char *pico_dns_client_seek_suffix(char *suf, struct pico_dns_prefix *pre, struct pico_dns_query *q) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_dns_client_send)
|
||||
{
|
||||
/* TODO: test this: static int pico_dns_client_send(struct pico_dns_query *q) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_dns_client_user_callback)
|
||||
{
|
||||
/* TODO: test this: static int pico_dns_client_user_callback(struct pico_dns_answer_suffix *asuffix, struct pico_dns_query *q) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_dns_client_getaddr_init)
|
||||
{
|
||||
/* TODO: test this: static int pico_dns_client_getaddr_init(const char *url, uint16_t proto, void (*callback)(char *, void *), void *arg) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_dns_ipv6_set_ptr)
|
||||
{
|
||||
/* TODO: test this: static void pico_dns_ipv6_set_ptr(const char *ip, char *dst) */
|
||||
}
|
||||
END_TEST
|
||||
|
||||
|
||||
Suite *pico_suite(void)
|
||||
{
|
||||
Suite *s = suite_create("PicoTCP");
|
||||
|
||||
TCase *TCase_pico_dns_client_callback = tcase_create("Unit test for pico_dns_client_callback");
|
||||
TCase *TCase_pico_dns_client_retransmission = tcase_create("Unit test for pico_dns_client_retransmission");
|
||||
TCase *TCase_dns_ns_cmp = tcase_create("Unit test for dns_ns_cmp");
|
||||
TCase *TCase_dns_query_cmp = tcase_create("Unit test for dns_query_cmp");
|
||||
TCase *TCase_pico_dns_client_del_ns = tcase_create("Unit test for pico_dns_client_del_ns");
|
||||
TCase *TCase_pico_dns_ns = tcase_create("Unit test for pico_dns_ns");
|
||||
TCase *TCase_pico_dns_client_del_query = tcase_create("Unit test for pico_dns_client_del_query");
|
||||
TCase *TCase_pico_dns_query = tcase_create("Unit test for pico_dns_query");
|
||||
TCase *TCase_pico_dns_client_strlen = tcase_create("Unit test for pico_dns_client_strlen");
|
||||
TCase *TCase_pico_dns_client_seek = tcase_create("Unit test for pico_dns_client_seek");
|
||||
TCase *TCase_pico_dns_client_mirror = tcase_create("Unit test for pico_dns_client_mirror");
|
||||
TCase *TCase_pico_dns_client_query_prefix = tcase_create("Unit test for pico_dns_client_query_prefix");
|
||||
TCase *TCase_pico_dns_client_query_suffix = tcase_create("Unit test for pico_dns_client_query_suffix");
|
||||
TCase *TCase_pico_dns_client_query_domain = tcase_create("Unit test for pico_dns_client_query_domain");
|
||||
TCase *TCase_pico_dns_client_answer_domain = tcase_create("Unit test for pico_dns_client_answer_domain");
|
||||
TCase *TCase_pico_dns_client_check_prefix = tcase_create("Unit test for pico_dns_client_check_prefix");
|
||||
TCase *TCase_pico_dns_client_check_qsuffix = tcase_create("Unit test for pico_dns_client_check_qsuffix");
|
||||
TCase *TCase_pico_dns_client_check_asuffix = tcase_create("Unit test for pico_dns_client_check_asuffix");
|
||||
TCase *TCase_pico_dns_client_seek_suffix = tcase_create("Unit test for pico_dns_client_seek_suffix");
|
||||
TCase *TCase_pico_dns_client_send = tcase_create("Unit test for pico_dns_client_send");
|
||||
TCase *TCase_pico_dns_client_user_callback = tcase_create("Unit test for pico_dns_client_user_callback");
|
||||
TCase *TCase_pico_dns_client_getaddr_init = tcase_create("Unit test for pico_dns_client_getaddr_init");
|
||||
TCase *TCase_pico_dns_ipv6_set_ptr = tcase_create("Unit test for pico_dns_ipv6_set_ptr");
|
||||
|
||||
|
||||
tcase_add_test(TCase_pico_dns_client_callback, tc_pico_dns_client_callback);
|
||||
suite_add_tcase(s, TCase_pico_dns_client_callback);
|
||||
tcase_add_test(TCase_pico_dns_client_retransmission, tc_pico_dns_client_retransmission);
|
||||
suite_add_tcase(s, TCase_pico_dns_client_retransmission);
|
||||
tcase_add_test(TCase_dns_ns_cmp, tc_dns_ns_cmp);
|
||||
suite_add_tcase(s, TCase_dns_ns_cmp);
|
||||
tcase_add_test(TCase_dns_query_cmp, tc_dns_query_cmp);
|
||||
suite_add_tcase(s, TCase_dns_query_cmp);
|
||||
tcase_add_test(TCase_pico_dns_client_del_ns, tc_pico_dns_client_del_ns);
|
||||
suite_add_tcase(s, TCase_pico_dns_client_del_ns);
|
||||
tcase_add_test(TCase_pico_dns_ns, tc_pico_dns_ns);
|
||||
suite_add_tcase(s, TCase_pico_dns_ns);
|
||||
tcase_add_test(TCase_pico_dns_client_del_query, tc_pico_dns_client_del_query);
|
||||
suite_add_tcase(s, TCase_pico_dns_client_del_query);
|
||||
tcase_add_test(TCase_pico_dns_query, tc_pico_dns_query);
|
||||
suite_add_tcase(s, TCase_pico_dns_query);
|
||||
tcase_add_test(TCase_pico_dns_client_strlen, tc_pico_dns_client_strlen);
|
||||
suite_add_tcase(s, TCase_pico_dns_client_strlen);
|
||||
tcase_add_test(TCase_pico_dns_client_seek, tc_pico_dns_client_seek);
|
||||
suite_add_tcase(s, TCase_pico_dns_client_seek);
|
||||
tcase_add_test(TCase_pico_dns_client_mirror, tc_pico_dns_client_mirror);
|
||||
suite_add_tcase(s, TCase_pico_dns_client_mirror);
|
||||
tcase_add_test(TCase_pico_dns_client_query_prefix, tc_pico_dns_client_query_prefix);
|
||||
suite_add_tcase(s, TCase_pico_dns_client_query_prefix);
|
||||
tcase_add_test(TCase_pico_dns_client_query_suffix, tc_pico_dns_client_query_suffix);
|
||||
suite_add_tcase(s, TCase_pico_dns_client_query_suffix);
|
||||
tcase_add_test(TCase_pico_dns_client_query_domain, tc_pico_dns_client_query_domain);
|
||||
suite_add_tcase(s, TCase_pico_dns_client_query_domain);
|
||||
tcase_add_test(TCase_pico_dns_client_answer_domain, tc_pico_dns_client_answer_domain);
|
||||
suite_add_tcase(s, TCase_pico_dns_client_answer_domain);
|
||||
tcase_add_test(TCase_pico_dns_client_check_prefix, tc_pico_dns_client_check_prefix);
|
||||
suite_add_tcase(s, TCase_pico_dns_client_check_prefix);
|
||||
tcase_add_test(TCase_pico_dns_client_check_qsuffix, tc_pico_dns_client_check_qsuffix);
|
||||
suite_add_tcase(s, TCase_pico_dns_client_check_qsuffix);
|
||||
tcase_add_test(TCase_pico_dns_client_check_asuffix, tc_pico_dns_client_check_asuffix);
|
||||
suite_add_tcase(s, TCase_pico_dns_client_check_asuffix);
|
||||
tcase_add_test(TCase_pico_dns_client_seek_suffix, tc_pico_dns_client_seek_suffix);
|
||||
suite_add_tcase(s, TCase_pico_dns_client_seek_suffix);
|
||||
tcase_add_test(TCase_pico_dns_client_send, tc_pico_dns_client_send);
|
||||
suite_add_tcase(s, TCase_pico_dns_client_send);
|
||||
tcase_add_test(TCase_pico_dns_client_user_callback, tc_pico_dns_client_user_callback);
|
||||
suite_add_tcase(s, TCase_pico_dns_client_user_callback);
|
||||
tcase_add_test(TCase_pico_dns_client_getaddr_init, tc_pico_dns_client_getaddr_init);
|
||||
suite_add_tcase(s, TCase_pico_dns_client_getaddr_init);
|
||||
tcase_add_test(TCase_pico_dns_ipv6_set_ptr, tc_pico_dns_ipv6_set_ptr);
|
||||
suite_add_tcase(s, TCase_pico_dns_ipv6_set_ptr);
|
||||
return s;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int fails;
|
||||
Suite *s = pico_suite();
|
||||
SRunner *sr = srunner_create(s);
|
||||
srunner_run_all(sr, CK_NORMAL);
|
||||
fails = srunner_ntests_failed(sr);
|
||||
srunner_free(sr);
|
||||
return fails;
|
||||
}
|
||||
1446
kernel/picotcp/test/unit/modunit_pico_dns_common.c
Normal file
1446
kernel/picotcp/test/unit/modunit_pico_dns_common.c
Normal file
File diff suppressed because it is too large
Load Diff
403
kernel/picotcp/test/unit/modunit_pico_dns_sd.c
Normal file
403
kernel/picotcp/test/unit/modunit_pico_dns_sd.c
Normal file
@@ -0,0 +1,403 @@
|
||||
#include "pico_config.h"
|
||||
#include "pico_stack.h"
|
||||
#include "pico_addressing.h"
|
||||
#include "pico_socket.h"
|
||||
#include "pico_ipv4.h"
|
||||
#include "pico_ipv6.h"
|
||||
#include "pico_dns_common.h"
|
||||
#include "pico_tree.h"
|
||||
#include "pico_dev_mock.c"
|
||||
#include "modules/pico_dns_sd.c"
|
||||
#include "check.h"
|
||||
|
||||
Suite *pico_suite(void);
|
||||
void callback( pico_mdns_rtree *tree, char *str, void *arg);
|
||||
int dns_sd_init(void);
|
||||
char text[] = "textvers";
|
||||
char text2[] = "pass";
|
||||
char text3[] = "color";
|
||||
char value[] = "1";
|
||||
char value3[] = "";
|
||||
void callback( pico_mdns_rtree *tree,
|
||||
char *str,
|
||||
void *arg )
|
||||
{
|
||||
kv_vector vector = {
|
||||
0
|
||||
};
|
||||
|
||||
/* This doesn't even gets called, tests exit before possible callback */
|
||||
IGNORE_PARAMETER(str);
|
||||
IGNORE_PARAMETER(arg);
|
||||
IGNORE_PARAMETER(tree);
|
||||
fail_unless(pico_dns_sd_register_service("Hello World!",
|
||||
"_kerberos._udp",
|
||||
88, &vector, 120,
|
||||
callback, NULL) == 0,
|
||||
"dns_sd_register_service failed!\n");
|
||||
}
|
||||
|
||||
int dns_sd_init()
|
||||
{
|
||||
struct mock_device *mock = NULL;
|
||||
|
||||
struct pico_ip4 local = {
|
||||
.addr = long_be(0x0a280064)
|
||||
};
|
||||
struct pico_ip4 netmask = {
|
||||
.addr = long_be(0xffffff00)
|
||||
};
|
||||
|
||||
mock = pico_mock_create(NULL);
|
||||
if (!mock)
|
||||
return -1;
|
||||
|
||||
pico_ipv4_link_add(mock->dev, local, netmask);
|
||||
|
||||
/* Try to initialise the mDNS module right */
|
||||
return pico_dns_sd_init("host.local", local, callback, NULL);
|
||||
}
|
||||
|
||||
START_TEST(tc_dns_sd_kv_vector_strlen)
|
||||
{
|
||||
kv_vector pairs = {
|
||||
0
|
||||
};
|
||||
|
||||
pico_dns_sd_kv_vector_add(&pairs, text, value);
|
||||
pico_dns_sd_kv_vector_add(&pairs, text2, NULL);
|
||||
pico_dns_sd_kv_vector_add(&pairs, text3, value3);
|
||||
|
||||
fail_unless(pico_dns_sd_kv_vector_strlen(&pairs) == 23,
|
||||
"dns_sd_kv_vector_strlen returned wrong length!\n");
|
||||
|
||||
pico_dns_sd_kv_vector_erase(&pairs);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_dns_sd_srv_record_create)
|
||||
{
|
||||
struct pico_mdns_record *record = NULL;
|
||||
|
||||
uint8_t buf[19] = {
|
||||
0, 0, 0, 0, 0, 80,
|
||||
5, 'h', 'i', 't', 'e', 'x',
|
||||
5, 'l', 'o', 'c', 'a', 'l',
|
||||
0
|
||||
};
|
||||
|
||||
record = pico_dns_sd_srv_record_create("test.local", 0, 0, 80,
|
||||
"hitex.local", 10,
|
||||
PICO_MDNS_RECORD_UNIQUE);
|
||||
|
||||
fail_unless(strcmp(record->record->rname, "\4test\5local") == 0,
|
||||
"Name of SRV record not correct!\n");
|
||||
fail_unless(short_be(record->record->rsuffix->rtype) == 33,
|
||||
"Type of SRV record not correctly set!\n");
|
||||
fail_unless(short_be(record->record->rsuffix->rclass) == 0x8001,
|
||||
"Class of SRV record not correctly set!\n");
|
||||
fail_unless(short_be(record->record->rsuffix->rdlength) == 19,
|
||||
"rdlength of SRV record not correctly set!\n");
|
||||
fail_unless(long_be(record->record->rsuffix->rttl) == 10,
|
||||
"TTL of SRV record not correctly set!\n");
|
||||
fail_unless(memcmp(record->record->rdata, buf, 19) == 0,
|
||||
"Rdata of TXT record not correctly set!\n");
|
||||
pico_mdns_record_delete((void **)&record);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_dns_sd_txt_record_create)
|
||||
{
|
||||
struct pico_mdns_record *record = NULL;
|
||||
kv_vector pairs = {
|
||||
0
|
||||
};
|
||||
|
||||
uint8_t buf[23] = {
|
||||
10, 't', 'e', 'x', 't', 'v', 'e', 'r', 's', '=', '1',
|
||||
4, 'p', 'a', 's', 's',
|
||||
6, 'c', 'o', 'l', 'o', 'r', '='
|
||||
};
|
||||
|
||||
pico_dns_sd_kv_vector_add(&pairs, text, value);
|
||||
pico_dns_sd_kv_vector_add(&pairs, text2, NULL);
|
||||
pico_dns_sd_kv_vector_add(&pairs, text3, value3);
|
||||
|
||||
record = pico_dns_sd_txt_record_create("test.local", pairs, 10,
|
||||
PICO_MDNS_RECORD_UNIQUE);
|
||||
|
||||
fail_unless(strcmp(record->record->rname, "\4test\5local") == 0,
|
||||
"Name of TXT record not correct!\n");
|
||||
fail_unless(short_be(record->record->rsuffix->rtype) == 16,
|
||||
"Type of TXT record not correctly set!\n");
|
||||
fail_unless(short_be(record->record->rsuffix->rclass) == 0x8001,
|
||||
"Class of TXT record not correctly set!\n");
|
||||
fail_unless(short_be(record->record->rsuffix->rdlength) == 23,
|
||||
"rdlength of TXT record not correctly set!\n");
|
||||
fail_unless(long_be(record->record->rsuffix->rttl) == 10,
|
||||
"TTL of TXT record not correctly set!\n");
|
||||
fail_unless(memcmp(record->record->rdata, buf, 23) == 0,
|
||||
"Rdata of TXT record not correctly set!\n");
|
||||
pico_mdns_record_delete((void **)&record);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_dns_sd_kv_create)
|
||||
{
|
||||
key_value_pair_t *pair = NULL;
|
||||
|
||||
pair = pico_dns_sd_kv_create("textvers", "1");
|
||||
fail_unless(strcmp(pair->key, "textvers") == 0,
|
||||
"dns_sd_kv_create failed!\n");
|
||||
fail_unless(strcmp(pair->value, "1") == 0,
|
||||
"dns_sd_kv_create failed!\n");
|
||||
PICO_FREE(pair->key);
|
||||
PICO_FREE(pair->value);
|
||||
PICO_FREE(pair);
|
||||
|
||||
pair = pico_dns_sd_kv_create("textvers", NULL);
|
||||
fail_unless(strcmp(pair->key, "textvers") == 0,
|
||||
"dns_sd_kv_create failed!\n");
|
||||
fail_unless(pair->value == NULL,
|
||||
"dns_sd_kv_create failed!\n");
|
||||
PICO_FREE(pair->key);
|
||||
PICO_FREE(pair);
|
||||
|
||||
pair = pico_dns_sd_kv_create("textvers", "");
|
||||
fail_unless(strcmp(pair->key, "textvers") == 0,
|
||||
"dns_sd_kv_create failed!\n");
|
||||
fail_unless(strcmp(pair->value, "") == 0,
|
||||
"dns_sd_kv_create failed!\n");
|
||||
PICO_FREE(pair->key);
|
||||
PICO_FREE(pair->value);
|
||||
PICO_FREE(pair);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_dns_sd_kv_delete)
|
||||
{
|
||||
key_value_pair_t *pair = NULL;
|
||||
|
||||
pair = pico_dns_sd_kv_create("textvers", "1");
|
||||
fail_unless(strcmp(pair->key, "textvers") == 0,
|
||||
"dns_sd_kv_create failed!\n");
|
||||
fail_unless(strcmp(pair->value, "1") == 0,
|
||||
"dns_sd_kv_create failed!\n");
|
||||
pico_dns_sd_kv_delete(&pair);
|
||||
fail_unless(pair == NULL,
|
||||
"dns_sd_kv_delete failed!\n");
|
||||
|
||||
pair = pico_dns_sd_kv_create("textvers", NULL);
|
||||
fail_unless(strcmp(pair->key, "textvers") == 0,
|
||||
"dns_sd_kv_create failed!\n");
|
||||
fail_unless(pair->value == NULL,
|
||||
"dns_sd_kv_create failed!\n");
|
||||
pico_dns_sd_kv_delete(&pair);
|
||||
fail_unless(pair == NULL,
|
||||
"dns_sd_kv_delete failed!\n");
|
||||
|
||||
pair = pico_dns_sd_kv_create("textvers", "");
|
||||
fail_unless(strcmp(pair->key, "textvers") == 0,
|
||||
"dns_sd_kv_create failed!\n");
|
||||
fail_unless(strcmp(pair->value, "") == 0,
|
||||
"dns_sd_kv_create failed!\n");
|
||||
pico_dns_sd_kv_delete(&pair);
|
||||
fail_unless(pair == NULL,
|
||||
"dns_sd_kv_delete failed!\n");
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_dns_sd_check_type_format)
|
||||
{
|
||||
fail_unless(pico_dns_sd_check_type_format("_http._tcp") == 0,
|
||||
"dns_sd_check_type_format failed with correct format!\n");
|
||||
fail_unless(pico_dns_sd_check_type_format("_printer._sub._http._tcp")
|
||||
== 0,
|
||||
"dns_sd_check_type_format failed with subtype!\n");
|
||||
|
||||
/* Test too long subtype */
|
||||
fail_unless(pico_dns_sd_check_type_format(
|
||||
"1234567891123456789212345678931234567894123456789512345678961234._sub._http._tcp"), "dns_sd_check_type_format failed with too big subtype!\n");
|
||||
|
||||
/* Test too long service type with subtype */
|
||||
fail_unless(pico_dns_sd_check_type_format(
|
||||
"printer._sub.0123456789112345678._tcp"),
|
||||
"dns_sd_check_type_format failed with too big sn w/ sub!\n");
|
||||
|
||||
/* Test too long service type with subtype */
|
||||
fail_unless(pico_dns_sd_check_type_format("0123456789112345678._tcp"),
|
||||
"dns_sd_check_type_format failed with too big sn!\n");
|
||||
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_dns_sd_check_instance_name_format)
|
||||
{
|
||||
/* Test too long name */
|
||||
fail_unless(pico_dns_sd_check_instance_name_format(
|
||||
"1234567891123456789212345678931234567894123456789512345678961234"),
|
||||
"dns_sd_check_instance_name_format failed with too big name!\n");
|
||||
|
||||
fail_unless(pico_dns_sd_check_instance_name_format("Hello World!") == 0,
|
||||
"dns_sd_check_instance_name_format failed!\n");
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_dns_sd_create_service_url)
|
||||
{
|
||||
char *service_url = NULL;
|
||||
|
||||
service_url = pico_dns_sd_create_service_url("Hello World!", "_http._tcp");
|
||||
|
||||
fail_unless(strcmp(service_url, "Hello World!._http._tcp.local") == 0,
|
||||
"dns_sd_create_service_url failed!\n");
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_dns_sd_init)
|
||||
{
|
||||
pico_stack_init();
|
||||
fail_unless(dns_sd_init() == 0,
|
||||
"dns_sd_init failed!\n");
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_dns_sd_register_service)
|
||||
{
|
||||
pico_stack_init();
|
||||
dns_sd_init();
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_dns_sd_browse_service)
|
||||
{
|
||||
/* Not implemented in code */
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_dns_sd_kv_vector_add)
|
||||
{
|
||||
kv_vector pairs = {
|
||||
0
|
||||
};
|
||||
char *key = NULL;
|
||||
|
||||
pico_dns_sd_kv_vector_add(&pairs, text, value);
|
||||
pico_dns_sd_kv_vector_add(&pairs, text2, NULL);
|
||||
pico_dns_sd_kv_vector_add(&pairs, text3, value3);
|
||||
|
||||
key = pico_dns_sd_kv_vector_get(&pairs, 2)->key;
|
||||
fail_unless(strcmp("color", key) == 0,
|
||||
"dns_sd_kv_vector_add failed!\n");
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_dns_sd_kv_vector_get)
|
||||
{
|
||||
kv_vector pairs = {
|
||||
0
|
||||
};
|
||||
char *key = NULL;
|
||||
|
||||
pico_dns_sd_kv_vector_add(&pairs, text, value);
|
||||
pico_dns_sd_kv_vector_add(&pairs, text2, NULL);
|
||||
pico_dns_sd_kv_vector_add(&pairs, text3, value3);
|
||||
|
||||
key = pico_dns_sd_kv_vector_get(&pairs, 2)->key;
|
||||
fail_unless(strcmp("color", key) == 0,
|
||||
"dns_sd_kv_vector_get failed!\n");
|
||||
|
||||
fail_unless(pico_dns_sd_kv_vector_get(&pairs, 3) == NULL,
|
||||
"dns_sd_kv_vector_get failed @ OOB!\n");
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_dns_sd_kv_vector_erase)
|
||||
{
|
||||
kv_vector pairs = {
|
||||
0
|
||||
};
|
||||
|
||||
pico_dns_sd_kv_vector_add(&pairs, text, value);
|
||||
pico_dns_sd_kv_vector_add(&pairs, text2, NULL);
|
||||
pico_dns_sd_kv_vector_add(&pairs, text3, value3);
|
||||
|
||||
pico_dns_sd_kv_vector_erase(&pairs);
|
||||
|
||||
fail_unless(pairs.pairs == NULL,
|
||||
"dns_sd_kv_vector_erase failed!\n");
|
||||
fail_unless(pairs.count == 0,
|
||||
"dns_sd_kv_vector_erase failed!\n");
|
||||
}
|
||||
END_TEST
|
||||
|
||||
Suite *pico_suite(void)
|
||||
{
|
||||
Suite *s = suite_create("PicoTCP");
|
||||
|
||||
/* Key-Value pair vector plain creation function */
|
||||
TCase *TCase_dns_sd_kv_vector_strlen = tcase_create("Unit test for dns_sd_kv_vector_strlen");
|
||||
|
||||
/* DNS utility functions */
|
||||
TCase *TCase_dns_sd_srv_record_create = tcase_create("Unit test for dns_sd_srv_record_create");
|
||||
TCase *TCase_dns_sd_txt_record_create = tcase_create("Unit test for dns_sd_txt_record_create");
|
||||
|
||||
/* Key-Value pair creation */
|
||||
TCase *TCase_dns_sd_kv_create = tcase_create("Unit test for dns_sd_kv_create");
|
||||
TCase *TCase_dns_sd_kv_delete = tcase_create("Unit test for dns_sd_kv_delete");
|
||||
|
||||
/* Utility functions */
|
||||
TCase *TCase_dns_sd_check_type_format = tcase_create("Unit test for dns_sd_check_type_format");
|
||||
TCase *TCase_dns_sd_check_instance_name_format = tcase_create("Unit test for dns_sd_check_instance_name_format");
|
||||
TCase *TCase_dns_sd_create_service_url = tcase_create("Unit test for dns_sd_create_service_url");
|
||||
/* DNS SD API functions */
|
||||
TCase *TCase_dns_sd_init = tcase_create("Unit test for dns_sd_init");
|
||||
TCase *TCase_dns_sd_register_service = tcase_create("Unit test for dns_sd_register_service");
|
||||
TCase *TCase_dns_sd_browse_service = tcase_create("Unit test for dns_sd_browse_service");
|
||||
|
||||
/* Key-Value vector functions */
|
||||
TCase *TCase_dns_sd_kv_vector_add = tcase_create("Unit test for dns_sd_kv_vector_add");
|
||||
TCase *TCase_dns_sd_kv_vector_get = tcase_create("Unit test for dns_sd_kv_vector_get");
|
||||
TCase *TCase_dns_sd_kv_vector_erase = tcase_create("Unit test for dns_sd_kv_vector_erase");
|
||||
|
||||
/* Key-Value pair vector plain creation function */
|
||||
tcase_add_test(TCase_dns_sd_kv_vector_strlen, tc_dns_sd_kv_vector_strlen);
|
||||
suite_add_tcase(s, TCase_dns_sd_kv_vector_strlen);
|
||||
|
||||
/* DNS utility functions */
|
||||
tcase_add_test(TCase_dns_sd_srv_record_create, tc_dns_sd_srv_record_create);
|
||||
suite_add_tcase(s, TCase_dns_sd_srv_record_create);
|
||||
tcase_add_test(TCase_dns_sd_txt_record_create, tc_dns_sd_txt_record_create);
|
||||
suite_add_tcase(s, TCase_dns_sd_txt_record_create);
|
||||
|
||||
/* Key-Value pair creation */
|
||||
tcase_add_test(TCase_dns_sd_kv_create, tc_dns_sd_kv_create);
|
||||
suite_add_tcase(s, TCase_dns_sd_kv_create);
|
||||
tcase_add_test(TCase_dns_sd_kv_delete, tc_dns_sd_kv_delete);
|
||||
suite_add_tcase(s, TCase_dns_sd_kv_delete);
|
||||
|
||||
/* Utility functions */
|
||||
tcase_add_test(TCase_dns_sd_check_type_format, tc_dns_sd_check_type_format);
|
||||
suite_add_tcase(s, TCase_dns_sd_check_type_format);
|
||||
tcase_add_test(TCase_dns_sd_check_instance_name_format, tc_dns_sd_check_instance_name_format);
|
||||
suite_add_tcase(s, TCase_dns_sd_check_instance_name_format);
|
||||
tcase_add_test(TCase_dns_sd_create_service_url, tc_dns_sd_create_service_url);
|
||||
suite_add_tcase(s, TCase_dns_sd_create_service_url);
|
||||
|
||||
/* DNS SD API functions */
|
||||
tcase_add_test(TCase_dns_sd_init, tc_dns_sd_init);
|
||||
suite_add_tcase(s, TCase_dns_sd_init);
|
||||
tcase_add_test(TCase_dns_sd_register_service, tc_dns_sd_register_service);
|
||||
suite_add_tcase(s, TCase_dns_sd_register_service);
|
||||
tcase_add_test(TCase_dns_sd_browse_service, tc_dns_sd_browse_service);
|
||||
suite_add_tcase(s, TCase_dns_sd_browse_service);
|
||||
|
||||
/* Key-Value vector functions */
|
||||
tcase_add_test(TCase_dns_sd_kv_vector_add, tc_dns_sd_kv_vector_add);
|
||||
suite_add_tcase(s, TCase_dns_sd_kv_vector_add);
|
||||
tcase_add_test(TCase_dns_sd_kv_vector_get, tc_dns_sd_kv_vector_get);
|
||||
suite_add_tcase(s, TCase_dns_sd_kv_vector_get);
|
||||
tcase_add_test(TCase_dns_sd_kv_vector_erase, tc_dns_sd_kv_vector_erase);
|
||||
suite_add_tcase(s, TCase_dns_sd_kv_vector_erase);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int fails;
|
||||
Suite *s = pico_suite();
|
||||
SRunner *sr = srunner_create(s);
|
||||
srunner_run_all(sr, CK_NORMAL);
|
||||
fails = srunner_ntests_failed(sr);
|
||||
srunner_free(sr);
|
||||
return fails;
|
||||
}
|
||||
315
kernel/picotcp/test/unit/modunit_pico_ethernet.c
Normal file
315
kernel/picotcp/test/unit/modunit_pico_ethernet.c
Normal file
@@ -0,0 +1,315 @@
|
||||
//#include "pico_config.h"
|
||||
#include "pico_stack.h"
|
||||
#include "pico_ipv4.h"
|
||||
#include "pico_ipv6.h"
|
||||
#include "pico_icmp4.h"
|
||||
#include "pico_icmp6.h"
|
||||
#include "pico_arp.h"
|
||||
#include "pico_ethernet.h"
|
||||
#include "modules/pico_ethernet.c"
|
||||
#include "check.h"
|
||||
|
||||
#define STARTING() \
|
||||
printf("*********************** STARTING %s ***\n", __func__); \
|
||||
fflush(stdout)
|
||||
#define TRYING(s, ...) \
|
||||
printf("Trying %s: " s, __func__, ##__VA_ARGS__); \
|
||||
fflush(stdout)
|
||||
#define CHECKING(i) \
|
||||
printf("Checking the results of test %2d in %s...", (i)++, \
|
||||
__func__); \
|
||||
fflush(stdout)
|
||||
#define SUCCESS() \
|
||||
printf(" SUCCES\n"); \
|
||||
fflush(stdout)
|
||||
#define BREAKING(s, ...) \
|
||||
printf("Breaking %s: " s, __func__, ##__VA_ARGS__); \
|
||||
fflush(stdout)
|
||||
#define ENDING(i) \
|
||||
printf("*********************** ENDING %s *** N TESTS: %d\n", \
|
||||
__func__, ((i)-1)); \
|
||||
fflush(stdout)
|
||||
#define DBG(s, ...) \
|
||||
printf(s, ##__VA_ARGS__); \
|
||||
fflush(stdout)
|
||||
|
||||
Suite *pico_suite(void);
|
||||
|
||||
START_TEST(tc_destination_is_bcast)
|
||||
{
|
||||
/* test this: static int destination_is_bcast(struct pico_frame *f) */
|
||||
struct pico_ip6 addr = {{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9 }};
|
||||
struct pico_frame *f = pico_frame_alloc(sizeof(struct pico_ipv6_hdr));
|
||||
struct pico_ipv6_hdr *h = (struct pico_ipv6_hdr *)f->buffer;
|
||||
struct pico_ipv4_hdr *h4 = NULL;
|
||||
|
||||
/* Test parameters */
|
||||
int ret = 0, count = 0;
|
||||
|
||||
f->net_hdr = (uint8_t*) h;
|
||||
f->buffer[0] = 0x60; /* Ipv6 */
|
||||
|
||||
STARTING();
|
||||
|
||||
TRYING("With wrong protocol -> IPv6\n");
|
||||
memcpy(h->dst.addr, addr.addr, PICO_SIZE_IP6);
|
||||
ret = destination_is_bcast(f);
|
||||
CHECKING(count);
|
||||
fail_unless(0 == ret, "Should've returned 0 since IPv6 frame\n");
|
||||
SUCCESS();
|
||||
pico_frame_discard(f);
|
||||
|
||||
f = pico_frame_alloc(sizeof(struct pico_ipv4_hdr));
|
||||
h4 = (struct pico_ipv4_hdr *)f->buffer;
|
||||
f->net_hdr = (uint8_t *)h4;
|
||||
f->buffer[0] = 0x40; /* IPv4 */
|
||||
TRYING("With right protocol -> IPv4\n");
|
||||
ret = destination_is_bcast(f);
|
||||
CHECKING(count);
|
||||
fail_unless(0 == ret, "Should've returned 0 since not a mcast address\n");
|
||||
SUCCESS();
|
||||
|
||||
BREAKING();
|
||||
ret = destination_is_bcast(NULL);
|
||||
CHECKING(count);
|
||||
fail_unless(0 == ret, "Should've returned 0 since NULL-pointer\n");
|
||||
SUCCESS();
|
||||
|
||||
ENDING(count);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_destination_is_mcast)
|
||||
{
|
||||
struct pico_ip6 addr = {{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9 }};
|
||||
struct pico_ip6 mcast = {{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9 }};
|
||||
struct pico_ip4 addr4 = {0};
|
||||
struct pico_ip4 mcast4 = {0};
|
||||
struct pico_frame *f = pico_frame_alloc(sizeof(struct pico_ipv6_hdr));
|
||||
struct pico_ipv6_hdr *h = (struct pico_ipv6_hdr *)f->buffer;
|
||||
struct pico_ipv4_hdr *h4 = (struct pico_ipv4_hdr *)f->buffer;
|
||||
/* Test parameters */
|
||||
int ret = 0, count = 0;
|
||||
|
||||
f->net_hdr = (uint8_t*) h;
|
||||
f->buffer[0] = 0x60; /* Ipv6 */
|
||||
|
||||
STARTING();
|
||||
|
||||
pico_string_to_ipv4("232.1.1.0", &(mcast4.addr)); /* 0 */
|
||||
pico_string_to_ipv4("10.20.0.1", &(addr4.addr));
|
||||
|
||||
pico_string_to_ipv6("ff00:0:0:0:0:0:e801:100", (mcast.addr)); /* 0 */
|
||||
pico_string_to_ipv6("fe80:0:0:0:0:0:a28:100", (addr.addr)); /* 0 */
|
||||
|
||||
TRYING("With IPv6 unicast addr\n");
|
||||
memcpy(h->dst.addr, addr.addr, PICO_SIZE_IP6);
|
||||
ret = destination_is_mcast(f);
|
||||
CHECKING(count);
|
||||
fail_unless(0 == ret, "Should've returned 0 since not an IPv6 multicast\n");
|
||||
SUCCESS();
|
||||
|
||||
TRYING("With IPv6 multicast addr\n");
|
||||
memcpy(h->dst.addr, mcast.addr, PICO_SIZE_IP6);
|
||||
ret = destination_is_mcast(f);
|
||||
CHECKING(count);
|
||||
fail_unless(1 == ret, "Should've returned 1 since an IPv6 multicast\n");
|
||||
SUCCESS();
|
||||
|
||||
pico_frame_discard(f);
|
||||
f = pico_frame_alloc(sizeof(struct pico_ipv4_hdr));
|
||||
h4 = (struct pico_ipv4_hdr *)f->buffer;
|
||||
f->net_hdr = (uint8_t *)h4;
|
||||
f->buffer[0] = 0x40; /* IPv4 */
|
||||
|
||||
TRYING("With IPv4 unicast addr\n");
|
||||
h4->dst = addr4;
|
||||
ret = destination_is_bcast(f);
|
||||
CHECKING(count);
|
||||
fail_unless(0 == ret, "Should've returned 0 since not an IPv4 mcast address\n");
|
||||
SUCCESS();
|
||||
|
||||
TRYING("With IPv4 multicast addr\n");
|
||||
h4->dst = mcast4;
|
||||
ret = destination_is_mcast(f);
|
||||
CHECKING(count);
|
||||
fail_unless(1 == ret, "Should've returned 1 since an IPv4 multicast\n");
|
||||
SUCCESS();
|
||||
|
||||
BREAKING();
|
||||
ret = destination_is_bcast(NULL);
|
||||
CHECKING(count);
|
||||
fail_unless(0 == ret, "Should've returned 0 since NULL-pointer\n");
|
||||
SUCCESS();
|
||||
|
||||
ENDING(count);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_ipv4_ethernet_receive)
|
||||
{
|
||||
/* test this: static int32_t pico_ipv4_ethernet_receive(struct pico_frame *f) */
|
||||
struct pico_frame *f = NULL;
|
||||
struct pico_ipv4_hdr *h4 = NULL;
|
||||
int ret = 0, count = 0;
|
||||
|
||||
STARTING();
|
||||
|
||||
f = pico_frame_alloc(sizeof(struct pico_ipv4_hdr));
|
||||
h4 = (struct pico_ipv4_hdr *)f->buffer;
|
||||
f->net_hdr = (uint8_t *)h4;
|
||||
f->buffer[0] = 0x40; /* IPv4 */
|
||||
|
||||
TRYING("With IPv4 frame\n");
|
||||
ret = pico_ipv4_ethernet_receive(f);
|
||||
CHECKING(count);
|
||||
fail_unless(ret > 0, "Was correct frame should've returned size of frame\n");
|
||||
SUCCESS();
|
||||
CHECKING(count);
|
||||
fail_unless(pico_proto_ipv4.q_in->size == f->buffer_len, "Frame not enqueued\n");
|
||||
SUCCESS();
|
||||
|
||||
ENDING(count);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_ipv6_ethernet_receive)
|
||||
{
|
||||
/* test this: static int32_t pico_ipv6_ethernet_receive(struct pico_frame *f) */
|
||||
struct pico_frame *f = NULL;
|
||||
struct pico_ipv6_hdr *h = NULL;
|
||||
|
||||
int ret = 0, count = 0;
|
||||
|
||||
STARTING();
|
||||
f = pico_frame_alloc(sizeof(struct pico_ipv6_hdr));
|
||||
h = (struct pico_ipv6_hdr *)f->buffer;
|
||||
f->net_hdr = (uint8_t*) h;
|
||||
f->buffer[0] = 0x40; /* Ipv6 */
|
||||
|
||||
TRYING("With wrong network type\n");
|
||||
ret = pico_ipv6_ethernet_receive(f);
|
||||
CHECKING(count);
|
||||
fail_unless(ret == -1, "Wrong type should've returned an error\n");
|
||||
SUCCESS();
|
||||
|
||||
f = pico_frame_alloc(sizeof(struct pico_ipv6_hdr));
|
||||
h = (struct pico_ipv6_hdr *)f->buffer;
|
||||
f->net_hdr = (uint8_t*) h;
|
||||
f->buffer[0] = 0x60;
|
||||
TRYING("With correct network type\n");
|
||||
ret = pico_ipv6_ethernet_receive(f);
|
||||
CHECKING(count);
|
||||
fail_unless(ret == (int32_t)f->buffer_len, "Was correct frame, should've returned success\n");
|
||||
SUCCESS();
|
||||
CHECKING(count);
|
||||
fail_unless(pico_proto_ipv6.q_in->size == f->buffer_len, "Frame not enqueued\n");
|
||||
SUCCESS();
|
||||
|
||||
ENDING(count);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_eth_receive)
|
||||
{
|
||||
struct pico_frame *f = NULL;
|
||||
struct pico_eth_hdr *eth = NULL;
|
||||
int ret = 0, count = 0;
|
||||
|
||||
STARTING();
|
||||
|
||||
f = pico_frame_alloc(sizeof(struct pico_ipv6_hdr) + sizeof(struct pico_eth_hdr));
|
||||
f->datalink_hdr = f->buffer;
|
||||
f->net_hdr = f->datalink_hdr + sizeof(struct pico_eth_hdr);
|
||||
eth = (struct pico_eth_hdr *)f->datalink_hdr;
|
||||
((uint8_t *)(f->net_hdr))[0] = 0x40; /* Ipv4 */
|
||||
|
||||
/* ETHERNET PROTOCOL : IPV6 */
|
||||
eth->proto = PICO_IDETH_IPV6;
|
||||
|
||||
TRYING("With wrong network type\n");
|
||||
ret = pico_eth_receive(f);
|
||||
CHECKING(count);
|
||||
fail_unless(ret == -1, "Wrong type should've returned an error\n");
|
||||
SUCCESS();
|
||||
|
||||
f = pico_frame_alloc(sizeof(struct pico_ipv6_hdr) + sizeof(struct pico_eth_hdr));
|
||||
f->datalink_hdr = f->buffer;
|
||||
f->net_hdr = f->datalink_hdr + sizeof(struct pico_eth_hdr);
|
||||
eth = (struct pico_eth_hdr *)f->datalink_hdr;
|
||||
((uint8_t *)(f->net_hdr))[0] = 0x60; /* Ipv6 */
|
||||
|
||||
/* ETHERNET PROTOCOL : IPV6 */
|
||||
eth->proto = PICO_IDETH_IPV6;
|
||||
TRYING("With correct network type\n");
|
||||
ret = pico_eth_receive(f);
|
||||
CHECKING(count);
|
||||
fail_unless(ret == (int32_t)f->buffer_len, "Was correct frame, should've returned success\n");
|
||||
SUCCESS();
|
||||
CHECKING(count);
|
||||
fail_unless(pico_proto_ipv6.q_in->size == f->buffer_len, "Frame not enqueued\n");
|
||||
SUCCESS();
|
||||
|
||||
pico_frame_discard(f);
|
||||
|
||||
f = pico_frame_alloc(sizeof(struct pico_ipv4_hdr) + sizeof(struct pico_eth_hdr));
|
||||
f->datalink_hdr = f->buffer;
|
||||
f->net_hdr = f->datalink_hdr + sizeof(struct pico_eth_hdr);
|
||||
eth = (struct pico_eth_hdr *)f->datalink_hdr;
|
||||
((uint8_t *)(f->net_hdr))[0] = 0x40; /* Ipv4 */
|
||||
|
||||
TRYING("With wrong frame type\n");
|
||||
ret = pico_eth_receive(f);
|
||||
CHECKING(count);
|
||||
fail_unless(ret == -1, "should've returned -1 wrong ethernet protocol\n");
|
||||
SUCCESS();
|
||||
|
||||
f = pico_frame_alloc(sizeof(struct pico_ipv4_hdr) + sizeof(struct pico_eth_hdr));
|
||||
f->datalink_hdr = f->buffer;
|
||||
f->net_hdr = f->datalink_hdr + sizeof(struct pico_eth_hdr);
|
||||
eth = (struct pico_eth_hdr *)f->datalink_hdr;
|
||||
((uint8_t *)(f->net_hdr))[0] = 0x40; /* Ipv4 */
|
||||
eth->proto = PICO_IDETH_IPV4;
|
||||
|
||||
TRYING("With IPv4 frame\n");
|
||||
ret = pico_eth_receive(f);
|
||||
CHECKING(count);
|
||||
fail_unless(ret > 0, "Was correct frame should've returned size of frame\n");
|
||||
SUCCESS();
|
||||
CHECKING(count);
|
||||
fail_unless(pico_proto_ipv4.q_in->size == f->buffer_len, "Frame not enqueued\n");
|
||||
SUCCESS();
|
||||
|
||||
ENDING(count);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
Suite *pico_suite(void)
|
||||
{
|
||||
Suite *s = suite_create("PicoTCP");
|
||||
|
||||
TCase *TCase_destination_is_bcast = tcase_create("Unit test for destination_is_bcast");
|
||||
TCase *TCase_destination_is_mcast = tcase_create("Unit test for destination_is_mcast");
|
||||
TCase *TCase_pico_ipv4_ethernet_receive = tcase_create("Unit test for pico_ipv4_ethernet_receive");
|
||||
TCase *TCase_pico_ipv6_ethernet_receive = tcase_create("Unit test for pico_ipv6_ethernet_receive");
|
||||
TCase *TCase_pico_eth_receive = tcase_create("Unit test for pico_eth_receive");
|
||||
|
||||
tcase_add_test(TCase_destination_is_bcast, tc_destination_is_bcast);
|
||||
suite_add_tcase(s, TCase_destination_is_bcast);
|
||||
tcase_add_test(TCase_destination_is_mcast, tc_destination_is_mcast);
|
||||
suite_add_tcase(s, TCase_destination_is_mcast);
|
||||
tcase_add_test(TCase_pico_ipv4_ethernet_receive, tc_pico_ipv4_ethernet_receive);
|
||||
suite_add_tcase(s, TCase_pico_ipv4_ethernet_receive);
|
||||
tcase_add_test(TCase_pico_ipv6_ethernet_receive, tc_pico_ipv6_ethernet_receive);
|
||||
suite_add_tcase(s, TCase_pico_ipv6_ethernet_receive);
|
||||
tcase_add_test(TCase_pico_eth_receive, tc_pico_eth_receive);
|
||||
suite_add_tcase(s, TCase_pico_eth_receive);
|
||||
return s;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int fails;
|
||||
Suite *s = pico_suite();
|
||||
SRunner *sr = srunner_create(s);
|
||||
srunner_run_all(sr, CK_NORMAL);
|
||||
fails = srunner_ntests_failed(sr);
|
||||
srunner_free(sr);
|
||||
return fails;
|
||||
}
|
||||
1234
kernel/picotcp/test/unit/modunit_pico_fragments.c
Normal file
1234
kernel/picotcp/test/unit/modunit_pico_fragments.c
Normal file
File diff suppressed because it is too large
Load Diff
274
kernel/picotcp/test/unit/modunit_pico_frame.c
Normal file
274
kernel/picotcp/test/unit/modunit_pico_frame.c
Normal file
@@ -0,0 +1,274 @@
|
||||
#include "pico_config.h"
|
||||
#include "pico_protocol.h"
|
||||
#include "pico_frame.h"
|
||||
#include "stack/pico_frame.c"
|
||||
#include "check.h"
|
||||
|
||||
volatile pico_err_t pico_err;
|
||||
|
||||
#define FRAME_SIZE 1000
|
||||
|
||||
Suite *pico_suite(void);
|
||||
|
||||
START_TEST(tc_pico_frame_alloc_discard)
|
||||
{
|
||||
struct pico_frame *f = pico_frame_alloc(FRAME_SIZE);
|
||||
|
||||
/* Test consistency */
|
||||
fail_if(!f);
|
||||
fail_if(!f->buffer);
|
||||
fail_if(!f->usage_count);
|
||||
fail_if(*f->usage_count != 1);
|
||||
fail_if(f->start != f->buffer);
|
||||
fail_if(f->len != f->buffer_len);
|
||||
fail_if(f->len != FRAME_SIZE);
|
||||
pico_frame_discard(f);
|
||||
|
||||
/* Test empty discard */
|
||||
pico_frame_discard(NULL);
|
||||
|
||||
#ifdef PICO_FAULTY
|
||||
printf("Testing with faulty memory in frame_alloc (1)\n");
|
||||
pico_set_mm_failure(1);
|
||||
f = pico_frame_alloc(FRAME_SIZE);
|
||||
fail_if(f);
|
||||
|
||||
printf("Testing with faulty memory in frame_alloc (2)\n");
|
||||
pico_set_mm_failure(2);
|
||||
f = pico_frame_alloc(FRAME_SIZE);
|
||||
fail_if(f);
|
||||
|
||||
printf("Testing with faulty memory in frame_do_alloc, with external buffer, failing to allocate usage_count \n");
|
||||
pico_set_mm_failure(2);
|
||||
f = pico_frame_do_alloc(FRAME_SIZE, 1, 1);
|
||||
fail_if(f);
|
||||
#endif
|
||||
printf("Testing frame_do_alloc, with invalid flags combination\n");
|
||||
f = pico_frame_do_alloc(FRAME_SIZE, 0, 1);
|
||||
fail_if(f);
|
||||
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_pico_frame_grow_head)
|
||||
{
|
||||
struct pico_frame *f = pico_frame_alloc(3);
|
||||
struct pico_frame *f2 = pico_frame_alloc(0);
|
||||
int ret = 0;
|
||||
uint8_t buf[6] = { 0, 0, 0, 'a', 'b', 'c'};
|
||||
|
||||
/* I don't care about usage_count, it's tested 'pico_frame_grow' */
|
||||
fail_if(pico_frame_grow_head(f, 2) == 0);
|
||||
|
||||
/* Check for dereferencing OOB */
|
||||
fail_if(pico_frame_grow_head(f2, 2) == -1);
|
||||
f2->net_hdr[0] = 1;
|
||||
|
||||
f->net_hdr = f->buffer;
|
||||
f->net_len = 3;
|
||||
f->net_hdr[0] = 'a';
|
||||
f->net_hdr[1] = 'b';
|
||||
f->net_hdr[2] = 'c';
|
||||
|
||||
/* Try to grow head */
|
||||
ret = pico_frame_grow_head(f, 6);
|
||||
fail_if(ret != 0);
|
||||
fail_unless(0 == memcmp(f->buffer, buf, f->buffer_len));
|
||||
fail_unless(3 == f->net_hdr - f->buffer);
|
||||
|
||||
f->datalink_hdr = f->net_hdr - 3;
|
||||
f->datalink_hdr[0] = 1;
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_pico_frame_grow)
|
||||
{
|
||||
struct pico_frame *f = pico_frame_alloc(3);
|
||||
struct pico_frame *f2 = pico_frame_alloc(0);
|
||||
fail_if(f->buffer_len != 3);
|
||||
/* Ensure that the usage_count starts at byte 4, for good alignment */
|
||||
fail_if(((void*)f->usage_count - (void *)f->buffer) != 4);
|
||||
|
||||
((uint8_t *)f->buffer)[0] = 'a';
|
||||
((uint8_t *)f->buffer)[1] = 'b';
|
||||
((uint8_t *)f->buffer)[2] = 'c';
|
||||
*f->usage_count = 12;
|
||||
|
||||
|
||||
/* First, the failing cases. */
|
||||
fail_if(pico_frame_grow(NULL, 30) == 0);
|
||||
fail_if(pico_frame_grow(f, 2) == 0);
|
||||
f->flags = 0;
|
||||
|
||||
/* Check for dereferencing OOB */
|
||||
fail_if(pico_frame_grow(f2, 3) != 0);
|
||||
f2->net_hdr[0] = 1;
|
||||
f2->net_hdr[1] = 2;
|
||||
|
||||
pico_set_mm_failure(1);
|
||||
fail_if(pico_frame_grow(f, 21) == 0);
|
||||
|
||||
/* Now, the good one. */
|
||||
fail_if(pico_frame_grow(f, 21) != 0);
|
||||
fail_if(f->buffer_len != 21);
|
||||
fail_if(((void *)f->usage_count - (void *)f->buffer) != 24);
|
||||
|
||||
|
||||
fail_if(((uint8_t *)f->buffer)[0] != 'a');
|
||||
fail_if(((uint8_t *)f->buffer)[1] != 'b');
|
||||
fail_if(((uint8_t *)f->buffer)[2] != 'c');
|
||||
fail_if(*f->usage_count != 12);
|
||||
|
||||
*f->usage_count = 1;
|
||||
pico_frame_discard(f);
|
||||
|
||||
f = pico_frame_alloc_skeleton(10, 1);
|
||||
fail_if(!f);
|
||||
fail_if(f->buffer);
|
||||
fail_if(!f->flags);
|
||||
f->buffer = PICO_ZALLOC(10);
|
||||
|
||||
fail_if(pico_frame_grow(f, 22) != 0);
|
||||
fail_if (f->flags);
|
||||
pico_frame_discard(f);
|
||||
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_pico_frame_copy)
|
||||
{
|
||||
struct pico_frame *f = pico_frame_alloc(FRAME_SIZE);
|
||||
struct pico_frame *c1, *c2, *c3;
|
||||
(void)c3;
|
||||
fail_if(!f);
|
||||
fail_if(!f->buffer);
|
||||
fail_if(*f->usage_count != 1);
|
||||
|
||||
/* First copy */
|
||||
c1 = pico_frame_copy(f);
|
||||
fail_if(!c1);
|
||||
fail_if(!c1->buffer);
|
||||
fail_if(!c1->usage_count);
|
||||
|
||||
fail_if (c1->buffer != f->buffer);
|
||||
fail_if(c1->usage_count != f->usage_count);
|
||||
fail_if(*c1->usage_count != 2);
|
||||
fail_if(*f->usage_count != 2);
|
||||
fail_if(c1->start != c1->buffer);
|
||||
fail_if(c1->len != c1->buffer_len);
|
||||
fail_if(c1->len != FRAME_SIZE);
|
||||
|
||||
/* Second copy */
|
||||
c2 = pico_frame_copy(f);
|
||||
fail_if (c2->buffer != f->buffer);
|
||||
fail_if(c2->usage_count != f->usage_count);
|
||||
fail_if(*c2->usage_count != 3);
|
||||
fail_if(*f->usage_count != 3);
|
||||
fail_if(c2->start != c2->buffer);
|
||||
fail_if(c2->len != c2->buffer_len);
|
||||
fail_if(c2->len != FRAME_SIZE);
|
||||
|
||||
|
||||
#ifdef PICO_FAULTY
|
||||
printf("Testing with faulty memory in frame_copy (1)\n");
|
||||
pico_set_mm_failure(1);
|
||||
c3 = pico_frame_copy(f);
|
||||
fail_if(c3);
|
||||
fail_if(!f);
|
||||
#endif
|
||||
|
||||
/* Discard 1 */
|
||||
pico_frame_discard(c1);
|
||||
fail_if(*f->usage_count != 2);
|
||||
|
||||
/* Discard 2 */
|
||||
pico_frame_discard(c2);
|
||||
fail_if(*f->usage_count != 1);
|
||||
|
||||
pico_frame_discard(f);
|
||||
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_pico_frame_deepcopy)
|
||||
{
|
||||
struct pico_frame *f = pico_frame_alloc(FRAME_SIZE);
|
||||
struct pico_frame *dc = pico_frame_deepcopy(f);
|
||||
fail_if(*f->usage_count != 1);
|
||||
fail_if(*dc->usage_count != 1);
|
||||
fail_if(dc->buffer == f->buffer);
|
||||
#ifdef PICO_FAULTY
|
||||
printf("Testing with faulty memory in frame_deepcopy (1)\n");
|
||||
pico_set_mm_failure(1);
|
||||
dc = pico_frame_deepcopy(f);
|
||||
fail_if(dc);
|
||||
fail_if(!f);
|
||||
#endif
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_pico_is_digit)
|
||||
{
|
||||
fail_if(pico_is_digit('a'));
|
||||
fail_if(pico_is_digit('Z'));
|
||||
fail_if(pico_is_digit('\0'));
|
||||
fail_if(pico_is_digit('\n'));
|
||||
fail_if(pico_is_digit('0' - 1));
|
||||
fail_if(pico_is_digit('9' + 1));
|
||||
fail_unless(pico_is_digit('0'));
|
||||
fail_unless(pico_is_digit('9'));
|
||||
}
|
||||
END_TEST
|
||||
|
||||
|
||||
START_TEST(tc_pico_is_hex)
|
||||
{
|
||||
fail_if(pico_is_hex('g'));
|
||||
fail_if(pico_is_hex('Z'));
|
||||
fail_if(pico_is_hex('\0'));
|
||||
fail_if(pico_is_hex('\n'));
|
||||
fail_if(pico_is_hex('0' - 1));
|
||||
fail_if(pico_is_hex('f' + 1));
|
||||
fail_if(pico_is_hex('F' + 1));
|
||||
fail_unless(pico_is_hex('0'));
|
||||
fail_unless(pico_is_hex('f'));
|
||||
fail_unless(pico_is_hex('A'));
|
||||
fail_unless(pico_is_hex('F'));
|
||||
}
|
||||
END_TEST
|
||||
|
||||
Suite *pico_suite(void)
|
||||
{
|
||||
Suite *s = suite_create("pico_frame.c");
|
||||
TCase *TCase_pico_frame_alloc_discard = tcase_create("Unit test for pico_frame_alloc_discard");
|
||||
TCase *TCase_pico_frame_copy = tcase_create("Unit test for pico_frame_copy");
|
||||
TCase *TCase_pico_frame_grow = tcase_create("Unit test for pico_frame_grow");
|
||||
TCase *TCase_pico_frame_grow_head = tcase_create("Unit test for pico_frame_grow_head");
|
||||
TCase *TCase_pico_frame_deepcopy = tcase_create("Unit test for pico_frame_deepcopy");
|
||||
TCase *TCase_pico_is_digit = tcase_create("Unit test for pico_is_digit");
|
||||
TCase *TCase_pico_is_hex = tcase_create("Unit test for pico_is_hex");
|
||||
tcase_add_test(TCase_pico_frame_alloc_discard, tc_pico_frame_alloc_discard);
|
||||
tcase_add_test(TCase_pico_frame_copy, tc_pico_frame_copy);
|
||||
tcase_add_test(TCase_pico_frame_grow, tc_pico_frame_grow);
|
||||
tcase_add_test(TCase_pico_frame_grow_head, tc_pico_frame_grow_head);
|
||||
tcase_add_test(TCase_pico_frame_deepcopy, tc_pico_frame_deepcopy);
|
||||
tcase_add_test(TCase_pico_is_digit, tc_pico_is_digit);
|
||||
tcase_add_test(TCase_pico_is_hex, tc_pico_is_hex);
|
||||
suite_add_tcase(s, TCase_pico_frame_alloc_discard);
|
||||
suite_add_tcase(s, TCase_pico_frame_copy);
|
||||
suite_add_tcase(s, TCase_pico_frame_grow);
|
||||
suite_add_tcase(s, TCase_pico_frame_grow_head);
|
||||
suite_add_tcase(s, TCase_pico_frame_deepcopy);
|
||||
return s;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int fails;
|
||||
Suite *s = pico_suite();
|
||||
SRunner *sr = srunner_create(s);
|
||||
srunner_run_all(sr, CK_NORMAL);
|
||||
fails = srunner_ntests_failed(sr);
|
||||
srunner_free(sr);
|
||||
return fails;
|
||||
}
|
||||
192
kernel/picotcp/test/unit/modunit_pico_hotplug_detection.c
Normal file
192
kernel/picotcp/test/unit/modunit_pico_hotplug_detection.c
Normal file
@@ -0,0 +1,192 @@
|
||||
#include "pico_hotplug_detection.h"
|
||||
#include "pico_tree.h"
|
||||
#include "pico_device.h"
|
||||
#include "modules/pico_hotplug_detection.c"
|
||||
#include "check.h"
|
||||
#include "pico_dev_null.c"
|
||||
|
||||
Suite *pico_suite(void);
|
||||
void cb_one(struct pico_device *dev, int event);
|
||||
void cb_two(struct pico_device *dev, int event);
|
||||
int link_state_a(struct pico_device *self);
|
||||
int link_state_b(struct pico_device *self);
|
||||
|
||||
/* stubs for timer */
|
||||
static int8_t timer_active = 0;
|
||||
void (*timer_cb_function)(pico_time, void *);
|
||||
uint32_t pico_timer_add(pico_time expire, void (*timer)(pico_time, void *), void *arg)
|
||||
{
|
||||
IGNORE_PARAMETER(expire);
|
||||
IGNORE_PARAMETER(arg);
|
||||
|
||||
timer_active++;
|
||||
timer_cb_function = timer;
|
||||
|
||||
return 123;
|
||||
}
|
||||
|
||||
void pico_timer_cancel(uint32_t id)
|
||||
{
|
||||
timer_active--;
|
||||
fail_if(id != 123);
|
||||
}
|
||||
|
||||
/* callbacks for testing */
|
||||
uint32_t cb_one_cntr = 0;
|
||||
int cb_one_last_event = 0;
|
||||
void cb_one(struct pico_device *dev, int event)
|
||||
{
|
||||
IGNORE_PARAMETER(dev);
|
||||
|
||||
cb_one_cntr++;
|
||||
cb_one_last_event = event;
|
||||
}
|
||||
uint32_t cb_two_cntr = 0;
|
||||
int cb_two_last_event = 0;
|
||||
void cb_two(struct pico_device *dev, int event)
|
||||
{
|
||||
IGNORE_PARAMETER(dev);
|
||||
|
||||
cb_two_cntr++;
|
||||
cb_two_last_event = event;
|
||||
}
|
||||
|
||||
/* link state functions for the testing devices */
|
||||
int state_a = 0;
|
||||
int link_state_a(struct pico_device *self)
|
||||
{
|
||||
IGNORE_PARAMETER(self);
|
||||
return state_a;
|
||||
}
|
||||
|
||||
int state_b = 0;
|
||||
int link_state_b(struct pico_device *self)
|
||||
{
|
||||
IGNORE_PARAMETER(self);
|
||||
return state_b;
|
||||
}
|
||||
|
||||
|
||||
START_TEST(tc_pico_hotplug_reg_dereg)
|
||||
{
|
||||
/* create some devices */
|
||||
struct pico_device *dev_a, *dev_b;
|
||||
dev_a = pico_null_create("dummy1");
|
||||
dev_b = pico_null_create("dummy2");
|
||||
|
||||
dev_a->link_state = &link_state_a;
|
||||
dev_b->link_state = &link_state_b;
|
||||
|
||||
/* add some function pointers to be called */
|
||||
pico_hotplug_register(dev_a, &cb_one);
|
||||
fail_unless(timer_active == 1);
|
||||
pico_hotplug_register(dev_a, &cb_two);
|
||||
pico_hotplug_register(dev_b, &cb_two);
|
||||
fail_unless(timer_active == 1);
|
||||
|
||||
/* remove function pointers */
|
||||
pico_hotplug_deregister(dev_a, &cb_one);
|
||||
pico_hotplug_deregister(dev_a, &cb_two);
|
||||
pico_hotplug_deregister(dev_b, &cb_two);
|
||||
|
||||
/* check that our tree is empty at the end */
|
||||
fail_unless(pico_tree_empty(&Hotplug_device_tree));
|
||||
|
||||
/* register functions multiple times */
|
||||
pico_hotplug_register(dev_a, &cb_one);
|
||||
pico_hotplug_register(dev_a, &cb_one);
|
||||
pico_hotplug_register(dev_a, &cb_two);
|
||||
pico_hotplug_register(dev_a, &cb_two);
|
||||
pico_hotplug_register(dev_b, &cb_two);
|
||||
pico_hotplug_register(dev_b, &cb_two);
|
||||
|
||||
/* remove function pointers once */
|
||||
pico_hotplug_deregister(dev_a, &cb_one);
|
||||
pico_hotplug_deregister(dev_a, &cb_two);
|
||||
fail_unless(timer_active == 1);
|
||||
pico_hotplug_deregister(dev_b, &cb_two);
|
||||
fail_unless(timer_active == 0);
|
||||
|
||||
/* check that our tree is empty at the end */
|
||||
fail_unless(pico_tree_empty(&Hotplug_device_tree));
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_pico_hotplug_callbacks)
|
||||
{
|
||||
/* create some devices */
|
||||
struct pico_device *dev_a, *dev_b;
|
||||
|
||||
dev_a = pico_null_create("dummy1");
|
||||
dev_b = pico_null_create("dummy2");
|
||||
|
||||
dev_a->link_state = &link_state_a;
|
||||
dev_b->link_state = &link_state_b;
|
||||
|
||||
/* add some function pointers to be called */
|
||||
pico_hotplug_register(dev_a, &cb_one);
|
||||
pico_hotplug_register(dev_a, &cb_two);
|
||||
pico_hotplug_register(dev_b, &cb_two);
|
||||
|
||||
fail_unless(timer_active == 1);
|
||||
|
||||
timer_active = 0;
|
||||
timer_cb_function(0, NULL);
|
||||
fail_unless(timer_active == 1);
|
||||
fail_unless(cb_one_cntr == 1);
|
||||
fail_unless(cb_two_cntr == 2);
|
||||
|
||||
state_a = 1;
|
||||
timer_active = 0;
|
||||
timer_cb_function(0, NULL);
|
||||
fail_unless(timer_active == 1);
|
||||
fail_unless(cb_one_cntr == 2);
|
||||
fail_unless(cb_one_last_event == PICO_HOTPLUG_EVENT_UP );
|
||||
fail_unless(cb_two_cntr == 3);
|
||||
fail_unless(cb_two_last_event == PICO_HOTPLUG_EVENT_UP );
|
||||
|
||||
state_b = 1;
|
||||
timer_active = 0;
|
||||
timer_cb_function(0, NULL);
|
||||
fail_unless(timer_active == 1);
|
||||
fail_unless(cb_one_cntr == 2);
|
||||
fail_unless(cb_one_last_event == PICO_HOTPLUG_EVENT_UP );
|
||||
fail_unless(cb_two_cntr == 4);
|
||||
fail_unless(cb_two_last_event == PICO_HOTPLUG_EVENT_UP );
|
||||
|
||||
state_a = 0;
|
||||
state_b = 0;
|
||||
timer_active = 0;
|
||||
timer_cb_function(0, NULL);
|
||||
fail_unless(timer_active == 1);
|
||||
fail_unless(cb_one_cntr == 3);
|
||||
fail_unless(cb_one_last_event == PICO_HOTPLUG_EVENT_DOWN );
|
||||
fail_unless(cb_two_cntr == 6);
|
||||
fail_unless(cb_two_last_event == PICO_HOTPLUG_EVENT_DOWN );
|
||||
}
|
||||
END_TEST
|
||||
|
||||
Suite *pico_suite(void)
|
||||
{
|
||||
Suite *s = suite_create("PicoTCP");
|
||||
|
||||
TCase *TCase_pico_hotplug_reg_dereg = tcase_create("Unit test for pico_hotplug_reg_dereg");
|
||||
TCase *TCase_pico_hotplug_callbacks = tcase_create("Unit test for pico_hotplug_callbacks");
|
||||
|
||||
tcase_add_test(TCase_pico_hotplug_reg_dereg, tc_pico_hotplug_reg_dereg);
|
||||
suite_add_tcase(s, TCase_pico_hotplug_reg_dereg);
|
||||
tcase_add_test(TCase_pico_hotplug_callbacks, tc_pico_hotplug_callbacks);
|
||||
suite_add_tcase(s, TCase_pico_hotplug_callbacks);
|
||||
return s;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int fails;
|
||||
Suite *s = pico_suite();
|
||||
SRunner *sr = srunner_create(s);
|
||||
srunner_run_all(sr, CK_NORMAL);
|
||||
fails = srunner_ntests_failed(sr);
|
||||
srunner_free(sr);
|
||||
return fails;
|
||||
}
|
||||
359
kernel/picotcp/test/unit/modunit_pico_igmp.c
Normal file
359
kernel/picotcp/test/unit/modunit_pico_igmp.c
Normal file
@@ -0,0 +1,359 @@
|
||||
#include "pico_config.h"
|
||||
#include "pico_eth.h"
|
||||
#include "pico_socket.h"
|
||||
#include "pico_stack.h"
|
||||
#include "pico_socket.h"
|
||||
#include "pico_queue.h"
|
||||
#include "pico_tree.h"
|
||||
#include "modules/pico_igmp.c"
|
||||
#include "check.h"
|
||||
#include "pico_dev_null.c"
|
||||
|
||||
Suite *pico_suite(void);
|
||||
void mock_callback(struct igmp_timer *t);
|
||||
|
||||
static uint32_t timers_added = 0;
|
||||
uint32_t pico_timer_add(pico_time expire, void (*timer)(pico_time, void *), void *arg)
|
||||
{
|
||||
IGNORE_PARAMETER(expire);
|
||||
IGNORE_PARAMETER(timer);
|
||||
IGNORE_PARAMETER(arg);
|
||||
return ++timers_added;
|
||||
}
|
||||
|
||||
void mock_callback(struct igmp_timer *t)
|
||||
{
|
||||
IGNORE_PARAMETER(t);
|
||||
}
|
||||
static int mcast_filter_cmp(void *ka, void *kb)
|
||||
{
|
||||
union pico_address *a = ka, *b = kb;
|
||||
if (a->ip4.addr < b->ip4.addr)
|
||||
return -1;
|
||||
|
||||
if (a->ip4.addr > b->ip4.addr)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int mcast_sources_cmp(void *ka, void *kb)
|
||||
{
|
||||
union pico_address *a = ka, *b = kb;
|
||||
if (a->ip4.addr < b->ip4.addr)
|
||||
return -1;
|
||||
|
||||
if (a->ip4.addr > b->ip4.addr)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
static PICO_TREE_DECLARE(_MCASTFilter, mcast_filter_cmp);
|
||||
START_TEST(tc_pico_igmp_report_expired)
|
||||
{
|
||||
struct igmp_timer *t = PICO_ZALLOC(sizeof(struct igmp_timer));
|
||||
struct pico_ip4 zero = {0};
|
||||
t->mcast_link = zero;
|
||||
t->mcast_group = zero;
|
||||
/* void function, just check for side effects */
|
||||
pico_igmp_report_expired(t);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_igmpt_type_compare)
|
||||
{
|
||||
struct igmp_timer a;
|
||||
struct igmp_timer b;
|
||||
a.type = 1;
|
||||
b.type = 2;
|
||||
fail_if(igmpt_type_compare(&a, &b) != -1);
|
||||
fail_if(igmpt_type_compare(&b, &a) != 1);
|
||||
fail_if(igmp_timer_cmp(&b, &a) != 1);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_igmp_state_change)
|
||||
{
|
||||
struct pico_ip4 mcast_link, mcast_group;
|
||||
pico_string_to_ipv4("192.168.1.1", &mcast_link.addr);
|
||||
pico_string_to_ipv4("224.7.7.7", &mcast_group.addr);
|
||||
fail_if(pico_igmp_state_change(&mcast_link, &mcast_group, 0, NULL, 99) != -1);
|
||||
fail_if(pico_igmp_state_change(&mcast_link, &mcast_group, 0, NULL, PICO_IGMP_STATE_CREATE) != 0);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_igmp_timer_expired)
|
||||
{
|
||||
struct igmp_timer *t, *s;
|
||||
t = PICO_ZALLOC(sizeof(struct igmp_timer));
|
||||
t->stopped = IGMP_TIMER_STOPPED;
|
||||
t->type = 0;
|
||||
pico_string_to_ipv4("192.168.1.1", &t->mcast_link.addr);
|
||||
pico_string_to_ipv4("244.7.7.7", &t->mcast_group.addr);
|
||||
/* void function, just check for side effects */
|
||||
pico_igmp_timer_expired(0, (void *)t);
|
||||
pico_tree_insert(&IGMPTimers, t);
|
||||
s = PICO_ZALLOC(sizeof(struct igmp_timer));
|
||||
memcpy(s,t,sizeof(struct igmp_timer)); // t will be freed next test
|
||||
pico_igmp_timer_expired(0, (void *)t); /* t is freed here */
|
||||
s->stopped++;
|
||||
s->start = PICO_TIME_MS()*2;
|
||||
s->type++;
|
||||
pico_tree_insert(&IGMPTimers, s);
|
||||
t = PICO_ZALLOC(sizeof(struct igmp_timer));
|
||||
memcpy(t,s,sizeof(struct igmp_timer)); // s will be freed next test
|
||||
pico_igmp_timer_expired(0, (void *)s); /* s is freed here */
|
||||
t->callback = mock_callback;
|
||||
pico_igmp_timer_expired(0, (void *)t);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_igmp_v2querier_expired)
|
||||
{
|
||||
struct igmp_timer *t = PICO_ZALLOC(sizeof(struct igmp_timer));
|
||||
struct pico_ip4 addr = {0};
|
||||
struct pico_device *dev = pico_null_create("dummy2");
|
||||
struct pico_frame *f = pico_frame_alloc(sizeof(struct pico_frame));
|
||||
t->f = f;
|
||||
pico_string_to_ipv4("192.168.1.1", &(addr.addr));
|
||||
/* void function, just check for side effects */
|
||||
/* No link */
|
||||
pico_igmp_v2querier_expired(t);
|
||||
f->dev = dev;
|
||||
pico_ipv4_link_add(dev, addr, addr);
|
||||
pico_igmp_v2querier_expired(t);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_igmp_delete_parameter)
|
||||
{
|
||||
struct mcast_parameters p;
|
||||
fail_if(pico_igmp_delete_parameter(&p) != -1);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_igmp_process_in)
|
||||
{
|
||||
struct mcast_parameters *p;
|
||||
struct pico_device *dev = pico_null_create("dummy3");
|
||||
struct pico_ipv4_link *link;
|
||||
uint8_t i, j, _i, _j;
|
||||
int result;
|
||||
struct pico_mcast_group g;
|
||||
/* Building example frame */
|
||||
p = PICO_ZALLOC(sizeof(struct mcast_parameters));
|
||||
pico_string_to_ipv4("192.168.1.1", &p->mcast_link.ip4.addr);
|
||||
pico_string_to_ipv4("244.7.7.7", &p->mcast_group.ip4.addr);
|
||||
/* no link */
|
||||
fail_if(pico_igmp_generate_report(p) != -1);
|
||||
|
||||
pico_ipv4_link_add(dev, p->mcast_link.ip4, p->mcast_link.ip4);
|
||||
link = pico_ipv4_link_get(&p->mcast_link.ip4);
|
||||
link->mcast_compatibility = PICO_IGMPV2;
|
||||
g.mcast_addr.ip4 = p->mcast_group.ip4;
|
||||
g.MCASTSources.root = &LEAF;
|
||||
g.MCASTSources.compare = mcast_sources_cmp;
|
||||
/* No mcastsources tree */
|
||||
link->mcast_compatibility = PICO_IGMPV3;
|
||||
fail_if(pico_igmp_generate_report(p) != -1);
|
||||
pico_tree_insert(link->MCASTGroups, &g);
|
||||
pico_tree_insert(&IGMPParameters, p);
|
||||
|
||||
link->mcast_compatibility = 99;
|
||||
fail_if(pico_igmp_generate_report(p) != -1);
|
||||
link->mcast_compatibility = PICO_IGMPV2;
|
||||
fail_if(pico_igmp_generate_report(p) != 0);
|
||||
link->mcast_compatibility = PICO_IGMPV3;
|
||||
for(_j = 0; _j < 3; _j++) { /* FILTER */
|
||||
(_j == 2) ? (result = -1) : (result = 0);
|
||||
for(_i = 0; _i < 3; _i++) { /* FILTER */
|
||||
if(_i == 2) result = -1;
|
||||
|
||||
for(i = 0; i < 3; i++) { /* STATES */
|
||||
for(j = 0; j < 6; j++) { /* EVENTS */
|
||||
p->MCASTFilter = &_MCASTFilter;
|
||||
p->filter_mode = _i;
|
||||
g.filter_mode = _j;
|
||||
if(p->event == IGMP_EVENT_DELETE_GROUP || p->event == IGMP_EVENT_QUERY_RECV)
|
||||
p->event++;
|
||||
|
||||
fail_if(pico_igmp_generate_report(p) != result);
|
||||
p->state = i;
|
||||
p->event = j;
|
||||
if(result != -1 && p->f) /* in some combinations, no frame is created */
|
||||
fail_if(pico_igmp_process_in(NULL, p->f) != 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_igmp_find_parameter)
|
||||
{
|
||||
struct pico_ip4 mcast_link, mcast_group;
|
||||
struct mcast_parameters test = {
|
||||
0
|
||||
};
|
||||
fail_if(pico_igmp_find_parameter(NULL, NULL) != NULL);
|
||||
pico_string_to_ipv4("192.168.1.1", &mcast_link.addr);
|
||||
fail_if(pico_igmp_find_parameter(&mcast_link, NULL) != NULL);
|
||||
pico_string_to_ipv4("192.168.1.2", &mcast_group.addr);
|
||||
fail_if(pico_igmp_find_parameter(&mcast_link, &mcast_group) != NULL);
|
||||
test.mcast_link.ip4 = mcast_link;
|
||||
test.mcast_group.ip4 = mcast_group;
|
||||
pico_tree_insert(&IGMPParameters, &test);
|
||||
|
||||
fail_if(pico_igmp_find_parameter(&mcast_link, &mcast_group) == NULL);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_igmp_compatibility_mode)
|
||||
{
|
||||
struct pico_frame *f;
|
||||
struct pico_device *dev = pico_null_create("dummy1");
|
||||
struct pico_ip4 addr;
|
||||
struct pico_ipv4_hdr *hdr;
|
||||
struct igmp_message *query;
|
||||
uint8_t ihl = 24;
|
||||
f = pico_proto_ipv4.alloc(&pico_proto_ipv4, dev, sizeof(struct igmpv3_report) + sizeof(struct igmpv3_group_record) + (0 * sizeof(struct pico_ip4)));
|
||||
pico_string_to_ipv4("192.168.1.2", &addr.addr);
|
||||
hdr = (struct pico_ipv4_hdr *) f->net_hdr;
|
||||
ihl = (uint8_t)((hdr->vhl & 0x0F) * 4); /* IHL is in 32bit words */
|
||||
query = (struct igmp_message *) f->transport_hdr;
|
||||
/* No link */
|
||||
fail_if(pico_igmp_compatibility_mode(f) != -1);
|
||||
pico_ipv4_link_add(dev, addr, addr);
|
||||
f->dev = dev;
|
||||
/* Igmpv3 query */
|
||||
hdr->len = short_be((uint16_t)(12 + ihl));
|
||||
fail_if(pico_igmp_compatibility_mode(f) != 0);
|
||||
/* Igmpv2 query */
|
||||
hdr->len = short_be((uint16_t)(8 + ihl));
|
||||
query->max_resp_time = 0;
|
||||
fail_if(pico_igmp_compatibility_mode(f) == 0);
|
||||
query->max_resp_time = 1;
|
||||
fail_if(pico_igmp_compatibility_mode(f) != 0);
|
||||
/* Invalid Query */
|
||||
hdr->len = short_be((uint16_t)(9 + ihl));
|
||||
fail_if(pico_igmp_compatibility_mode(f) == 0);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_igmp_analyse_packet)
|
||||
{
|
||||
struct pico_frame *f;
|
||||
struct pico_device *dev = pico_null_create("dummy0");
|
||||
struct pico_ip4 addr;
|
||||
struct igmp_message *igmp;
|
||||
f = pico_proto_ipv4.alloc(&pico_proto_ipv4, dev, sizeof(struct igmp_message));
|
||||
pico_string_to_ipv4("192.168.1.1", &addr.addr);
|
||||
/* No link */
|
||||
fail_if(pico_igmp_analyse_packet(f) != NULL);
|
||||
pico_ipv4_link_add(dev, addr, addr);
|
||||
f->dev = dev;
|
||||
|
||||
igmp = (struct igmp_message *) (f->transport_hdr);
|
||||
igmp->type = 0;
|
||||
/* wrong type */
|
||||
fail_if(pico_igmp_analyse_packet(f) != NULL);
|
||||
|
||||
/* all correct */
|
||||
igmp->type = IGMP_TYPE_MEM_QUERY;
|
||||
fail_if(pico_igmp_analyse_packet(f) == NULL);
|
||||
igmp->type = IGMP_TYPE_MEM_REPORT_V1;
|
||||
fail_if(pico_igmp_analyse_packet(f) == NULL);
|
||||
igmp->type = IGMP_TYPE_MEM_REPORT_V2;
|
||||
fail_if(pico_igmp_analyse_packet(f) == NULL);
|
||||
igmp->type = IGMP_TYPE_MEM_REPORT_V3;
|
||||
fail_if(pico_igmp_analyse_packet(f) == NULL);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_igmp_discard)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_srst)
|
||||
{
|
||||
struct mcast_parameters p;
|
||||
struct pico_device *dev = pico_null_create("dummy0");
|
||||
struct pico_ipv4_link *link;
|
||||
|
||||
pico_string_to_ipv4("192.168.1.1", &p.mcast_link.ip4.addr);
|
||||
/* no link */
|
||||
fail_if(srst(&p) != -1);
|
||||
pico_ipv4_link_add(dev, p.mcast_link.ip4, p.mcast_link.ip4);
|
||||
link = pico_ipv4_link_get(&p.mcast_link.ip4);
|
||||
/* Not supported protocol for this call */
|
||||
link->mcast_compatibility = PICO_IGMPV2;
|
||||
fail_if(srst(&p) != -1);
|
||||
link->mcast_compatibility = PICO_IGMPV3;
|
||||
fail_if(srst(&p) != -1);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_stcl)
|
||||
{
|
||||
struct igmp_timer *t = PICO_ZALLOC(sizeof(struct igmp_timer));
|
||||
struct mcast_parameters p;
|
||||
|
||||
pico_string_to_ipv4("192.168.1.10", &t->mcast_link.addr);
|
||||
pico_string_to_ipv4("244.7.7.7", &t->mcast_group.addr);
|
||||
p.mcast_link.ip4 = t->mcast_link;
|
||||
p.mcast_group.ip4 = t->mcast_group;
|
||||
t->type = IGMP_TIMER_GROUP_REPORT;
|
||||
/* not in tree */
|
||||
fail_if(stcl(&p) != -1);
|
||||
pico_igmp_timer_start(t);
|
||||
fail_if(stcl(&p) != 0);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
Suite *pico_suite(void)
|
||||
{
|
||||
|
||||
Suite *s = suite_create("PicoTCP");
|
||||
|
||||
TCase *TCase_pico_igmp_report_expired = tcase_create("Unit test for pico_igmp_report_expired");
|
||||
TCase *TCase_igmpt_type_compare = tcase_create("Unit test for igmpt_type_compare");
|
||||
TCase *TCase_pico_igmp_analyse_packet = tcase_create("Unit test for pico_igmp_analyse_packet");
|
||||
TCase *TCase_pico_igmp_discard = tcase_create("Unit test for pico_igmp_discard");
|
||||
TCase *TCase_pico_igmp_compatibility_mode = tcase_create("Unit test for pico_igmp_compatibility");
|
||||
TCase *TCase_pico_igmp_state_change = tcase_create("Unit test for pico_igmp_state_change");
|
||||
TCase *TCase_pico_igmp_process_in = tcase_create("Unit test for pico_igmp_process_in");
|
||||
TCase *TCase_pico_igmp_timer_expired = tcase_create("Unit test for pico_igmp_timer_expired");
|
||||
TCase *TCase_pico_igmp_delete_parameter = tcase_create("Unit test for pico_igmp_delete_parameter");
|
||||
TCase *TCase_pico_igmp_find_parameter = tcase_create("Unit test for pico_igmp_find_parameter");
|
||||
TCase *TCase_stcl = tcase_create("Unit test for stcl");
|
||||
TCase *TCase_srst = tcase_create("Unit test for srst");
|
||||
TCase *TCase_pico_igmp_v2querier_expired = tcase_create("Unit test for pico_igmp_v2_querier_expired");
|
||||
|
||||
tcase_add_test(TCase_pico_igmp_report_expired, tc_pico_igmp_report_expired);
|
||||
suite_add_tcase(s, TCase_pico_igmp_report_expired);
|
||||
tcase_add_test(TCase_igmpt_type_compare, tc_igmpt_type_compare);
|
||||
suite_add_tcase(s, TCase_igmpt_type_compare);
|
||||
tcase_add_test(TCase_pico_igmp_analyse_packet, tc_pico_igmp_analyse_packet);
|
||||
suite_add_tcase(s, TCase_pico_igmp_analyse_packet);
|
||||
tcase_add_test(TCase_pico_igmp_discard, tc_pico_igmp_discard);
|
||||
suite_add_tcase(s, TCase_pico_igmp_discard);
|
||||
tcase_add_test(TCase_pico_igmp_compatibility_mode, tc_pico_igmp_compatibility_mode);
|
||||
suite_add_tcase(s, TCase_pico_igmp_compatibility_mode);
|
||||
suite_add_tcase(s, TCase_pico_igmp_state_change);
|
||||
tcase_add_test(TCase_pico_igmp_state_change, tc_pico_igmp_state_change);
|
||||
suite_add_tcase(s, TCase_pico_igmp_process_in);
|
||||
tcase_add_test(TCase_pico_igmp_process_in, tc_pico_igmp_process_in);
|
||||
suite_add_tcase(s, TCase_pico_igmp_timer_expired);
|
||||
tcase_add_test(TCase_pico_igmp_timer_expired, tc_pico_igmp_timer_expired);
|
||||
suite_add_tcase(s, TCase_pico_igmp_delete_parameter);
|
||||
tcase_add_test(TCase_pico_igmp_delete_parameter, tc_pico_igmp_delete_parameter);
|
||||
suite_add_tcase(s, TCase_pico_igmp_find_parameter);
|
||||
tcase_add_test(TCase_pico_igmp_find_parameter, tc_pico_igmp_find_parameter);
|
||||
suite_add_tcase(s, TCase_stcl);
|
||||
tcase_add_test(TCase_stcl, tc_stcl);
|
||||
suite_add_tcase(s, TCase_srst);
|
||||
tcase_add_test(TCase_srst, tc_srst);
|
||||
suite_add_tcase(s, TCase_pico_igmp_v2querier_expired);
|
||||
tcase_add_test(TCase_pico_igmp_v2querier_expired, tc_pico_igmp_v2querier_expired);
|
||||
return s;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int fails;
|
||||
Suite *s = pico_suite();
|
||||
SRunner *sr = srunner_create(s);
|
||||
srunner_run_all(sr, CK_NORMAL);
|
||||
fails = srunner_ntests_failed(sr);
|
||||
srunner_free(sr);
|
||||
return fails;
|
||||
}
|
||||
321
kernel/picotcp/test/unit/modunit_pico_ipfilter.c
Normal file
321
kernel/picotcp/test/unit/modunit_pico_ipfilter.c
Normal file
@@ -0,0 +1,321 @@
|
||||
#include "pico_ipv4.h"
|
||||
#include "pico_config.h"
|
||||
#include "pico_icmp4.h"
|
||||
#include "pico_stack.h"
|
||||
#include "pico_eth.h"
|
||||
#include "pico_socket.h"
|
||||
#include "pico_device.h"
|
||||
#include "pico_ipfilter.h"
|
||||
#include "pico_tcp.h"
|
||||
#include "pico_udp.h"
|
||||
#include "pico_tree.h"
|
||||
#include "modules/pico_ipfilter.c"
|
||||
#include "check.h"
|
||||
|
||||
Suite *pico_suite(void);
|
||||
int pico_icmp4_packet_filtered(struct pico_frame *f)
|
||||
{
|
||||
(void)f;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void pico_frame_discard(struct pico_frame *f)
|
||||
{
|
||||
(void)f;
|
||||
}
|
||||
|
||||
volatile pico_err_t pico_err;
|
||||
|
||||
|
||||
|
||||
START_TEST(tc_ipfilter)
|
||||
{
|
||||
uint32_t r;
|
||||
struct filter_node a = {
|
||||
0
|
||||
}, b = {
|
||||
0
|
||||
};
|
||||
fail_if(filter_compare(&a, &b) != 0);
|
||||
|
||||
|
||||
/* a is rule, matching packet b */
|
||||
a.filter_id = 1;
|
||||
|
||||
/* check that rule is matched properly */
|
||||
fail_if(filter_match_packet_find_rule(&a, &b) != &a);
|
||||
|
||||
/* a has a out port that does not match packet */
|
||||
b.out_port = 8;
|
||||
a.out_port = 7;
|
||||
fail_if(filter_compare(&a, &b) == 0);
|
||||
|
||||
/* a matches all ports */
|
||||
a.out_port = 0;
|
||||
fail_if(filter_compare(&a, &b) != 0);
|
||||
|
||||
/*** NEXT TEST ***/
|
||||
|
||||
|
||||
/* a has a in port that does not match packet */
|
||||
b.in_port = 8;
|
||||
a.in_port = 7;
|
||||
fail_if(filter_compare(&a, &b) == 0);
|
||||
|
||||
/* a matches all ports */
|
||||
a.in_port = 0;
|
||||
fail_if(filter_compare(&a, &b) != 0);
|
||||
|
||||
/* a matches port exactly */
|
||||
a.in_port = 0;
|
||||
fail_if(filter_compare(&a, &b) != 0);
|
||||
|
||||
/*** NEXT TEST ***/
|
||||
|
||||
/* a matches all out addresses */
|
||||
b.out_addr = 0x010000a0;
|
||||
fail_if(filter_compare(&a, &b) != 0);
|
||||
|
||||
/* a does not match b via 8-bit netmask */
|
||||
a.out_addr = 0x000000c0;
|
||||
a.out_addr_netmask = 0x000000ff;
|
||||
fail_if(filter_compare(&a, &b) == 0);
|
||||
|
||||
/* a does not match b at all*/
|
||||
a.out_addr = 0x020000b0;
|
||||
a.out_addr_netmask = 0xffffffff;
|
||||
fail_if(filter_compare(&a, &b) == 0);
|
||||
|
||||
/* a matches b via 8-bit netmask */
|
||||
a.out_addr = 0x000000a0;
|
||||
a.out_addr_netmask = 0x000000ff;
|
||||
fail_if(filter_compare(&a, &b) != 0);
|
||||
|
||||
/* a matches b exactly */
|
||||
a.out_addr = 0x010000a0;
|
||||
a.out_addr_netmask = 0xffffffff;
|
||||
fail_if(filter_compare(&a, &b) != 0);
|
||||
|
||||
/*** NEXT TEST ***/
|
||||
|
||||
/* a matches all in addresses */
|
||||
b.in_addr = 0x010000a0;
|
||||
fail_if(filter_compare(&a, &b) != 0);
|
||||
|
||||
/* a does not match b via 8-bit netmask */
|
||||
a.in_addr = 0x000000c0;
|
||||
a.in_addr_netmask = 0x000000ff;
|
||||
fail_if(filter_compare(&a, &b) == 0);
|
||||
|
||||
/* a does not match b at all*/
|
||||
a.in_addr = 0x020000b0;
|
||||
a.in_addr_netmask = 0xffffffff;
|
||||
fail_if(filter_compare(&a, &b) == 0);
|
||||
|
||||
/* a matches b via 8-bit netmask */
|
||||
a.in_addr = 0x000000a0;
|
||||
a.in_addr_netmask = 0x000000ff;
|
||||
fail_if(filter_compare(&a, &b) != 0);
|
||||
|
||||
/* a matches b exactly */
|
||||
a.in_addr = 0x010000a0;
|
||||
a.in_addr_netmask = 0xffffffff;
|
||||
fail_if(filter_compare(&a, &b) != 0);
|
||||
|
||||
/*** NEXT TEST ***/
|
||||
|
||||
/* a matches all protocols */
|
||||
b.proto = 4u;
|
||||
fail_if(filter_compare(&a, &b) != 0);
|
||||
|
||||
/* a does not match protocol */
|
||||
a.proto = 5u;
|
||||
fail_if(filter_compare(&a, &b) == 0);
|
||||
|
||||
/* a matches b's protocol */
|
||||
a.proto = b.proto;
|
||||
fail_if(filter_compare(&a, &b) != 0);
|
||||
|
||||
/*** NEXT TEST ***/
|
||||
|
||||
/* a matches all devices */
|
||||
b.fdev = (struct pico_device *) &b;
|
||||
fail_if(filter_compare(&a, &b) != 0);
|
||||
|
||||
/* a does not match device */
|
||||
a.fdev = (struct pico_device *)&a;
|
||||
fail_if(filter_compare(&a, &b) == 0);
|
||||
|
||||
/* a matches b's device */
|
||||
a.fdev = b.fdev;
|
||||
fail_if(filter_compare(&a, &b) != 0);
|
||||
|
||||
|
||||
/*** SAME TEST DUPLICATED WITH INVERTED ORDER OF PARAMETERS ***/
|
||||
|
||||
memset(&a, 0, sizeof(struct filter_node));
|
||||
memset(&b, 0, sizeof(struct filter_node));
|
||||
|
||||
a.filter_id = 2;
|
||||
|
||||
|
||||
/* check that rule is matched properly */
|
||||
fail_if(filter_match_packet_find_rule(&b, &a) != &a);
|
||||
|
||||
/* a has a out port that does not match packet */
|
||||
b.out_port = 8;
|
||||
a.out_port = 7;
|
||||
fail_if(filter_compare(&b, &a) == 0);
|
||||
|
||||
/* a matches all ports */
|
||||
a.out_port = 0;
|
||||
fail_if(filter_compare(&b, &a) != 0);
|
||||
|
||||
/*** NEXT TEST ***/
|
||||
|
||||
|
||||
/* a has a in port that does not match packet */
|
||||
b.in_port = 8;
|
||||
a.in_port = 7;
|
||||
fail_if(filter_compare(&b, &a) == 0);
|
||||
|
||||
/* a matches all ports */
|
||||
a.in_port = 0;
|
||||
fail_if(filter_compare(&b, &a) != 0);
|
||||
|
||||
/* a matches port exactly */
|
||||
a.in_port = 0;
|
||||
fail_if(filter_compare(&b, &a) != 0);
|
||||
|
||||
/*** NEXT TEST ***/
|
||||
|
||||
/* a matches all out addresses */
|
||||
b.out_addr = 0x010000a0;
|
||||
fail_if(filter_compare(&b, &a) != 0);
|
||||
|
||||
/* a does not match b via 8-bit netmask */
|
||||
a.out_addr = 0x000000c0;
|
||||
a.out_addr_netmask = 0x000000ff;
|
||||
fail_if(filter_compare(&b, &a) == 0);
|
||||
|
||||
/* a does not match b at all*/
|
||||
a.out_addr = 0x020000b0;
|
||||
a.out_addr_netmask = 0xffffffff;
|
||||
fail_if(filter_compare(&b, &a) == 0);
|
||||
|
||||
/* a matches b via 8-bit netmask */
|
||||
a.out_addr = 0x000000a0;
|
||||
a.out_addr_netmask = 0x000000ff;
|
||||
fail_if(filter_compare(&b, &a) != 0);
|
||||
|
||||
/* a matches b exactly */
|
||||
a.out_addr = 0x010000a0;
|
||||
a.out_addr_netmask = 0xffffffff;
|
||||
fail_if(filter_compare(&b, &a) != 0);
|
||||
|
||||
/*** NEXT TEST ***/
|
||||
|
||||
/* a matches all in addresses */
|
||||
b.in_addr = 0x010000a0;
|
||||
fail_if(filter_compare(&b, &a) != 0);
|
||||
|
||||
/* a does not match b via 8-bit netmask */
|
||||
a.in_addr = 0x000000c0;
|
||||
a.in_addr_netmask = 0x000000ff;
|
||||
fail_if(filter_compare(&b, &a) == 0);
|
||||
|
||||
/* a does not match b at all*/
|
||||
a.in_addr = 0x020000b0;
|
||||
a.in_addr_netmask = 0xffffffff;
|
||||
fail_if(filter_compare(&b, &a) == 0);
|
||||
|
||||
/* a matches b via 8-bit netmask */
|
||||
a.in_addr = 0x000000a0;
|
||||
a.in_addr_netmask = 0x000000ff;
|
||||
fail_if(filter_compare(&b, &a) != 0);
|
||||
|
||||
/* a matches b exactly */
|
||||
a.in_addr = 0x010000a0;
|
||||
a.in_addr_netmask = 0xffffffff;
|
||||
fail_if(filter_compare(&b, &a) != 0);
|
||||
|
||||
/*** NEXT TEST ***/
|
||||
|
||||
/* a matches all protocols */
|
||||
b.proto = 4u;
|
||||
fail_if(filter_compare(&b, &a) != 0);
|
||||
|
||||
/* a does not match protocol */
|
||||
a.proto = 5u;
|
||||
fail_if(filter_compare(&b, &a) == 0);
|
||||
|
||||
/* a matches b's protocol */
|
||||
a.proto = b.proto;
|
||||
fail_if(filter_compare(&b, &a) != 0);
|
||||
|
||||
/*** NEXT TEST ***/
|
||||
|
||||
/* a matches all devices */
|
||||
b.fdev = (struct pico_device *)&b;
|
||||
fail_if(filter_compare(&b, &a) != 0);
|
||||
|
||||
/* a does not match device */
|
||||
a.fdev = (struct pico_device *)&a;
|
||||
fail_if(filter_compare(&b, &a) == 0);
|
||||
|
||||
/* a matches b's device */
|
||||
a.fdev = b.fdev;
|
||||
fail_if(filter_compare(&b, &a) != 0);
|
||||
|
||||
|
||||
|
||||
/*********** TEST ADD FILTER **************/
|
||||
|
||||
/*
|
||||
uint32_t pico_ipv4_filter_add(struct pico_device *dev, uint8_t proto,
|
||||
struct pico_ip4 *out_addr, struct pico_ip4 *out_addr_netmask,
|
||||
struct pico_ip4 *in_addr, struct pico_ip4 *in_addr_netmask,
|
||||
uint16_t out_port, uint16_t in_port, int8_t priority,
|
||||
uint8_t tos, enum filter_action action)
|
||||
*/
|
||||
|
||||
|
||||
r = pico_ipv4_filter_add(NULL, 0, NULL, NULL, NULL, NULL, 0, 0, MAX_PRIORITY + 1, 0, FILTER_DROP);
|
||||
fail_if(r > 0);
|
||||
|
||||
r = pico_ipv4_filter_add(NULL, 0, NULL, NULL, NULL, NULL, 0, 0, MIN_PRIORITY - 1, 0, FILTER_PRIORITY);
|
||||
fail_if(r > 0);
|
||||
|
||||
r = pico_ipv4_filter_add(NULL, 0, NULL, NULL, NULL, NULL, 0, 0, 0, 0, FILTER_COUNT);
|
||||
fail_if(r > 0);
|
||||
|
||||
#ifdef FAULTY
|
||||
pico_set_mm_failure(1);
|
||||
r = pico_ipv4_filter_add(NULL, 0, NULL, NULL, NULL, NULL, 0, 0, 0, 0, FILTER_DROP);
|
||||
fail_if(r > 0);
|
||||
fail_if(pico_err != PICO_ERR_ENOMEM);
|
||||
#endif
|
||||
}
|
||||
END_TEST
|
||||
|
||||
|
||||
Suite *pico_suite(void)
|
||||
{
|
||||
Suite *s = suite_create("IPfilter module");
|
||||
|
||||
TCase *TCase_ipfilter = tcase_create("Unit test for ipfilter");
|
||||
tcase_add_test(TCase_ipfilter, tc_ipfilter);
|
||||
suite_add_tcase(s, TCase_ipfilter);
|
||||
return s;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int fails;
|
||||
Suite *s = pico_suite();
|
||||
SRunner *sr = srunner_create(s);
|
||||
srunner_run_all(sr, CK_NORMAL);
|
||||
fails = srunner_ntests_failed(sr);
|
||||
srunner_free(sr);
|
||||
return fails;
|
||||
}
|
||||
289
kernel/picotcp/test/unit/modunit_pico_ipv6_nd.c
Normal file
289
kernel/picotcp/test/unit/modunit_pico_ipv6_nd.c
Normal file
@@ -0,0 +1,289 @@
|
||||
#include "pico_config.h"
|
||||
#include "pico_tree.h"
|
||||
#include "pico_ipv6_nd.h"
|
||||
#include "pico_icmp6.h"
|
||||
#include "pico_ipv6.h"
|
||||
#include "pico_stack.h"
|
||||
#include "pico_device.h"
|
||||
#include "pico_eth.h"
|
||||
#include "pico_addressing.h"
|
||||
#include "modules/pico_ipv6_nd.c"
|
||||
#include "check.h"
|
||||
#ifdef PICO_SUPPORT_IPV6
|
||||
|
||||
#undef PICO_TIME
|
||||
#undef PICO_TIME_MS
|
||||
|
||||
#define PICO_TIME_MS (0)
|
||||
#define PICO_TIME (0)
|
||||
|
||||
Suite *pico_suite(void);
|
||||
START_TEST(tc_pico_nd_new_expire_time)
|
||||
{
|
||||
struct pico_ipv6_neighbor n = {
|
||||
0
|
||||
};
|
||||
struct pico_device d = { {0} };
|
||||
|
||||
/* TODO: how to test these time values */
|
||||
|
||||
n.dev = &d;
|
||||
|
||||
d.hostvars.retranstime = 666;
|
||||
|
||||
n.state = PICO_ND_STATE_INCOMPLETE;
|
||||
pico_nd_new_expire_time(&n);
|
||||
|
||||
n.state = PICO_ND_STATE_REACHABLE;
|
||||
pico_nd_new_expire_time(&n);
|
||||
|
||||
|
||||
n.state = PICO_ND_STATE_STALE;
|
||||
pico_nd_new_expire_time(&n);
|
||||
|
||||
|
||||
n.state = PICO_ND_STATE_PROBE;
|
||||
pico_nd_new_expire_time(&n);
|
||||
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_nd_queue)
|
||||
{
|
||||
struct pico_ip6 addr = {{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9 }};
|
||||
int i;
|
||||
struct pico_frame *f = pico_frame_alloc(sizeof(struct pico_ipv6_hdr));
|
||||
struct pico_ipv6_hdr *h = (struct pico_ipv6_hdr *) f->buffer;
|
||||
f->net_hdr = (uint8_t*) h;
|
||||
f->buffer[0] = 0x60; /* Ipv6 */
|
||||
memcpy(h->dst.addr, addr.addr, PICO_SIZE_IP6);
|
||||
|
||||
fail_if(!f);
|
||||
|
||||
for (i = 0; i < PICO_ND_MAX_FRAMES_QUEUED; i++) {
|
||||
fail_if(frames_queued_v6[i] != NULL);
|
||||
}
|
||||
pico_ipv6_nd_unreachable(&addr);
|
||||
for (i = 0; i < PICO_ND_MAX_FRAMES_QUEUED; i++) {
|
||||
fail_if(frames_queued_v6[i] != NULL);
|
||||
}
|
||||
pico_ipv6_nd_postpone(f);
|
||||
fail_if(frames_queued_v6[0]->buffer != f->buffer);
|
||||
|
||||
pico_ipv6_nd_unreachable(&addr);
|
||||
|
||||
for (i = 0; i < PICO_ND_MAX_FRAMES_QUEUED; i++) {
|
||||
fail_if(frames_queued_v6[i] != NULL);
|
||||
}
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_pico_nd_discover)
|
||||
{
|
||||
/* TODO: test this: static void pico_nd_discover(struct pico_ipv6_neighbor *n) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_neigh_options)
|
||||
{
|
||||
/* TODO: test this: static int neigh_options(struct pico_frame *f, struct pico_icmp6_opt_lladdr *opt, uint8_t expected_opt) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_neigh_adv_complete)
|
||||
{
|
||||
/* TODO: test this: static int neigh_adv_complete(struct pico_ipv6_neighbor *n, struct pico_icmp6_opt_lladdr *opt) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_neigh_adv_reconfirm_router_option)
|
||||
{
|
||||
/* TODO: test this: static void neigh_adv_reconfirm_router_option(struct pico_ipv6_neighbor *n, unsigned int isRouter) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_neigh_adv_reconfirm)
|
||||
{
|
||||
/* TODO: test this: static int neigh_adv_reconfirm(struct pico_ipv6_neighbor *n, struct pico_icmp6_opt_lladdr *opt, struct pico_icmp6_hdr *hdr) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_neigh_adv_check_solicited)
|
||||
{
|
||||
/* TODO: test this: static void neigh_adv_check_solicited(struct pico_icmp6_hdr *ic6, struct pico_ipv6_neighbor *n) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_neigh_adv_process)
|
||||
{
|
||||
/* TODO: test this: static int neigh_adv_process(struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_ipv6_neighbor)
|
||||
{
|
||||
/* TODO: test this: static struct pico_ipv6_neighbor *neighbor_from_sol_new(struct pico_ip6 *ip, struct pico_icmp6_opt_lladdr *opt, struct pico_device *dev) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_neighbor_from_sol)
|
||||
{
|
||||
/* TODO: test this: static void neighbor_from_sol(struct pico_ip6 *ip, struct pico_icmp6_opt_lladdr *opt, struct pico_device *dev) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_neigh_sol_process)
|
||||
{
|
||||
/* TODO: test this: static int neigh_sol_process(struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_icmp6_initial_checks)
|
||||
{
|
||||
/* TODO: test this: static int icmp6_initial_checks(struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_neigh_adv_mcast_validity_checks)
|
||||
{
|
||||
/* TODO: test this: static int neigh_adv_mcast_validity_check(struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_neigh_sol_mcast_validity_checks)
|
||||
{
|
||||
/* TODO: test this: static int neigh_sol_mcast_validity_check(struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_neigh_adv_validity_checks)
|
||||
{
|
||||
/* TODO: test this: static int neigh_adv_validity_checks(struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_neigh_sol_validity_checks)
|
||||
{
|
||||
/* TODO: test this: static int neigh_sol_validity_checks(struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_neigh_adv_checks)
|
||||
{
|
||||
/* TODO: test this: static int neigh_adv_checks(struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_nd_router_sol_recv)
|
||||
{
|
||||
/* TODO: test this: static int pico_nd_router_sol_recv(struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_nd_router_adv_recv)
|
||||
{
|
||||
/* TODO: test this: static int pico_nd_router_adv_recv(struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_nd_neigh_sol_recv)
|
||||
{
|
||||
/* TODO: test this: static int pico_nd_neigh_sol_recv(struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_nd_neigh_adv_recv)
|
||||
{
|
||||
/* TODO: test this: static int pico_nd_neigh_adv_recv(struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_nd_redirect_recv)
|
||||
{
|
||||
/* TODO: test this: static int pico_nd_redirect_recv(struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_ipv6_nd_timer_callback)
|
||||
{
|
||||
/* TODO: test this: static void pico_ipv6_nd_timer_callback(pico_time now, void *arg) */
|
||||
}
|
||||
END_TEST
|
||||
|
||||
|
||||
Suite *pico_suite(void)
|
||||
{
|
||||
Suite *s = suite_create("PicoTCP");
|
||||
|
||||
TCase *TCase_pico_nd_new_expire_time = tcase_create("Unit test for pico_nd_new_expire_time");
|
||||
TCase *TCase_pico_nd_discover = tcase_create("Unit test for pico_nd_discover");
|
||||
TCase *TCase_neigh_options = tcase_create("Unit test for neigh_options");
|
||||
TCase *TCase_neigh_adv_complete = tcase_create("Unit test for neigh_adv_complete");
|
||||
TCase *TCase_neigh_adv_reconfirm_router_option = tcase_create("Unit test for neigh_adv_reconfirm_router_option");
|
||||
TCase *TCase_neigh_adv_reconfirm = tcase_create("Unit test for neigh_adv_reconfirm");
|
||||
TCase *TCase_neigh_adv_check_solicited = tcase_create("Unit test for neigh_adv_check_solicited");
|
||||
TCase *TCase_neigh_adv_process = tcase_create("Unit test for neigh_adv_process");
|
||||
TCase *TCase_pico_ipv6_neighbor = tcase_create("Unit test for pico_ipv6_neighbor");
|
||||
TCase *TCase_neighbor_from_sol = tcase_create("Unit test for neighbor_from_sol");
|
||||
TCase *TCase_neigh_sol_process = tcase_create("Unit test for neigh_sol_process");
|
||||
TCase *TCase_icmp6_initial_checks = tcase_create("Unit test for icmp6_initial_checks");
|
||||
TCase *TCase_neigh_sol_mcast_validity_checks = tcase_create("Unit test for neigh_sol_mcast_validity_checks");
|
||||
TCase *TCase_neigh_sol_validity_checks = tcase_create("Unit test for neigh_sol_validity_checks");
|
||||
TCase *TCase_neigh_adv_checks = tcase_create("Unit test for neigh_adv_checks");
|
||||
TCase *TCase_neigh_adv_validity_checks = tcase_create("Unit test for neigh_adv_validity_checks");
|
||||
TCase *TCase_neigh_adv_mcast_validity_checks = tcase_create("Unit test for neigh_adv_mcast_validity_checks");
|
||||
TCase *TCase_pico_nd_router_sol_recv = tcase_create("Unit test for pico_nd_router_sol_recv");
|
||||
TCase *TCase_pico_nd_router_adv_recv = tcase_create("Unit test for pico_nd_router_adv_recv");
|
||||
TCase *TCase_pico_nd_neigh_sol_recv = tcase_create("Unit test for pico_nd_neigh_sol_recv");
|
||||
TCase *TCase_pico_nd_neigh_adv_recv = tcase_create("Unit test for pico_nd_neigh_adv_recv");
|
||||
TCase *TCase_pico_nd_redirect_recv = tcase_create("Unit test for pico_nd_redirect_recv");
|
||||
TCase *TCase_pico_ipv6_nd_timer_callback = tcase_create("Unit test for pico_ipv6_nd_timer_callback");
|
||||
TCase *TCase_pico_nd_queue = tcase_create("Unit test for pico_ipv6_nd: queue for pending frames");
|
||||
|
||||
|
||||
tcase_add_test(TCase_pico_nd_new_expire_time, tc_pico_nd_new_expire_time);
|
||||
suite_add_tcase(s, TCase_pico_nd_new_expire_time);
|
||||
tcase_add_test(TCase_pico_nd_discover, tc_pico_nd_discover);
|
||||
suite_add_tcase(s, TCase_pico_nd_discover);
|
||||
tcase_add_test(TCase_neigh_options, tc_neigh_options);
|
||||
suite_add_tcase(s, TCase_neigh_options);
|
||||
tcase_add_test(TCase_neigh_adv_complete, tc_neigh_adv_complete);
|
||||
suite_add_tcase(s, TCase_neigh_adv_complete);
|
||||
tcase_add_test(TCase_neigh_adv_reconfirm_router_option, tc_neigh_adv_reconfirm_router_option);
|
||||
suite_add_tcase(s, TCase_neigh_adv_reconfirm_router_option);
|
||||
tcase_add_test(TCase_neigh_adv_reconfirm, tc_neigh_adv_reconfirm);
|
||||
suite_add_tcase(s, TCase_neigh_adv_reconfirm);
|
||||
tcase_add_test(TCase_neigh_adv_check_solicited, tc_neigh_adv_check_solicited);
|
||||
suite_add_tcase(s, TCase_neigh_adv_check_solicited);
|
||||
tcase_add_test(TCase_neigh_adv_process, tc_neigh_adv_process);
|
||||
suite_add_tcase(s, TCase_neigh_adv_process);
|
||||
tcase_add_test(TCase_pico_ipv6_neighbor, tc_pico_ipv6_neighbor);
|
||||
suite_add_tcase(s, TCase_pico_ipv6_neighbor);
|
||||
tcase_add_test(TCase_neighbor_from_sol, tc_neighbor_from_sol);
|
||||
suite_add_tcase(s, TCase_neighbor_from_sol);
|
||||
tcase_add_test(TCase_neigh_sol_process, tc_neigh_sol_process);
|
||||
suite_add_tcase(s, TCase_neigh_sol_process);
|
||||
tcase_add_test(TCase_icmp6_initial_checks, tc_icmp6_initial_checks);
|
||||
suite_add_tcase(s, TCase_icmp6_initial_checks);
|
||||
tcase_add_test(TCase_neigh_adv_mcast_validity_checks, tc_neigh_adv_mcast_validity_checks);
|
||||
suite_add_tcase(s, TCase_neigh_adv_mcast_validity_checks);
|
||||
tcase_add_test(TCase_neigh_sol_mcast_validity_checks, tc_neigh_sol_mcast_validity_checks);
|
||||
suite_add_tcase(s, TCase_neigh_sol_mcast_validity_checks);
|
||||
tcase_add_test(TCase_neigh_adv_validity_checks, tc_neigh_adv_validity_checks);
|
||||
suite_add_tcase(s, TCase_neigh_adv_validity_checks);
|
||||
tcase_add_test(TCase_neigh_sol_validity_checks, tc_neigh_sol_validity_checks);
|
||||
suite_add_tcase(s, TCase_neigh_sol_validity_checks);
|
||||
tcase_add_test(TCase_neigh_adv_checks, tc_neigh_adv_checks);
|
||||
suite_add_tcase(s, TCase_neigh_adv_checks);
|
||||
tcase_add_test(TCase_pico_nd_router_sol_recv, tc_pico_nd_router_sol_recv);
|
||||
suite_add_tcase(s, TCase_pico_nd_router_sol_recv);
|
||||
tcase_add_test(TCase_pico_nd_router_adv_recv, tc_pico_nd_router_adv_recv);
|
||||
suite_add_tcase(s, TCase_pico_nd_router_adv_recv);
|
||||
tcase_add_test(TCase_pico_nd_neigh_sol_recv, tc_pico_nd_neigh_sol_recv);
|
||||
suite_add_tcase(s, TCase_pico_nd_neigh_sol_recv);
|
||||
tcase_add_test(TCase_pico_nd_neigh_adv_recv, tc_pico_nd_neigh_adv_recv);
|
||||
suite_add_tcase(s, TCase_pico_nd_neigh_adv_recv);
|
||||
tcase_add_test(TCase_pico_nd_redirect_recv, tc_pico_nd_redirect_recv);
|
||||
suite_add_tcase(s, TCase_pico_nd_redirect_recv);
|
||||
tcase_add_test(TCase_pico_ipv6_nd_timer_callback, tc_pico_ipv6_nd_timer_callback);
|
||||
suite_add_tcase(s, TCase_pico_ipv6_nd_timer_callback);
|
||||
tcase_add_test(TCase_pico_nd_queue, tc_pico_nd_queue);
|
||||
suite_add_tcase(s, TCase_pico_nd_queue);
|
||||
return s;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int fails;
|
||||
Suite *s = pico_suite();
|
||||
SRunner *sr = srunner_create(s);
|
||||
srunner_run_all(sr, CK_NORMAL);
|
||||
fails = srunner_ntests_failed(sr);
|
||||
srunner_free(sr);
|
||||
return fails;
|
||||
}
|
||||
#else
|
||||
int main(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
2227
kernel/picotcp/test/unit/modunit_pico_mdns.c
Normal file
2227
kernel/picotcp/test/unit/modunit_pico_mdns.c
Normal file
File diff suppressed because it is too large
Load Diff
584
kernel/picotcp/test/unit/modunit_pico_mld.c
Normal file
584
kernel/picotcp/test/unit/modunit_pico_mld.c
Normal file
@@ -0,0 +1,584 @@
|
||||
#include "pico_config.h"
|
||||
#include "pico_eth.h"
|
||||
#include "pico_socket.h"
|
||||
#include "pico_stack.h"
|
||||
#include "pico_socket.h"
|
||||
#include "pico_queue.h"
|
||||
#include "pico_tree.h"
|
||||
#include "modules/pico_mld.c"
|
||||
#include "check.h"
|
||||
#include "pico_dev_null.c"
|
||||
|
||||
Suite *pico_suite(void);
|
||||
void mock_callback(struct mld_timer *t);
|
||||
|
||||
static uint32_t timers_added = 0;
|
||||
uint32_t pico_timer_add(pico_time expire, void (*timer)(pico_time, void *), void *arg)
|
||||
{
|
||||
IGNORE_PARAMETER(expire);
|
||||
IGNORE_PARAMETER(timer);
|
||||
IGNORE_PARAMETER(arg);
|
||||
return ++timers_added;
|
||||
}
|
||||
void mock_callback(struct mld_timer *t)
|
||||
{
|
||||
IGNORE_PARAMETER(t);
|
||||
}
|
||||
static int mcast_filter_cmp_ipv6(void *ka, void *kb)
|
||||
{
|
||||
union pico_address *a = ka, *b = kb;
|
||||
return memcmp(&a->ip6, &b->ip6, sizeof(struct pico_ip6));
|
||||
}
|
||||
static int mcast_sources_cmp_ipv6(void *ka, void *kb)
|
||||
{
|
||||
union pico_address *a = ka, *b = kb;
|
||||
return memcmp(&a->ip6, &b->ip6, sizeof(struct pico_ip6));
|
||||
}
|
||||
static PICO_TREE_DECLARE(_MCASTFilter, mcast_filter_cmp_ipv6);
|
||||
|
||||
START_TEST(tc_pico_mld_fill_hopbyhop)
|
||||
{
|
||||
struct pico_ipv6_hbhoption *hbh = NULL;
|
||||
/* Not-null case tested by unit_ipv6.c */
|
||||
fail_if(pico_mld_fill_hopbyhop(hbh) != NULL);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_mld_check_hopbyhop)
|
||||
{
|
||||
struct pico_ipv6_hbhoption *hbh = NULL;
|
||||
struct pico_ipv6_hbhoption _hbh;
|
||||
uint8_t *p;
|
||||
uint8_t options[8] = {
|
||||
PICO_PROTO_ICMP6, 0, PICO_IPV6_EXTHDR_OPT_ROUTER_ALERT, \
|
||||
PICO_IPV6_EXTHDR_OPT_ROUTER_ALERT_DATALEN, 0, 0, 1, 0
|
||||
};
|
||||
int i = 0;
|
||||
int test = 0;
|
||||
fail_if(pico_mld_check_hopbyhop(hbh) != -1);
|
||||
_hbh.type = 1;
|
||||
_hbh.len = 0;
|
||||
fail_if(pico_mld_check_hopbyhop(&_hbh) != -1);
|
||||
_hbh.type = PICO_PROTO_ICMP6;
|
||||
_hbh.len = 1;
|
||||
fail_if(pico_mld_check_hopbyhop(&_hbh) != -1);
|
||||
|
||||
hbh = (struct pico_ipv6_hbhoption *) PICO_ZALLOC(sizeof(struct pico_ipv6_hbhoption) + 7);
|
||||
hbh->type = PICO_PROTO_ICMP6;
|
||||
hbh->len = 0;
|
||||
for(test = 0; test < 7; test++) {
|
||||
p = (uint8_t *)hbh + sizeof(struct pico_ipv6_hbhoption);
|
||||
for(i = 0; i < 6; i++ ) {
|
||||
if(i != test)
|
||||
*(p++) = options[i + 2];
|
||||
else
|
||||
*(p++) = 9;
|
||||
}
|
||||
if(test != 6)
|
||||
fail_if(pico_mld_check_hopbyhop(hbh) != -1);
|
||||
else
|
||||
fail_if(pico_mld_check_hopbyhop(hbh) != 0);
|
||||
}
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_mld_v1querier_expired)
|
||||
{
|
||||
struct mld_timer *t = PICO_ZALLOC(sizeof(struct mld_timer));
|
||||
struct pico_ip6 addr = {{0}};
|
||||
struct pico_device *dev = pico_null_create("dummy2");
|
||||
struct pico_frame *f = pico_frame_alloc(sizeof(struct pico_frame));
|
||||
t->f = f;
|
||||
pico_string_to_ipv6("AAAA::109", addr.addr);
|
||||
/* void function, just check for side effects */
|
||||
/* No link */
|
||||
pico_mld_v1querier_expired(t);
|
||||
f->dev = dev;
|
||||
pico_ipv6_link_add(dev, addr, addr);
|
||||
pico_mld_v1querier_expired(t);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_mld_send_report)
|
||||
{
|
||||
struct pico_frame *f;
|
||||
struct pico_device *dev = pico_null_create("dummy1");
|
||||
struct pico_ip6 addr;
|
||||
struct pico_ipv6_link *link;
|
||||
struct mcast_parameters p;
|
||||
f = pico_proto_ipv6.alloc(&pico_proto_ipv6, dev, sizeof(struct mldv2_report) + MLD_ROUTER_ALERT_LEN + sizeof(struct mldv2_group_record) + (0 * sizeof(struct pico_ip6)));
|
||||
pico_string_to_ipv6("AAAA::110", addr.addr);
|
||||
p.mcast_link.ip6 = addr;
|
||||
/* No link */
|
||||
fail_if(pico_mld_send_report(&p, f) != -1);
|
||||
link = pico_ipv6_link_add(dev, addr, addr);
|
||||
p.event = 0;
|
||||
link->mcast_compatibility = PICO_MLDV1;
|
||||
fail_if(pico_mld_send_report(&p, f) != 0);
|
||||
link->mcast_compatibility = 99;
|
||||
fail_if(pico_mld_send_report(&p, f) != -1);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_mld_report_expired)
|
||||
{
|
||||
struct mld_timer *t = PICO_ZALLOC(sizeof(struct mld_timer));
|
||||
struct pico_ip6 zero = {0};
|
||||
|
||||
t->mcast_link = zero;
|
||||
t->mcast_group = zero;
|
||||
/* void function, just check for side effects */
|
||||
pico_mld_report_expired(t);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_mld_delete_parameter)
|
||||
{
|
||||
struct mcast_parameters p;
|
||||
fail_if(pico_mld_delete_parameter(&p) != -1);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_mldt_type_compare)
|
||||
{
|
||||
struct mld_timer a;
|
||||
struct mld_timer b;
|
||||
a.type = 1;
|
||||
b.type = 2;
|
||||
fail_if(mldt_type_compare(&a, &b) != -1);
|
||||
fail_if(mldt_type_compare(&b, &a) != 1);
|
||||
fail_if(mld_timer_cmp(&b, &a) != 1);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_mld_is_checksum_valid)
|
||||
{
|
||||
struct pico_frame *f;
|
||||
f = pico_proto_ipv6.alloc(&pico_proto_ipv6, NULL, sizeof(struct mldv2_report) + MLD_ROUTER_ALERT_LEN + sizeof(struct mldv2_group_record) + (0 * sizeof(struct pico_ip6)));
|
||||
fail_if(pico_mld_is_checksum_valid(f) == 1);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_mld_find_parameter)
|
||||
{
|
||||
struct pico_ip6 mcast_link, mcast_group;
|
||||
struct mcast_parameters test = {
|
||||
0
|
||||
};
|
||||
fail_if(pico_mld_find_parameter(NULL, NULL) != NULL);
|
||||
pico_string_to_ipv6("AAAA::111", mcast_link.addr);
|
||||
fail_if(pico_mld_find_parameter(&mcast_link, NULL) != NULL);
|
||||
pico_string_to_ipv6("AAAA::211", mcast_group.addr);
|
||||
fail_if(pico_mld_find_parameter(&mcast_link, &mcast_group) != NULL);
|
||||
test.mcast_link.ip6 = mcast_link;
|
||||
test.mcast_group.ip6 = mcast_group;
|
||||
pico_tree_insert(&MLDParameters, &test);
|
||||
|
||||
fail_if(pico_mld_find_parameter(&mcast_link, &mcast_group) == NULL);
|
||||
pico_tree_delete(&MLDParameters, &test);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_mld_timer_expired)
|
||||
{
|
||||
struct mld_timer *t, *s;
|
||||
t = PICO_ZALLOC(sizeof(struct mld_timer));
|
||||
t->stopped = MLD_TIMER_STOPPED;
|
||||
t->type = 0;
|
||||
pico_string_to_ipv6("AAAA::112", t->mcast_link.addr);
|
||||
pico_string_to_ipv6("AAAA::112", t->mcast_group.addr);
|
||||
/* void function, just check for side effects */
|
||||
pico_mld_timer_expired(0, (void *)t);
|
||||
pico_tree_insert(&MLDTimers, t);
|
||||
s = PICO_ZALLOC(sizeof(struct mld_timer));
|
||||
memcpy(s, t, sizeof(struct mld_timer)); /* t will be freed next test */
|
||||
pico_mld_timer_expired(0, (void *)t); /* will be freed */
|
||||
s->stopped++;
|
||||
s->start = PICO_TIME_MS() * 2;
|
||||
s->type++;
|
||||
pico_tree_insert(&MLDTimers, s);
|
||||
t = PICO_ZALLOC(sizeof(struct mld_timer));
|
||||
memcpy(t, s, sizeof(struct mld_timer)); /* s will be freed next test */
|
||||
pico_mld_timer_expired(0, (void *)s); /* s will be freed */
|
||||
t->mld_callback = mock_callback;
|
||||
pico_mld_timer_expired(0, (void *)t); /* t will be freed */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_mld_send_done)
|
||||
{
|
||||
struct mcast_parameters p;
|
||||
fail_if(pico_mld_send_done(&p, NULL) != 0);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_mld_stsdifs)
|
||||
{
|
||||
struct mcast_parameters *p;
|
||||
struct pico_device *dev = pico_null_create("dummy3");
|
||||
struct pico_ipv6_link *link;
|
||||
struct mld_timer *t = PICO_ZALLOC(sizeof(struct mld_timer));
|
||||
/* Building example frame */
|
||||
p = PICO_ZALLOC(sizeof(struct mcast_parameters));
|
||||
pico_string_to_ipv6("AAAA::113", p->mcast_link.ip6.addr);
|
||||
pico_string_to_ipv6("FF00::e007:707", p->mcast_group.ip6.addr);
|
||||
/* no link */
|
||||
fail_if(mld_stsdifs(p) != -1);
|
||||
link = pico_ipv6_link_add(dev, p->mcast_link.ip6, p->mcast_link.ip6);
|
||||
link->mcast_compatibility = PICO_MLDV1;
|
||||
/* no timer */
|
||||
fail_if(mld_stsdifs(p) != -1);
|
||||
t->type = MLD_TIMER_GROUP_REPORT;
|
||||
t->mcast_link = p->mcast_link.ip6;
|
||||
t->mcast_group = p->mcast_group.ip6;
|
||||
pico_tree_insert(&MLDTimers, t);
|
||||
fail_if(mld_stsdifs(p) != 0);
|
||||
/* set flag */
|
||||
pico_mld_flag = 1;
|
||||
fail_if(mld_stsdifs(p) != 0);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_mld_srsf)
|
||||
{
|
||||
struct mcast_parameters *p;
|
||||
/* Building example frame */
|
||||
|
||||
p = PICO_ZALLOC(sizeof(struct mcast_parameters));
|
||||
pico_string_to_ipv6("AAAA::114", p->mcast_link.ip6.addr);
|
||||
pico_string_to_ipv6("FF00::e007:707", p->mcast_group.ip6.addr);
|
||||
fail_if(mld_srsf(p) != -1);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_mld_srst)
|
||||
{
|
||||
struct mcast_parameters *p;
|
||||
struct pico_device *dev = pico_null_create("dummy3");
|
||||
struct pico_ipv6_link *link;
|
||||
struct pico_mcast_group g;
|
||||
/* Building example frame */
|
||||
|
||||
p = PICO_ZALLOC(sizeof(struct mcast_parameters));
|
||||
pico_string_to_ipv6("AAAA::99", p->mcast_link.ip6.addr);
|
||||
pico_string_to_ipv6("FF00::e007:707", p->mcast_group.ip6.addr);
|
||||
p->MCASTFilter = &_MCASTFilter;
|
||||
p->filter_mode = 0;
|
||||
g.filter_mode = 0;
|
||||
g.mcast_addr = p->mcast_group;
|
||||
g.MCASTSources.root = &LEAF;
|
||||
g.MCASTSources.compare = mcast_sources_cmp_ipv6;
|
||||
|
||||
pico_tree_insert(&MLDParameters, p);
|
||||
/* no link */
|
||||
fail_if(mld_srst(p) != -1);
|
||||
link = pico_ipv6_link_add(dev, p->mcast_link.ip6, p->mcast_link.ip6);
|
||||
link->mcast_compatibility = PICO_MLDV1;
|
||||
/* invalid proto */
|
||||
fail_if(mld_srst(p) != -1);
|
||||
link->mcast_compatibility = PICO_MLDV2;
|
||||
pico_tree_insert(link->MCASTGroups, &g);
|
||||
|
||||
fail_if(mld_srst(p) != 0);
|
||||
pico_tree_delete(&MLDParameters, p);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_mld_mrsrrt)
|
||||
{
|
||||
struct mcast_parameters *p;
|
||||
struct pico_device *dev = pico_null_create("dummy3");
|
||||
struct pico_ipv6_link *link;
|
||||
/* Building example frame */
|
||||
p = PICO_ZALLOC(sizeof(struct mcast_parameters));
|
||||
pico_string_to_ipv6("AAAA::115", p->mcast_link.ip6.addr);
|
||||
pico_string_to_ipv6("FF00::e007:707", p->mcast_group.ip6.addr);
|
||||
/* no link */
|
||||
fail_if(mld_mrsrrt(p) != -1);
|
||||
link = pico_ipv6_link_add(dev, p->mcast_link.ip6, p->mcast_link.ip6);
|
||||
link->mcast_compatibility = PICO_MLDV1;
|
||||
/* wrong proto */
|
||||
fail_if(mld_mrsrrt(p) != -1);
|
||||
link->mcast_compatibility = PICO_MLDV2;
|
||||
p->f = pico_proto_ipv6.alloc(&pico_proto_ipv6, dev, sizeof(struct mldv2_report) + MLD_ROUTER_ALERT_LEN + sizeof(struct mldv2_group_record) + (0 * sizeof(struct pico_ip6)));
|
||||
fail_if(mld_mrsrrt(p) != -1);
|
||||
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_mld_process_in)
|
||||
{
|
||||
struct mcast_parameters *p;
|
||||
struct pico_device *dev = pico_null_create("dummy3");
|
||||
struct pico_ipv6_link *link;
|
||||
uint8_t i, j, _i, _j;
|
||||
int result = 0;
|
||||
struct pico_mcast_group g;
|
||||
struct mldv2_report *report;
|
||||
/* Building example frame */
|
||||
p = PICO_ZALLOC(sizeof(struct mcast_parameters));
|
||||
pico_string_to_ipv6("AAAA::101", p->mcast_link.ip6.addr);
|
||||
pico_string_to_ipv6("FF00::e007:707", p->mcast_group.ip6.addr);
|
||||
/* no link */
|
||||
fail_if(pico_mld_generate_report(p) != -1);
|
||||
link = pico_ipv6_link_add(dev, p->mcast_link.ip6, p->mcast_link.ip6);
|
||||
pico_string_to_ipv6("AAAA::100", p->mcast_group.ip6.addr);
|
||||
fail_if(pico_mld_generate_report(p) != -1);
|
||||
pico_string_to_ipv6("FF00::e007:707", p->mcast_group.ip6.addr);
|
||||
link->mcast_compatibility = PICO_MLDV1;
|
||||
g.mcast_addr = p->mcast_group;
|
||||
g.MCASTSources.root = &LEAF;
|
||||
g.MCASTSources.compare = mcast_sources_cmp_ipv6;
|
||||
/* No mcastsources tree */
|
||||
link->mcast_compatibility = PICO_MLDV2;
|
||||
fail_if(pico_mld_generate_report(p) != -1);
|
||||
pico_tree_insert(link->MCASTGroups, &g);
|
||||
pico_tree_insert(&MLDParameters, p);
|
||||
|
||||
link->mcast_compatibility = 99;
|
||||
fail_if(pico_mld_generate_report(p) != -1);
|
||||
link->mcast_compatibility = PICO_MLDV1;
|
||||
fail_if(pico_mld_generate_report(p) != 0);
|
||||
link->mcast_compatibility = PICO_MLDV2;
|
||||
for(_j = 0; _j < 3; _j++) { /* FILTER */
|
||||
(_j == 2) ? (result = -1) : (result = 0);
|
||||
for(_i = 0; _i < 3; _i++) { /* FILTER */
|
||||
if(_i == 2) result = -1;
|
||||
|
||||
for(i = 0; i < 3; i++) { /* STATES */
|
||||
for(j = 0; j < 6; j++) { /* EVENTS */
|
||||
p->MCASTFilter = &_MCASTFilter;
|
||||
p->filter_mode = _i;
|
||||
g.filter_mode = _j;
|
||||
if(p->event == MLD_EVENT_DELETE_GROUP || p->event == MLD_EVENT_QUERY_RECV)
|
||||
p->event++;
|
||||
|
||||
fail_if(pico_mld_generate_report(p) != result);
|
||||
p->state = i;
|
||||
p->event = j;
|
||||
if(result != -1 && p->f) { /* in some combinations, no frame is created */
|
||||
report = (struct mldv2_report *)(p->f->transport_hdr + MLD_ROUTER_ALERT_LEN);
|
||||
report->crc = short_be(pico_icmp6_checksum(p->f));
|
||||
fail_if(pico_mld_process_in(p->f) != 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
pico_tree_delete(&MLDParameters, p);
|
||||
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_mld_rtimrtct)
|
||||
{
|
||||
struct mld_timer *t = PICO_ZALLOC(sizeof(struct mld_timer));
|
||||
struct mcast_parameters p;
|
||||
pico_string_to_ipv6("AAAA::102", t->mcast_link.addr);
|
||||
pico_string_to_ipv6("AAAA::102", t->mcast_group.addr);
|
||||
p.mcast_link.ip6 = t->mcast_link;
|
||||
p.mcast_group.ip6 = t->mcast_group;
|
||||
t->type = MLD_TIMER_GROUP_REPORT;
|
||||
/* not in tree */
|
||||
fail_if(mld_rtimrtct(&p) != -1);
|
||||
pico_mld_timer_start(t);
|
||||
fail_if(mld_rtimrtct(&p) != 0);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_mld_stcl)
|
||||
{
|
||||
struct mld_timer *t = PICO_ZALLOC(sizeof(struct mld_timer));
|
||||
struct mcast_parameters p;
|
||||
pico_string_to_ipv6("AAAA::103", t->mcast_link.addr);
|
||||
pico_string_to_ipv6("AAAA::103", t->mcast_group.addr);
|
||||
p.mcast_link.ip6 = t->mcast_link;
|
||||
p.mcast_group.ip6 = t->mcast_group;
|
||||
t->type = MLD_TIMER_GROUP_REPORT;
|
||||
/* not in tree */
|
||||
fail_if(mld_stcl(&p) != -1);
|
||||
pico_mld_timer_start(t);
|
||||
fail_if(mld_stcl(&p) != 0);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_mld_compatibility_mode)
|
||||
{
|
||||
struct pico_frame *f;
|
||||
struct pico_device *dev = pico_null_create("dummy1");
|
||||
struct pico_ip6 addr;
|
||||
|
||||
f = pico_proto_ipv6.alloc(&pico_proto_ipv6, NULL, sizeof(struct mldv2_report) + MLD_ROUTER_ALERT_LEN + sizeof(struct mldv2_group_record) + (0 * sizeof(struct pico_ip6)));
|
||||
pico_string_to_ipv6("AAAA::104", addr.addr);
|
||||
/* No link */
|
||||
fail_if(pico_mld_compatibility_mode(f) != -1);
|
||||
pico_ipv6_link_add(dev, addr, addr);
|
||||
f->dev = dev;
|
||||
/* MLDv2 query */
|
||||
f->buffer_len = 28 + PICO_SIZE_IP6HDR + MLD_ROUTER_ALERT_LEN;
|
||||
fail_if(pico_mld_compatibility_mode(f) != 0);
|
||||
/* MLDv1 query */
|
||||
f->buffer_len = 24 + PICO_SIZE_IP6HDR + MLD_ROUTER_ALERT_LEN;
|
||||
fail_if(pico_mld_compatibility_mode(f) != 0);
|
||||
/* Invalid Query */
|
||||
f->buffer_len = 25 + PICO_SIZE_IP6HDR + MLD_ROUTER_ALERT_LEN;
|
||||
fail_if(pico_mld_compatibility_mode(f) == 0);
|
||||
/* MLDv2 query + timer amready running */
|
||||
f->dev = dev;
|
||||
f->buffer_len = 28 + PICO_SIZE_IP6HDR + MLD_ROUTER_ALERT_LEN + PICO_SIZE_ETHHDR;
|
||||
fail_if(pico_mld_compatibility_mode(f) != -1);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_mld_timer_reset)
|
||||
{
|
||||
struct mld_timer *t = PICO_ZALLOC(sizeof(struct mld_timer));
|
||||
pico_string_to_ipv6("AAAA::105", t->mcast_link.addr);
|
||||
pico_string_to_ipv6("AAAA::105", t->mcast_group.addr);
|
||||
t->type = 0;
|
||||
fail_if(pico_mld_timer_reset(t) != -1);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_mld_state_change)
|
||||
{
|
||||
struct pico_ip6 mcast_link, mcast_group;
|
||||
struct mcast_parameters p;
|
||||
pico_string_to_ipv6("AAAA::106", mcast_link.addr);
|
||||
pico_string_to_ipv6("AAAA::106", mcast_group.addr);
|
||||
p.mcast_link.ip6 = mcast_link;
|
||||
p.mcast_group.ip6 = mcast_group;
|
||||
|
||||
fail_if(pico_mld_state_change(NULL, &mcast_group, 0, NULL, PICO_MLD_STATE_CREATE) != -1);
|
||||
/* All host group */
|
||||
pico_string_to_ipv6("FF01:0:0:0:0:0:0:1", mcast_group.addr);
|
||||
fail_if(pico_mld_state_change(&mcast_link, &mcast_group, 0, NULL, PICO_MLD_STATE_CREATE) != 0);
|
||||
pico_string_to_ipv6("AAAA::107", mcast_group.addr);
|
||||
fail_if(pico_mld_state_change(&mcast_link, &mcast_group, 0, NULL, 99) != -1);
|
||||
pico_tree_insert(&MLDParameters, &p);
|
||||
fail_if(pico_mld_state_change(&mcast_link, &mcast_group, 0, NULL, 99) != -1);
|
||||
pico_tree_delete(&MLDParameters, &p);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_mld_analyse_packet)
|
||||
{
|
||||
struct pico_frame *f;
|
||||
struct pico_device *dev = pico_null_create("dummy0");
|
||||
struct pico_ip6 addr;
|
||||
struct pico_ip6 local;
|
||||
struct pico_ipv6_hdr *ip6;
|
||||
struct pico_ipv6_hbhoption *hbh;
|
||||
struct pico_icmp6_hdr *mld;
|
||||
f = pico_proto_ipv6.alloc(&pico_proto_ipv6, dev, sizeof(struct mld_message) + MLD_ROUTER_ALERT_LEN);
|
||||
pico_string_to_ipv6("AAAA::108", addr.addr);
|
||||
pico_string_to_ipv6("FE80::1", local.addr);
|
||||
/* No link */
|
||||
fail_if(pico_mld_analyse_packet(f) != NULL);
|
||||
pico_ipv6_link_add(dev, addr, addr);
|
||||
ip6 = (struct pico_ipv6_hdr *) f->net_hdr;
|
||||
ip6->hop = 99;
|
||||
/* Incorrect hop */
|
||||
fail_if(pico_mld_analyse_packet(f) != NULL);
|
||||
ip6->hop = 1;
|
||||
hbh = (struct pico_ipv6_hbhoption *) f->transport_hdr;
|
||||
pico_mld_fill_hopbyhop(hbh);
|
||||
hbh->type = 99;
|
||||
/* incorrect hop by hop */
|
||||
fail_if(pico_mld_analyse_packet(f) != NULL);
|
||||
pico_mld_fill_hopbyhop(hbh);
|
||||
ip6->src = addr;
|
||||
/* Not link local */
|
||||
fail_if(pico_mld_analyse_packet(f) != NULL);
|
||||
memcpy(&ip6->src, PICO_IP6_ANY, sizeof(struct pico_ip6));
|
||||
fail_if(pico_mld_analyse_packet(f) != NULL);
|
||||
ip6->src = local;
|
||||
mld = (struct pico_icmp6_hdr *) (f->transport_hdr + MLD_ROUTER_ALERT_LEN);
|
||||
mld->type = 0;
|
||||
|
||||
/* wrong type */
|
||||
fail_if(pico_mld_analyse_packet(f) != NULL);
|
||||
/* all correct */
|
||||
mld->type = PICO_MLD_QUERY;
|
||||
fail_if(pico_mld_analyse_packet(f) == NULL);
|
||||
mld->type = PICO_MLD_REPORT;
|
||||
fail_if(pico_mld_analyse_packet(f) == NULL);
|
||||
mld->type = PICO_MLD_DONE;
|
||||
fail_if(pico_mld_analyse_packet(f) == NULL);
|
||||
mld->type = PICO_MLD_REPORTV2;
|
||||
fail_if(pico_mld_analyse_packet(f) == NULL);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_mld_discard)
|
||||
{
|
||||
mld_discard(NULL);
|
||||
}
|
||||
END_TEST
|
||||
Suite *pico_suite(void)
|
||||
{
|
||||
|
||||
Suite *s = suite_create("PicoTCP");
|
||||
|
||||
TCase *TCase_pico_mld_fill_hopbyhop = tcase_create("Unit test for pico_mld_fill_hopbyhop");
|
||||
TCase *TCase_pico_mld_check_hopbyhop = tcase_create("Unit test for pico_mld_check_hopbyhop");
|
||||
TCase *TCase_pico_mld_report_expired = tcase_create("Unit test for pico_mld_report_expired");
|
||||
TCase *TCase_mldt_type_compare = tcase_create("Unit test for mldt_type_compare");
|
||||
TCase *TCase_pico_mld_analyse_packet = tcase_create("Unit test for pico_mld_analyse_packet");
|
||||
TCase *TCase_pico_mld_discard = tcase_create("Unit test for pico_mld_discard");
|
||||
TCase *TCase_pico_mld_compatibility_mode = tcase_create("Unit test for pico_mld_compatibility");
|
||||
TCase *TCase_pico_mld_v1querier_expired = tcase_create("Unit test for pico_mld_v1querier_expired");
|
||||
TCase *TCase_pico_mld_delete_parameter = tcase_create("Unit test for pico_mld_delete_parameter");
|
||||
TCase *TCase_pico_mld_timer_expired = tcase_create("Unit test for pico_mld_timer_expired");
|
||||
TCase *TCase_pico_mld_timer_reset = tcase_create("Unit test for pico_mld_timer_reset");
|
||||
TCase *TCase_pico_mld_send_done = tcase_create("Unit test for pico_mld_send_done");
|
||||
TCase *TCase_pico_mld_is_checksum_valid = tcase_create("Unit test for pico_mld_is_checksum");
|
||||
TCase *TCase_pico_mld_find_parameter = tcase_create("Unit test for pico_mld_find_parameter");
|
||||
TCase *TCase_pico_mld_state_change = tcase_create("Unit test for pico_mld_state_change");
|
||||
TCase *TCase_mld_srst = tcase_create("Unit test for pico_mld_srst");
|
||||
TCase *TCase_mld_stcl = tcase_create("Unit test for pico_mld_stcl");
|
||||
TCase *TCase_pico_mld_process_in = tcase_create("Unit test for pico_mld_process_in");
|
||||
TCase *TCase_pico_mld_send_report = tcase_create("Unit test for pico_mld_send_report");
|
||||
TCase *TCase_mld_stsdifs = tcase_create("Unit test for mld_stsdifs");
|
||||
TCase *TCase_mld_srsf = tcase_create("Unit test for mld_srsf");
|
||||
TCase *TCase_mld_rtimrtct = tcase_create("Unit test for mld_rtimrtct");
|
||||
TCase *TCase_mld_mrsrrt = tcase_create("Unit test for mld_mrsrrt");
|
||||
|
||||
tcase_add_test(TCase_pico_mld_fill_hopbyhop, tc_pico_mld_fill_hopbyhop);
|
||||
suite_add_tcase(s, TCase_pico_mld_fill_hopbyhop);
|
||||
tcase_add_test(TCase_pico_mld_check_hopbyhop, tc_pico_mld_check_hopbyhop);
|
||||
suite_add_tcase(s, TCase_pico_mld_check_hopbyhop);
|
||||
tcase_add_test(TCase_pico_mld_report_expired, tc_pico_mld_report_expired);
|
||||
suite_add_tcase(s, TCase_pico_mld_report_expired);
|
||||
tcase_add_test(TCase_mldt_type_compare, tc_mldt_type_compare);
|
||||
suite_add_tcase(s, TCase_mldt_type_compare);
|
||||
tcase_add_test(TCase_pico_mld_analyse_packet, tc_pico_mld_analyse_packet);
|
||||
suite_add_tcase(s, TCase_pico_mld_analyse_packet);
|
||||
tcase_add_test(TCase_pico_mld_discard, tc_pico_mld_discard);
|
||||
suite_add_tcase(s, TCase_pico_mld_discard);
|
||||
tcase_add_test(TCase_pico_mld_compatibility_mode, tc_pico_mld_compatibility_mode);
|
||||
suite_add_tcase(s, TCase_pico_mld_compatibility_mode);
|
||||
tcase_add_test(TCase_pico_mld_v1querier_expired, tc_pico_mld_v1querier_expired);
|
||||
suite_add_tcase(s, TCase_pico_mld_v1querier_expired);
|
||||
tcase_add_test(TCase_pico_mld_delete_parameter, tc_pico_mld_delete_parameter);
|
||||
suite_add_tcase(s, TCase_pico_mld_delete_parameter);
|
||||
tcase_add_test(TCase_pico_mld_timer_expired, tc_pico_mld_timer_expired);
|
||||
suite_add_tcase(s, TCase_pico_mld_timer_expired);
|
||||
tcase_add_test(TCase_pico_mld_timer_reset, tc_pico_mld_timer_reset);
|
||||
suite_add_tcase(s, TCase_pico_mld_timer_reset);
|
||||
tcase_add_test(TCase_pico_mld_send_done, tc_pico_mld_send_done);
|
||||
suite_add_tcase(s, TCase_pico_mld_send_done);
|
||||
tcase_add_test(TCase_pico_mld_is_checksum_valid, tc_pico_mld_is_checksum_valid);
|
||||
suite_add_tcase(s, TCase_pico_mld_is_checksum_valid);
|
||||
tcase_add_test(TCase_pico_mld_find_parameter, tc_pico_mld_find_parameter);
|
||||
suite_add_tcase(s, TCase_pico_mld_find_parameter);
|
||||
tcase_add_test(TCase_pico_mld_state_change, tc_pico_mld_state_change);
|
||||
suite_add_tcase(s, TCase_pico_mld_state_change);
|
||||
tcase_add_test(TCase_mld_srst, tc_mld_srst);
|
||||
suite_add_tcase(s, TCase_mld_srst);
|
||||
tcase_add_test(TCase_mld_stcl, tc_mld_stcl);
|
||||
suite_add_tcase(s, TCase_mld_stcl);
|
||||
tcase_add_test(TCase_pico_mld_process_in, tc_pico_mld_process_in);
|
||||
suite_add_tcase(s, TCase_pico_mld_process_in);
|
||||
tcase_add_test(TCase_pico_mld_send_report, tc_pico_mld_send_report);
|
||||
suite_add_tcase(s, TCase_pico_mld_send_report);
|
||||
tcase_add_test(TCase_mld_stsdifs, tc_mld_stsdifs);
|
||||
suite_add_tcase(s, TCase_mld_stsdifs);
|
||||
tcase_add_test(TCase_mld_srsf, tc_mld_srsf);
|
||||
suite_add_tcase(s, TCase_mld_srsf);
|
||||
tcase_add_test(TCase_mld_rtimrtct, tc_mld_rtimrtct);
|
||||
suite_add_tcase(s, TCase_mld_rtimrtct);
|
||||
tcase_add_test(TCase_mld_mrsrrt, tc_mld_mrsrrt);
|
||||
suite_add_tcase(s, TCase_mld_mrsrrt);
|
||||
return s;
|
||||
}
|
||||
int main(void)
|
||||
{
|
||||
int fails;
|
||||
Suite *s = pico_suite();
|
||||
SRunner *sr = srunner_create(s);
|
||||
srunner_run_all(sr, CK_NORMAL);
|
||||
fails = srunner_ntests_failed(sr);
|
||||
srunner_free(sr);
|
||||
return fails;
|
||||
}
|
||||
229
kernel/picotcp/test/unit/modunit_pico_protocol.c
Normal file
229
kernel/picotcp/test/unit/modunit_pico_protocol.c
Normal file
@@ -0,0 +1,229 @@
|
||||
#include "pico_protocol.h"
|
||||
#include "pico_tree.h"
|
||||
#include "stack/pico_protocol.c"
|
||||
#include "check.h"
|
||||
|
||||
Suite *pico_suite(void);
|
||||
|
||||
volatile pico_err_t pico_err = 0;
|
||||
|
||||
static int protocol_passby = 0;
|
||||
|
||||
static struct pico_frame f = {
|
||||
.next = NULL
|
||||
};
|
||||
|
||||
static struct pico_queue q = {
|
||||
0
|
||||
};
|
||||
|
||||
static struct pico_tree_node NODE_IN = {
|
||||
0
|
||||
};
|
||||
static struct pico_tree_node NODE_OUT = {
|
||||
0
|
||||
};
|
||||
|
||||
#define KEY_IN 0x0D01
|
||||
#define KEY_OUT 0x0D00
|
||||
|
||||
|
||||
START_TEST(tc_pico_proto_cmp)
|
||||
{
|
||||
struct pico_protocol a = {
|
||||
.hash = 0
|
||||
};
|
||||
struct pico_protocol b = {
|
||||
.hash = 1
|
||||
};
|
||||
fail_if(pico_proto_cmp(&a, &b) >= 0);
|
||||
a.hash = 1;
|
||||
fail_if(pico_proto_cmp(&a, &b) != 0);
|
||||
a.hash = 2;
|
||||
fail_if(pico_proto_cmp(&a, &b) <= 0);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
static int modunit_proto_loop_cb_in(struct pico_protocol *self, struct pico_frame *p)
|
||||
{
|
||||
if (!p)
|
||||
protocol_passby = -1; /* Error! */
|
||||
|
||||
if (!self)
|
||||
protocol_passby = -1; /* Error! */
|
||||
|
||||
if (protocol_passby != 0) /* Ensure that we are called only once. */
|
||||
protocol_passby = -1;
|
||||
|
||||
protocol_passby = KEY_IN;
|
||||
|
||||
return 1; /* One frame processed! */
|
||||
}
|
||||
|
||||
static int modunit_proto_loop_cb_out(struct pico_protocol *self, struct pico_frame *p)
|
||||
{
|
||||
if (!p)
|
||||
protocol_passby = -1; /* Error! */
|
||||
|
||||
if (!self)
|
||||
protocol_passby = -1; /* Error! */
|
||||
|
||||
if (protocol_passby != 0) /* Ensure that we are called only once. */
|
||||
protocol_passby = -1;
|
||||
|
||||
protocol_passby = KEY_OUT;
|
||||
|
||||
return 1; /* One frame processed! */
|
||||
}
|
||||
|
||||
START_TEST(tc_proto_loop_in)
|
||||
{
|
||||
struct pico_protocol p = {
|
||||
.process_in = modunit_proto_loop_cb_in, .q_in = &q
|
||||
};
|
||||
protocol_passby = 0;
|
||||
pico_enqueue(p.q_in, &f);
|
||||
fail_if(proto_loop_in(&p, 1) != 0);
|
||||
fail_if(protocol_passby != KEY_IN);
|
||||
|
||||
/* Try to dequeue from empty queue, get same loop_score */
|
||||
protocol_passby = 0;
|
||||
fail_if(proto_loop_in(&p, 1) != 1);
|
||||
fail_if(protocol_passby != 0);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
|
||||
START_TEST(tc_proto_loop_out)
|
||||
{
|
||||
struct pico_protocol p = {
|
||||
.process_out = modunit_proto_loop_cb_out, .q_out = &q
|
||||
};
|
||||
protocol_passby = 0;
|
||||
pico_enqueue(p.q_out, &f);
|
||||
fail_if(proto_loop_out(&p, 1) != 0);
|
||||
fail_if(protocol_passby != KEY_OUT);
|
||||
|
||||
/* Try to dequeue from empty queue, get same loop_score */
|
||||
protocol_passby = 0;
|
||||
fail_if(proto_loop_out(&p, 1) != 1);
|
||||
fail_if(protocol_passby != 0);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_proto_loop)
|
||||
{
|
||||
struct pico_protocol p = {
|
||||
.process_in = modunit_proto_loop_cb_in,
|
||||
.process_out = modunit_proto_loop_cb_out,
|
||||
.q_in = &q,
|
||||
.q_out = &q
|
||||
};
|
||||
protocol_passby = 0;
|
||||
pico_enqueue(p.q_in, &f);
|
||||
fail_if(proto_loop(&p, 1, PICO_LOOP_DIR_IN) != 0);
|
||||
fail_if(protocol_passby != KEY_IN);
|
||||
|
||||
protocol_passby = 0;
|
||||
pico_enqueue(p.q_out, &f);
|
||||
fail_if(proto_loop(&p, 1, PICO_LOOP_DIR_OUT) != 0);
|
||||
fail_if(protocol_passby != KEY_OUT);
|
||||
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_pico_tree_node)
|
||||
{
|
||||
struct pico_proto_rr rr = {
|
||||
0
|
||||
};
|
||||
rr.node_in = &NODE_IN;
|
||||
rr.node_out = &NODE_OUT;
|
||||
fail_unless(roundrobin_init(&rr, PICO_LOOP_DIR_IN) == &NODE_IN);
|
||||
fail_unless(roundrobin_init(&rr, PICO_LOOP_DIR_OUT) == &NODE_OUT);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_roundrobin_end)
|
||||
{
|
||||
struct pico_proto_rr rr;
|
||||
roundrobin_end(&rr, PICO_LOOP_DIR_IN, &NODE_IN);
|
||||
fail_if(rr.node_in != &NODE_IN);
|
||||
roundrobin_end(&rr, PICO_LOOP_DIR_OUT, &NODE_OUT);
|
||||
fail_if(rr.node_out != &NODE_OUT);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_pico_protocol_generic_loop)
|
||||
{
|
||||
struct pico_proto_rr rr = {
|
||||
0
|
||||
};
|
||||
int ret = 0;
|
||||
|
||||
rr.node_in = &NODE_IN;
|
||||
rr.node_out = &NODE_OUT;
|
||||
ret = pico_protocol_generic_loop(&rr, 0, PICO_LOOP_DIR_IN);
|
||||
|
||||
fail_if(ret != 0);
|
||||
|
||||
pico_protocols_loop(0);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
|
||||
START_TEST(tc_proto_layer_rr_reset)
|
||||
{
|
||||
struct pico_proto_rr rr;
|
||||
rr.node_in = &NODE_IN;
|
||||
rr.node_out = &NODE_OUT;
|
||||
proto_layer_rr_reset(&rr);
|
||||
fail_if(rr.node_in != NULL);
|
||||
fail_if(rr.node_out != NULL);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
|
||||
Suite *pico_suite(void)
|
||||
{
|
||||
Suite *s = suite_create("pico_protocol.c");
|
||||
|
||||
TCase *TCase_pico_proto_cmp = tcase_create("Unit test for pico_proto_cmp");
|
||||
TCase *TCase_proto_loop_in = tcase_create("Unit test for proto_loop_in");
|
||||
TCase *TCase_proto_loop_out = tcase_create("Unit test for proto_loop_out");
|
||||
TCase *TCase_proto_loop = tcase_create("Unit test for proto_loop");
|
||||
TCase *TCase_pico_tree_node = tcase_create("Unit test for pico_tree_node");
|
||||
TCase *TCase_roundrobin_end = tcase_create("Unit test for roundrobin_end");
|
||||
TCase *TCase_pico_protocol_generic_loop = tcase_create("Unit test for pico_protocol_generic_loop");
|
||||
TCase *TCase_proto_layer_rr_reset = tcase_create("Unit test for proto_layer_rr_reset");
|
||||
|
||||
|
||||
tcase_add_test(TCase_pico_proto_cmp, tc_pico_proto_cmp);
|
||||
suite_add_tcase(s, TCase_pico_proto_cmp);
|
||||
tcase_add_test(TCase_proto_loop_in, tc_proto_loop_in);
|
||||
suite_add_tcase(s, TCase_proto_loop_in);
|
||||
tcase_add_test(TCase_proto_loop_out, tc_proto_loop_out);
|
||||
suite_add_tcase(s, TCase_proto_loop_out);
|
||||
tcase_add_test(TCase_proto_loop, tc_proto_loop);
|
||||
suite_add_tcase(s, TCase_proto_loop);
|
||||
tcase_add_test(TCase_pico_tree_node, tc_pico_tree_node);
|
||||
suite_add_tcase(s, TCase_pico_tree_node);
|
||||
tcase_add_test(TCase_roundrobin_end, tc_roundrobin_end);
|
||||
suite_add_tcase(s, TCase_roundrobin_end);
|
||||
tcase_add_test(TCase_pico_protocol_generic_loop, tc_pico_protocol_generic_loop);
|
||||
suite_add_tcase(s, TCase_pico_protocol_generic_loop);
|
||||
tcase_add_test(TCase_proto_layer_rr_reset, tc_proto_layer_rr_reset);
|
||||
suite_add_tcase(s, TCase_proto_layer_rr_reset);
|
||||
return s;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int fails;
|
||||
Suite *s = pico_suite();
|
||||
SRunner *sr = srunner_create(s);
|
||||
srunner_run_all(sr, CK_NORMAL);
|
||||
fails = srunner_ntests_failed(sr);
|
||||
srunner_free(sr);
|
||||
return fails;
|
||||
}
|
||||
428
kernel/picotcp/test/unit/modunit_pico_sntp_client.c
Normal file
428
kernel/picotcp/test/unit/modunit_pico_sntp_client.c
Normal file
@@ -0,0 +1,428 @@
|
||||
#include "pico_sntp_client.h"
|
||||
#include "modules/pico_sntp_client.c"
|
||||
#include "check.h"
|
||||
#include "pico_socket.h"
|
||||
/* Mocking functions, variables, ... */
|
||||
volatile pico_time pico_tick = 0ull;
|
||||
volatile pico_err_t pico_err = 0;
|
||||
|
||||
Suite *pico_suite(void);
|
||||
void cb_synced(pico_err_t status);
|
||||
|
||||
/* Used in pico_sntp_sync_start */
|
||||
struct pico_socket *pico_socket_open(uint16_t net, uint16_t proto, void (*wakeup)(uint16_t ev, struct pico_socket *s))
|
||||
{
|
||||
struct pico_socket *sock = PICO_ZALLOC(sizeof(struct pico_socket));
|
||||
(void) net;
|
||||
(void) proto;
|
||||
(void) wakeup;
|
||||
fail_unless (sock != NULL);
|
||||
return sock;
|
||||
}
|
||||
|
||||
/* Used in pico_sntp_sync_start */
|
||||
int pico_socket_bind(struct pico_socket *s, void *local_addr, uint16_t *port)
|
||||
{
|
||||
(void) s;
|
||||
(void) local_addr;
|
||||
(void) port;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Used in pico_sntp_sync_start */
|
||||
int pico_socket_close(struct pico_socket *s)
|
||||
{
|
||||
(void) s;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Used in pico_sntp_send */
|
||||
int8_t pico_socket_del(struct pico_socket *s)
|
||||
{
|
||||
(void) s;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Used in dnsCallback */
|
||||
int pico_string_to_ipv4(const char *ipstr, uint32_t *ip)
|
||||
{
|
||||
(void) ipstr;
|
||||
(void) ip;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Used in dnsCallback */
|
||||
int pico_string_to_ipv6(const char *ipstr, uint8_t *ip)
|
||||
{
|
||||
(void) ipstr;
|
||||
(void) ip;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Used in pico_sntp_sync_start_ipv4 */
|
||||
int pico_ipv4_to_string(char* ipbuf, const uint32_t ip)
|
||||
{
|
||||
(void) ipbuf;
|
||||
(void) ip;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Used in pico_sntp_sync_start_ipv6 */
|
||||
int pico_ipv6_to_string(char* ipbuf, const uint8_t ip[PICO_SIZE_IP6])
|
||||
{
|
||||
(void) ipbuf;
|
||||
(void) ip;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Used in pico_sntp_client_wakeup */
|
||||
int pico_socket_recvfrom(struct pico_socket *s, void *buf, int len, void *orig, uint16_t *remote_port)
|
||||
{
|
||||
(void) s;
|
||||
(void) buf;
|
||||
(void) len;
|
||||
(void) orig;
|
||||
(void) remote_port;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Used in pico_sntp_send */
|
||||
int pico_socket_sendto(struct pico_socket *s, const void *buf, int len, void *dst, uint16_t remote_port)
|
||||
{
|
||||
(void) s;
|
||||
(void) buf;
|
||||
(void) len;
|
||||
(void) dst;
|
||||
(void) remote_port;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Used in pico_sntp_sync_start_dns_ipv4, not tested */
|
||||
int pico_dns_client_getaddr(const char *url, void (*callback)(char *ip, void *arg), void *arg)
|
||||
{
|
||||
(void) url;
|
||||
(void) callback;
|
||||
(void) arg;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Used in pico_sntp_sync_start_dns_ipv6, not tested */
|
||||
int pico_dns_client_getaddr6(const char *url, void (*callback)(char *, void *), void *arg)
|
||||
{
|
||||
(void) url;
|
||||
(void) callback;
|
||||
(void) arg;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Used in pico_sntp_parse */
|
||||
void cb_synced(pico_err_t status)
|
||||
{
|
||||
(void) status;
|
||||
|
||||
}
|
||||
|
||||
/* Used in pico_sntp_send */
|
||||
static uint32_t timers_added = 0;
|
||||
uint32_t pico_timer_add(pico_time expire, void (*timer)(pico_time, void *), void *arg)
|
||||
{
|
||||
(void) expire;
|
||||
(void) timer;
|
||||
(void) arg;
|
||||
return ++timers_added;
|
||||
}
|
||||
|
||||
/* Used in pico_sntp_cleanup */
|
||||
void pico_timer_cancel(uint32_t t)
|
||||
{
|
||||
IGNORE_PARAMETER(t);
|
||||
}
|
||||
|
||||
START_TEST(tc_timestamp_convert)
|
||||
{
|
||||
struct pico_sntp_ts ts;
|
||||
struct pico_timeval tv;
|
||||
pico_time delay = 0ull;
|
||||
int ret = 0;
|
||||
|
||||
/* Input is all zero */
|
||||
ts.sec = long_be(0ul);
|
||||
ts.frac = long_be(0ul);
|
||||
ret = timestamp_convert(&ts, &tv, delay);
|
||||
ck_assert(ret == -1);
|
||||
ck_assert(tv.tv_sec == 0);
|
||||
ck_assert(tv.tv_msec == 0);
|
||||
|
||||
/* Minimum input*/
|
||||
ts.sec = long_be(SNTP_UNIX_OFFSET + 1390000000ul);
|
||||
ts.frac = long_be(4310344ul); /* MIN value: 1msec */
|
||||
ret = timestamp_convert(&ts, &tv, delay);
|
||||
ck_assert(ret == 0);
|
||||
fail_unless(tv.tv_sec == 1390000000);
|
||||
fail_unless(tv.tv_msec == 1);
|
||||
|
||||
/* Intermediate input */
|
||||
ts.sec = long_be(SNTP_UNIX_OFFSET + 1390000000ul);
|
||||
ts.frac = long_be(3865470566ul); /* value: 899msec */
|
||||
ret = timestamp_convert(&ts, &tv, delay);
|
||||
ck_assert(ret == 0);
|
||||
fail_unless(tv.tv_sec == 1390000000);
|
||||
fail_unless(tv.tv_msec == 900);
|
||||
|
||||
/* Maximum input */
|
||||
ts.sec = long_be(SNTP_UNIX_OFFSET + 1390000000ul);
|
||||
ts.frac = long_be(4294967295ul); /* MAX value: 999msec */
|
||||
ret = timestamp_convert(&ts, &tv, delay);
|
||||
ck_assert(ret == 0);
|
||||
fail_unless(tv.tv_sec == 1390000001);
|
||||
fail_unless(tv.tv_msec == 0);
|
||||
|
||||
/* Intermediate input with delay */
|
||||
ts.sec = long_be(SNTP_UNIX_OFFSET + 1390000000ul);
|
||||
ts.frac = long_be(3865470566ul); /* value: 899msec */
|
||||
delay = 200ull;
|
||||
ret = timestamp_convert(&ts, &tv, delay);
|
||||
ck_assert(ret == 0);
|
||||
fail_unless(tv.tv_sec == 1390000001);
|
||||
fail_unless(tv.tv_msec == 100);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_sntp_cleanup)
|
||||
{
|
||||
struct sntp_server_ns_cookie *ck;
|
||||
struct pico_socket *sock;
|
||||
ck = PICO_ZALLOC(sizeof(struct sntp_server_ns_cookie));
|
||||
fail_unless (ck != NULL);
|
||||
ck->hostname = PICO_ZALLOC(sizeof(char) * 5);
|
||||
fail_unless (ck->hostname != NULL);
|
||||
ck->stamp = 0ull;
|
||||
ck->cb_synced = cb_synced;
|
||||
|
||||
sock = pico_socket_open(0, 0, &pico_sntp_client_wakeup);
|
||||
ck->sock = sock;
|
||||
sock->priv = ck;
|
||||
|
||||
|
||||
pico_sntp_cleanup(ck, PICO_ERR_NOERR);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_sntp_parse)
|
||||
{
|
||||
/* TODO: test this: static void pico_sntp_parse(char *buf, struct sntp_server_ns_cookie *ck) */
|
||||
struct sntp_server_ns_cookie *ck;
|
||||
struct pico_socket *sock;
|
||||
struct pico_sntp_header header = {
|
||||
0
|
||||
};
|
||||
|
||||
ck = PICO_ZALLOC(sizeof(struct sntp_server_ns_cookie));
|
||||
fail_unless (ck != NULL);
|
||||
ck->hostname = PICO_ZALLOC(sizeof(char) * 5);
|
||||
fail_unless (ck->hostname != NULL);
|
||||
ck->stamp = 0ull;
|
||||
ck->cb_synced = cb_synced;
|
||||
|
||||
sock = pico_socket_open(0, 0, &pico_sntp_client_wakeup);
|
||||
ck->sock = sock;
|
||||
sock->priv = ck;
|
||||
|
||||
header.mode = 4; /* server mode */
|
||||
header.vn = 4; /* sntp version 4 */
|
||||
header.stratum = 1; /* primary reference */
|
||||
header.trs_ts.sec = long_be(SNTP_UNIX_OFFSET + 1390000000ul);
|
||||
header.trs_ts.frac = long_be(3865470566ul); /* value: 899msec */
|
||||
|
||||
fail_if(pico_sntp_parse((char *) &header, NULL) == 0);
|
||||
fail_if(pico_sntp_parse((char *) &header, ck) != 0);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_sntp_client_wakeup)
|
||||
{
|
||||
/* TODO: test this: static void pico_sntp_client_wakeup(uint16_t ev, struct pico_socket *s) */
|
||||
uint16_t event = PICO_SOCK_EV_ERR;
|
||||
struct sntp_server_ns_cookie *ck;
|
||||
struct pico_socket *sock;
|
||||
ck = PICO_ZALLOC(sizeof(struct sntp_server_ns_cookie));
|
||||
fail_unless (ck != NULL);
|
||||
ck->hostname = PICO_ZALLOC(sizeof(char) * 5);
|
||||
fail_unless (ck->hostname != NULL);
|
||||
ck->stamp = 0ull;
|
||||
ck->cb_synced = cb_synced;
|
||||
|
||||
sock = pico_socket_open(0, 0, &pico_sntp_client_wakeup);
|
||||
ck->sock = sock;
|
||||
sock->priv = ck;
|
||||
|
||||
ck->cb_synced = cb_synced;
|
||||
printf("Started wakeup unit test\n");
|
||||
|
||||
pico_sntp_client_wakeup(event, sock);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_sntp_receive_timeout)
|
||||
{
|
||||
struct sntp_server_ns_cookie *ck;
|
||||
struct pico_socket *sock;
|
||||
ck = PICO_ZALLOC(sizeof(struct sntp_server_ns_cookie));
|
||||
fail_unless (ck != NULL);
|
||||
ck->hostname = PICO_ZALLOC(sizeof(char) * 5);
|
||||
fail_unless (ck->hostname != NULL);
|
||||
ck->stamp = 0ull;
|
||||
ck->cb_synced = cb_synced;
|
||||
|
||||
sock = pico_socket_open(0, 0, &pico_sntp_client_wakeup);
|
||||
ck->sock = sock;
|
||||
sock->priv = ck;
|
||||
sntp_receive_timeout(0ull, ck);
|
||||
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_sntp_send)
|
||||
{
|
||||
/* TODO: test this: static void pico_sntp_send(struct pico_socket *sock, union pico_address *dst) */
|
||||
struct pico_socket sock = {
|
||||
0
|
||||
};
|
||||
union pico_address dst;
|
||||
struct sntp_server_ns_cookie ck = {
|
||||
0
|
||||
};
|
||||
sock.priv = &ck;
|
||||
|
||||
pico_sntp_send(&sock, &dst);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_dnsCallback)
|
||||
{
|
||||
/* TODO: test this: static void dnsCallback(char *ip, void *arg) */
|
||||
char ip[] = "198.123.30.132";
|
||||
struct sntp_server_ns_cookie *ck;
|
||||
ck = PICO_ZALLOC(sizeof(struct sntp_server_ns_cookie));
|
||||
|
||||
dnsCallback(ip, ck);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_sntp_sync)
|
||||
{
|
||||
const char *sntp_server= "ntp.nasa.gov";
|
||||
|
||||
fail_if(pico_sntp_sync(NULL, cb_synced) == 0);
|
||||
fail_if(pico_err != PICO_ERR_EINVAL);
|
||||
|
||||
fail_if(pico_sntp_sync(sntp_server, NULL) == 0);
|
||||
fail_if(pico_err != PICO_ERR_EINVAL);
|
||||
|
||||
fail_if(pico_sntp_sync(sntp_server, cb_synced) != 0);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_sntp_sync_ip)
|
||||
{
|
||||
union pico_address sntp_addr = { .ip4.addr = 0ul };
|
||||
|
||||
fail_if(pico_sntp_sync_ip(NULL, cb_synced) == 0);
|
||||
fail_if(pico_err != PICO_ERR_EINVAL);
|
||||
|
||||
fail_if(pico_sntp_sync_ip(&sntp_addr, NULL) == 0);
|
||||
fail_if(pico_err != PICO_ERR_EINVAL);
|
||||
|
||||
fail_if(pico_sntp_sync_ip(&sntp_addr, cb_synced) != 0);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_sntp_sync_start)
|
||||
{
|
||||
struct sntp_server_ns_cookie ck = { 0 };
|
||||
union pico_address sntp_addr = { .ip4.addr= 0ul };
|
||||
|
||||
fail_if(pico_sntp_sync_start(&ck, &sntp_addr) != 0);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_sntp_sync_start_dns_ipv4)
|
||||
{
|
||||
const char *sntp_server = "ntp.nasa.gov";
|
||||
|
||||
fail_if(pico_sntp_sync_start_dns_ipv4(sntp_server, cb_synced) != 0);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_sntp_sync_start_dns_ipv6)
|
||||
{
|
||||
const char *sntp_server = "ntp.nasa.gov";
|
||||
|
||||
fail_if(pico_sntp_sync_start_dns_ipv6(sntp_server, cb_synced) != 0);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_sntp_sync_start_ipv4)
|
||||
{
|
||||
union pico_address sntp_addr = { .ip4.addr = 0};
|
||||
|
||||
fail_if(pico_sntp_sync_start_ipv4(&sntp_addr, cb_synced) != 0);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_sntp_sync_start_ipv6)
|
||||
{
|
||||
union pico_address sntp_addr = { .ip6.addr = { 0 } };
|
||||
|
||||
fail_if(pico_sntp_sync_start_ipv6(&sntp_addr, cb_synced) != 0);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
Suite *pico_suite(void)
|
||||
{
|
||||
Suite *s = suite_create("PicoTCP");
|
||||
|
||||
TCase *TCase_timestamp_convert = tcase_create("Unit test for pico_timeval");
|
||||
TCase *TCase_pico_sntp_cleanup = tcase_create("Unit test for pico_sntp_cleanup");
|
||||
TCase *TCase_pico_sntp_send = tcase_create("Unit test for pico_sntp_send");
|
||||
TCase *TCase_pico_sntp_parse = tcase_create("Unit test for pico_sntp_parse");
|
||||
TCase *TCase_pico_sntp_client_wakeup = tcase_create("Unit test for pico_sntp_client_wakeup");
|
||||
TCase *TCase_sntp_receive_timeout = tcase_create("Unit test for sntp_receive_timeout");
|
||||
TCase *TCase_dnsCallback = tcase_create("Unit test for dnsCallback");
|
||||
TCase *TCase_pico_sntp_sync = tcase_create("Unit test for pico_sntp_sync");
|
||||
TCase *TCase_pico_sntp_sync_ip = tcase_create("Unit test for pico_sntp_sync_ip");
|
||||
TCase *TCase_pico_sntp_sync_start = tcase_create("Unit test for pico_sntp_sync_start");
|
||||
TCase *TCase_pico_sntp_sync_start_dns_ipv4 = tcase_create("Unit test for pico_sntp_sync_start_dns_ipv4");
|
||||
TCase *TCase_pico_sntp_sync_start_dns_ipv6 = tcase_create("Unit test for pico_sntp_sync_start_dns_ipv6");
|
||||
TCase *TCase_pico_sntp_sync_start_ipv4 = tcase_create("Unit test for pico_sntp_sync_start_ipv4");
|
||||
TCase *TCase_pico_sntp_sync_start_ipv6 = tcase_create("Unit test for pico_sntp_sync_start_ipv6");
|
||||
|
||||
|
||||
tcase_add_test(TCase_timestamp_convert, tc_timestamp_convert);
|
||||
suite_add_tcase(s, TCase_timestamp_convert);
|
||||
tcase_add_test(TCase_pico_sntp_cleanup, tc_pico_sntp_cleanup);
|
||||
suite_add_tcase(s, TCase_pico_sntp_cleanup);
|
||||
tcase_add_test(TCase_pico_sntp_parse, tc_pico_sntp_parse);
|
||||
suite_add_tcase(s, TCase_pico_sntp_parse);
|
||||
tcase_add_test(TCase_pico_sntp_client_wakeup, tc_pico_sntp_client_wakeup);
|
||||
suite_add_tcase(s, TCase_pico_sntp_client_wakeup);
|
||||
tcase_add_test(TCase_sntp_receive_timeout, tc_sntp_receive_timeout);
|
||||
suite_add_tcase(s, TCase_sntp_receive_timeout);
|
||||
tcase_add_test(TCase_pico_sntp_send, tc_pico_sntp_send);
|
||||
suite_add_tcase(s, TCase_pico_sntp_send);
|
||||
tcase_add_test(TCase_dnsCallback, tc_dnsCallback);
|
||||
suite_add_tcase(s, TCase_dnsCallback);
|
||||
tcase_add_test(TCase_pico_sntp_sync, tc_pico_sntp_sync);
|
||||
suite_add_tcase(s, TCase_pico_sntp_sync);
|
||||
tcase_add_test(TCase_pico_sntp_sync_ip, tc_pico_sntp_sync_ip);
|
||||
suite_add_tcase(s, TCase_pico_sntp_sync_ip);
|
||||
tcase_add_test(TCase_pico_sntp_sync_start, tc_pico_sntp_sync_start);
|
||||
suite_add_tcase(s, TCase_pico_sntp_sync_start);
|
||||
tcase_add_test(TCase_pico_sntp_sync_start_dns_ipv4, tc_pico_sntp_sync_start_dns_ipv4);
|
||||
suite_add_tcase(s, TCase_pico_sntp_sync_start_dns_ipv4);
|
||||
tcase_add_test(TCase_pico_sntp_sync_start_dns_ipv6, tc_pico_sntp_sync_start_dns_ipv6);
|
||||
suite_add_tcase(s, TCase_pico_sntp_sync_start_dns_ipv6);
|
||||
tcase_add_test(TCase_pico_sntp_sync_start_ipv4, tc_pico_sntp_sync_start_ipv4);
|
||||
suite_add_tcase(s, TCase_pico_sntp_sync_start_ipv4);
|
||||
tcase_add_test(TCase_pico_sntp_sync_start_ipv6, tc_pico_sntp_sync_start_ipv6);
|
||||
suite_add_tcase(s, TCase_pico_sntp_sync_start_ipv6);
|
||||
return s;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int fails;
|
||||
Suite *s = pico_suite();
|
||||
SRunner *sr = srunner_create(s);
|
||||
srunner_run_all(sr, CK_NORMAL);
|
||||
fails = srunner_ntests_failed(sr);
|
||||
srunner_free(sr);
|
||||
return fails;
|
||||
}
|
||||
145
kernel/picotcp/test/unit/modunit_pico_stack.c
Normal file
145
kernel/picotcp/test/unit/modunit_pico_stack.c
Normal file
@@ -0,0 +1,145 @@
|
||||
#include "pico_config.h"
|
||||
#include "pico_frame.h"
|
||||
#include "pico_device.h"
|
||||
#include "pico_protocol.h"
|
||||
#include "pico_stack.h"
|
||||
#include "pico_addressing.h"
|
||||
#include "pico_dns_client.h"
|
||||
#include "pico_eth.h"
|
||||
#include "pico_arp.h"
|
||||
#include "pico_ipv4.h"
|
||||
#include "pico_ipv6.h"
|
||||
#include "pico_icmp4.h"
|
||||
#include "pico_igmp.h"
|
||||
#include "pico_udp.h"
|
||||
#include "pico_tcp.h"
|
||||
#include "pico_socket.h"
|
||||
#include "heap.h"
|
||||
#include "stack/pico_stack.c"
|
||||
#include "check.h"
|
||||
|
||||
|
||||
Suite *pico_suite(void);
|
||||
void fake_timer(pico_time __attribute__((unused)) now, void __attribute__((unused)) *n);
|
||||
|
||||
START_TEST(tc_pico_ll_receive)
|
||||
{
|
||||
/* TODO: test this: static int32_t pico_ll_receive(struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_ll_check_bcast)
|
||||
{
|
||||
/* TODO: test this: static void pico_ll_check_bcast(struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_destination_is_bcast)
|
||||
{
|
||||
/* TODO: test this: static int destination_is_bcast(struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_destination_is_mcast)
|
||||
{
|
||||
/* TODO: test this: static int destination_is_mcast(struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_eth)
|
||||
{
|
||||
/* TODO: test this: static struct pico_eth *pico_ethernet_mcast_translate(struct pico_frame *f, uint8_t *pico_mcast_mac) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_ethsend_local)
|
||||
{
|
||||
/* TODO: test this: static int32_t pico_ethsend_local(struct pico_frame *f, struct pico_eth_hdr *hdr, int *ret) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_ethsend_bcast)
|
||||
{
|
||||
/* TODO: test this: static int32_t pico_ethsend_bcast(struct pico_frame *f, int *ret) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_ethsend_dispatch)
|
||||
{
|
||||
/* TODO: test this: static int32_t pico_ethsend_dispatch(struct pico_frame *f, int *ret) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_calc_score)
|
||||
{
|
||||
/* TODO: test this: static int calc_score(int *score, int *index, int avg[][PROTO_DEF_AVG_NR], int *ret) */
|
||||
}
|
||||
END_TEST
|
||||
|
||||
#ifdef PICO_FAULTY
|
||||
void fake_timer(pico_time __attribute__((unused)) now, void __attribute__((unused)) *n)
|
||||
{
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
START_TEST(tc_stack_generic)
|
||||
{
|
||||
#ifdef PICO_FAULTY
|
||||
printf("Testing with faulty memory in pico_stack_init (11)\n");
|
||||
pico_set_mm_failure(13);
|
||||
fail_if(pico_stack_init() != -1);
|
||||
#endif
|
||||
pico_stack_init();
|
||||
#ifdef PICO_FAULTY
|
||||
printf("Testing with faulty memory in pico_timer_add (1)\n");
|
||||
pico_set_mm_failure(1);
|
||||
fail_if(pico_timer_add(0, fake_timer, NULL) != 0);
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
END_TEST
|
||||
|
||||
|
||||
Suite *pico_suite(void)
|
||||
{
|
||||
Suite *s = suite_create("PicoTCP");
|
||||
|
||||
TCase *TCase_pico_ll_receive = tcase_create("Unit test for pico_ll_receive");
|
||||
TCase *TCase_pico_ll_check_bcast = tcase_create("Unit test for pico_ll_check_bcast");
|
||||
TCase *TCase_destination_is_bcast = tcase_create("Unit test for destination_is_bcast");
|
||||
TCase *TCase_destination_is_mcast = tcase_create("Unit test for destination_is_mcast");
|
||||
TCase *TCase_pico_eth = tcase_create("Unit test for pico_eth");
|
||||
TCase *TCase_pico_ethsend_local = tcase_create("Unit test for pico_ethsend_local");
|
||||
TCase *TCase_pico_ethsend_bcast = tcase_create("Unit test for pico_ethsend_bcast");
|
||||
TCase *TCase_pico_ethsend_dispatch = tcase_create("Unit test for pico_ethsend_dispatch");
|
||||
TCase *TCase_calc_score = tcase_create("Unit test for calc_score");
|
||||
TCase *TCase_stack_generic = tcase_create("GENERIC stack initialization unit test");
|
||||
|
||||
|
||||
tcase_add_test(TCase_pico_ll_receive, tc_pico_ll_receive);
|
||||
suite_add_tcase(s, TCase_pico_ll_receive);
|
||||
tcase_add_test(TCase_pico_ll_check_bcast, tc_pico_ll_check_bcast);
|
||||
suite_add_tcase(s, TCase_pico_ll_check_bcast);
|
||||
tcase_add_test(TCase_destination_is_bcast, tc_destination_is_bcast);
|
||||
suite_add_tcase(s, TCase_destination_is_bcast);
|
||||
tcase_add_test(TCase_destination_is_mcast, tc_destination_is_mcast);
|
||||
suite_add_tcase(s, TCase_destination_is_mcast);
|
||||
tcase_add_test(TCase_pico_eth, tc_pico_eth);
|
||||
suite_add_tcase(s, TCase_pico_eth);
|
||||
tcase_add_test(TCase_pico_ethsend_local, tc_pico_ethsend_local);
|
||||
suite_add_tcase(s, TCase_pico_ethsend_local);
|
||||
tcase_add_test(TCase_pico_ethsend_bcast, tc_pico_ethsend_bcast);
|
||||
suite_add_tcase(s, TCase_pico_ethsend_bcast);
|
||||
tcase_add_test(TCase_pico_ethsend_dispatch, tc_pico_ethsend_dispatch);
|
||||
suite_add_tcase(s, TCase_pico_ethsend_dispatch);
|
||||
tcase_add_test(TCase_calc_score, tc_calc_score);
|
||||
suite_add_tcase(s, TCase_calc_score);
|
||||
tcase_add_test(TCase_stack_generic, tc_stack_generic);
|
||||
suite_add_tcase(s, TCase_stack_generic);
|
||||
return s;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int fails;
|
||||
Suite *s = pico_suite();
|
||||
SRunner *sr = srunner_create(s);
|
||||
srunner_run_all(sr, CK_NORMAL);
|
||||
fails = srunner_ntests_failed(sr);
|
||||
srunner_free(sr);
|
||||
return fails;
|
||||
}
|
||||
59
kernel/picotcp/test/unit/modunit_pico_strings.c
Normal file
59
kernel/picotcp/test/unit/modunit_pico_strings.c
Normal file
@@ -0,0 +1,59 @@
|
||||
#include "modules/pico_strings.c"
|
||||
#include "check.h"
|
||||
|
||||
Suite *pico_suite(void);
|
||||
|
||||
START_TEST(tc_get_string_terminator_position)
|
||||
{
|
||||
char buf[6] = "unit";
|
||||
get_string_terminator_position(NULL,0);
|
||||
fail_if(get_string_terminator_position(buf,2) != 0);
|
||||
fail_if(get_string_terminator_position(buf,6) != &buf[4]);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_strncasecmp)
|
||||
{
|
||||
fail_if(pico_strncasecmp("unit","UNIT",4) != 0);
|
||||
fail_if(pico_strncasecmp("unit1","UNIT2",5) != -1);
|
||||
fail_if(pico_strncasecmp("unit2","UNIT1",5) != 1);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_num2string)
|
||||
{
|
||||
char buf[20];
|
||||
fail_if(num2string(-1,NULL,1) != -1);
|
||||
fail_if(num2string(1,NULL,1) != -1);
|
||||
fail_if(num2string(1,buf,1) != -1);
|
||||
fail_if(num2string(1,buf,3) != 2);
|
||||
fail_if(num2string(11,buf,3) != 3);
|
||||
fail_if(num2string(112,buf,4) != 4);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
Suite *pico_suite(void)
|
||||
{
|
||||
Suite *s = suite_create("PicoTCP");
|
||||
|
||||
TCase *TCase_get_string_terminator_position = tcase_create("Unit test for get_string_terminator_position");
|
||||
TCase *TCase_num2string = tcase_create("Unit test for num2string");
|
||||
TCase *TCase_pico_strncasecmp = tcase_create("Unit test for pico_strncasecmp");
|
||||
|
||||
tcase_add_test(TCase_get_string_terminator_position, tc_get_string_terminator_position);
|
||||
suite_add_tcase(s, TCase_get_string_terminator_position);
|
||||
tcase_add_test(TCase_num2string,tc_num2string);
|
||||
suite_add_tcase(s, TCase_num2string);
|
||||
tcase_add_test(TCase_pico_strncasecmp,tc_pico_strncasecmp);
|
||||
suite_add_tcase(s, TCase_pico_strncasecmp);
|
||||
|
||||
return s;
|
||||
}
|
||||
int main(void)
|
||||
{
|
||||
int fails;
|
||||
Suite *s = pico_suite();
|
||||
SRunner *sr = srunner_create(s);
|
||||
srunner_run_all(sr, CK_NORMAL);
|
||||
fails = srunner_ntests_failed(sr);
|
||||
srunner_free(sr);
|
||||
return fails;
|
||||
}
|
||||
863
kernel/picotcp/test/unit/modunit_pico_tcp.c
Normal file
863
kernel/picotcp/test/unit/modunit_pico_tcp.c
Normal file
@@ -0,0 +1,863 @@
|
||||
#include "pico_tcp.h"
|
||||
#include "pico_config.h"
|
||||
#include "pico_eth.h"
|
||||
#include "pico_socket.h"
|
||||
#include "pico_stack.h"
|
||||
#include "pico_socket.h"
|
||||
#include "pico_queue.h"
|
||||
#include "pico_tree.h"
|
||||
#include "modules/pico_tcp.c"
|
||||
#include "check.h"
|
||||
|
||||
Suite *pico_suite(void);
|
||||
|
||||
static uint32_t timers_added = 0;
|
||||
uint32_t pico_timer_add(pico_time expire, void (*timer)(pico_time, void *), void *arg)
|
||||
{
|
||||
IGNORE_PARAMETER(expire);
|
||||
IGNORE_PARAMETER(timer);
|
||||
IGNORE_PARAMETER(arg);
|
||||
return ++timers_added;
|
||||
}
|
||||
|
||||
START_TEST(tc_input_segment_compare)
|
||||
{
|
||||
struct tcp_input_segment A = {
|
||||
.seq = 0xFFFFFFFF
|
||||
};
|
||||
struct tcp_input_segment B = {
|
||||
.seq = 0xFFFFFFFe
|
||||
};
|
||||
struct tcp_input_segment a = {
|
||||
.seq = 0x01
|
||||
};
|
||||
struct tcp_input_segment b = {
|
||||
.seq = 0x02
|
||||
};
|
||||
|
||||
fail_if(input_segment_compare(&A, &B) <= 0);
|
||||
fail_if(input_segment_compare(&a, &b) >= 0);
|
||||
fail_if(input_segment_compare(&A, &b) >= 0);
|
||||
fail_if(input_segment_compare(&A, &A) != 0);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_input_segment)
|
||||
{
|
||||
/* TODO: test this: static struct tcp_input_segment *segment_from_frame(struct pico_frame *f) */
|
||||
struct pico_frame *f = pico_frame_alloc(60);
|
||||
struct tcp_input_segment *seg;
|
||||
|
||||
fail_if(!f);
|
||||
f->payload = f->start;
|
||||
f->payload_len = 60;
|
||||
f->transport_hdr = f->payload;
|
||||
f->transport_len = (uint16_t)(f->payload_len - 40);
|
||||
memset(f->payload, 'c', f->payload_len);
|
||||
((struct pico_tcp_hdr *)((f)->transport_hdr))->seq = long_be(0xdeadbeef);
|
||||
|
||||
seg = segment_from_frame(f);
|
||||
fail_if(!seg);
|
||||
fail_if(seg->seq != 0xdeadbeef);
|
||||
fail_if(seg->payload_len != f->payload_len);
|
||||
fail_if(memcmp(seg->payload, f->payload, f->payload_len) != 0);
|
||||
|
||||
#ifdef PICO_FAULTY
|
||||
printf("Testing with faulty memory in segment_from_frame (1)\n");
|
||||
pico_set_mm_failure(1);
|
||||
seg = segment_from_frame(f);
|
||||
fail_if(seg);
|
||||
|
||||
printf("Testing with faulty memory in segment_from_frame (2)\n");
|
||||
pico_set_mm_failure(2);
|
||||
seg = segment_from_frame(f);
|
||||
fail_if(seg);
|
||||
#endif
|
||||
printf("Testing segment_from_frame with empty payload\n");
|
||||
f->payload_len = 0;
|
||||
seg = segment_from_frame(f);
|
||||
fail_if(seg);
|
||||
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_segment_compare)
|
||||
{
|
||||
/* TODO: test this: static int segment_compare(void *ka, void *kb) */
|
||||
struct pico_frame *a = pico_frame_alloc(40);
|
||||
struct pico_frame *b = pico_frame_alloc(60);
|
||||
a->transport_hdr = a->start;
|
||||
b->transport_hdr = b->start;
|
||||
|
||||
((struct pico_tcp_hdr *)((b)->transport_hdr))->seq = long_be(0xaa00);
|
||||
((struct pico_tcp_hdr *)((a)->transport_hdr))->seq = long_be(0xffffaa00);
|
||||
fail_if(segment_compare(a, b) >= 0);
|
||||
fail_if(segment_compare(a, a) != 0);
|
||||
|
||||
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_discard_all_segments)
|
||||
{
|
||||
struct pico_socket_tcp *t = (struct pico_socket_tcp *)pico_tcp_open(PICO_PROTO_IPV4);
|
||||
struct pico_frame *f = pico_frame_alloc(80);
|
||||
struct tcp_input_segment *is;
|
||||
fail_if(!t);
|
||||
fail_if(!f);
|
||||
|
||||
printf("Testing enqueuing bogus frame\n");
|
||||
f->buffer_len = 0;
|
||||
fail_if(pico_enqueue_segment(&t->tcpq_out, f) >= 0);
|
||||
f->buffer_len = 80;
|
||||
f->transport_hdr = f->start;
|
||||
f->transport_len = (uint16_t)(f->buffer_len - 40);
|
||||
f->payload = f->start + 40;
|
||||
f->payload_len = 40;
|
||||
memset(f->payload, 'c', f->payload_len);
|
||||
is = segment_from_frame(f);
|
||||
fail_if(!is);
|
||||
is->payload_len = 0;
|
||||
fail_if(pico_enqueue_segment(&t->tcpq_in, is) >= 0);
|
||||
is->payload_len = 40;
|
||||
|
||||
/* Successfull cases */
|
||||
fail_if(pico_enqueue_segment(&t->tcpq_out, f) <= 0);
|
||||
fail_if(pico_enqueue_segment(&t->tcpq_in, is) <= 0);
|
||||
|
||||
/* Fail because size exceeded. Must return 0. */
|
||||
t->tcpq_out.max_size = 50;
|
||||
t->tcpq_in.max_size = 50;
|
||||
fail_if(pico_enqueue_segment(&t->tcpq_out, f) != 0);
|
||||
fail_if(pico_enqueue_segment(&t->tcpq_in, is) != 0);
|
||||
|
||||
|
||||
#ifdef PICO_FAULTY
|
||||
/* Fail because the tree cannot allocate a new node. Should return 0 */
|
||||
printf("Testing with faulty memory (1)\n");
|
||||
pico_set_mm_failure(1);
|
||||
fail_if(pico_enqueue_segment(&t->tcpq_out, f) > 0);
|
||||
pico_set_mm_failure(1);
|
||||
fail_if(pico_enqueue_segment(&t->tcpq_in, is) > 0);
|
||||
|
||||
printf("Testing input segment conversion with faulty mm(1)\n");
|
||||
pico_set_mm_failure(1);
|
||||
is = segment_from_frame(f);
|
||||
fail_if(is);
|
||||
printf("Testing input segment conversion with faulty mm(2)\n");
|
||||
pico_set_mm_failure(2);
|
||||
is = segment_from_frame(f);
|
||||
fail_if(is);
|
||||
#endif
|
||||
|
||||
/* Discard all segments */
|
||||
fail_if(t->tcpq_out.size == 0);
|
||||
fail_if(t->tcpq_out.frames == 0);
|
||||
tcp_discard_all_segments(&t->tcpq_out);
|
||||
fail_if(t->tcpq_out.size != 0);
|
||||
fail_if(t->tcpq_out.frames != 0);
|
||||
|
||||
fail_if(t->tcpq_in.size == 0);
|
||||
fail_if(t->tcpq_in.frames == 0);
|
||||
fail_if(pico_tcp_queue_in_is_empty(&t->sock));
|
||||
|
||||
tcp_discard_all_segments(&t->tcpq_in);
|
||||
fail_if(t->tcpq_in.size != 0);
|
||||
fail_if(t->tcpq_in.frames != 0);
|
||||
fail_unless(pico_tcp_queue_in_is_empty(&t->sock));
|
||||
|
||||
|
||||
/* Testing next_segment with NULLS */
|
||||
fail_if(next_segment(NULL, NULL) != NULL);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_release_until)
|
||||
{
|
||||
struct pico_socket_tcp *t = (struct pico_socket_tcp *)pico_tcp_open(PICO_PROTO_IPV6);
|
||||
struct pico_frame *f;
|
||||
uint32_t i = 0;
|
||||
int ret = 0;
|
||||
struct tcp_input_segment *is;
|
||||
fail_if(!t);
|
||||
ret = release_until(&t->tcpq_out, 0);
|
||||
fail_unless(ret == 0);
|
||||
|
||||
/* Test with output queue */
|
||||
for (i = 0; i < 32; i++) {
|
||||
f = pico_frame_alloc(84);
|
||||
fail_if(!f);
|
||||
f->transport_hdr = f->start;
|
||||
f->transport_len = (uint16_t)f->buffer_len;
|
||||
f->payload_len = f->transport_len;
|
||||
((struct pico_tcp_hdr *)((f)->transport_hdr))->seq = long_be(0xaa00 + f->buffer_len * i);
|
||||
printf("inserting frame seq = %08x len = %d\n", 0xaa00 + f->buffer_len * i, f->buffer_len);
|
||||
fail_if(pico_enqueue_segment(&t->tcpq_out, f) <= 0);
|
||||
}
|
||||
ret = release_until(&t->tcpq_out, 0xaa00 + f->buffer_len * 30);
|
||||
printf("Release until %08x\n", 0xaa00 + f->buffer_len * 30);
|
||||
fail_if(ret != 30);
|
||||
printf("Ret is %d\n", ret);
|
||||
printf("Remaining is %d\n", t->tcpq_out.frames);
|
||||
fail_if(t->tcpq_out.frames != 2);
|
||||
|
||||
/* Test with input queue */
|
||||
for (i = 0; i < 32; i++) {
|
||||
f = pico_frame_alloc(84);
|
||||
fail_if(!f);
|
||||
f->transport_hdr = f->start;
|
||||
f->transport_len = (uint16_t)f->buffer_len;
|
||||
f->payload_len = f->transport_len;
|
||||
f->payload = f->start;
|
||||
((struct pico_tcp_hdr *)((f)->transport_hdr))->seq = long_be(0xaa00 + f->buffer_len * i);
|
||||
is = segment_from_frame(f);
|
||||
fail_if(!is);
|
||||
printf("inserting Input frame seq = %08x len = %d\n", long_be(is->seq), is->payload_len);
|
||||
fail_if(!is);
|
||||
fail_if(pico_enqueue_segment(&t->tcpq_in, is) <= 0);
|
||||
}
|
||||
ret = release_until(&t->tcpq_in, 0xaa00 + f->buffer_len * 30);
|
||||
printf("Release until %08x\n", 0xaa00 + f->buffer_len * 30);
|
||||
fail_if(ret != 30);
|
||||
printf("Ret is %d\n", ret);
|
||||
printf("Remaining is %d\n", t->tcpq_out.frames);
|
||||
fail_if(t->tcpq_out.frames != 2);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_release_all_until)
|
||||
{
|
||||
struct pico_socket_tcp *t = (struct pico_socket_tcp *)pico_tcp_open(PICO_PROTO_IPV4);
|
||||
struct pico_frame *f;
|
||||
uint32_t i = 0;
|
||||
int ret = 0;
|
||||
struct tcp_input_segment *is;
|
||||
pico_time tm;
|
||||
fail_if(!t);
|
||||
ret = release_all_until(&t->tcpq_out, 0, &tm);
|
||||
fail_unless(ret == 0);
|
||||
|
||||
/* Test with output queue */
|
||||
for (i = 0; i < 32; i++) {
|
||||
f = pico_frame_alloc(84);
|
||||
fail_if(!f);
|
||||
f->transport_hdr = f->start;
|
||||
f->transport_len = (uint16_t)f->buffer_len;
|
||||
f->payload_len = f->transport_len;
|
||||
((struct pico_tcp_hdr *)((f)->transport_hdr))->seq = long_be(0xaa00 + f->buffer_len * i);
|
||||
printf("inserting frame seq = %08x len = %d\n", 0xaa00 + f->buffer_len * i, f->buffer_len);
|
||||
fail_if(pico_enqueue_segment(&t->tcpq_out, f) <= 0);
|
||||
}
|
||||
ret = release_all_until(&t->tcpq_out, 0xaa00 + f->buffer_len * 30, &tm);
|
||||
printf("Release until %08x\n", 0xaa00 + f->buffer_len * 30);
|
||||
fail_if(ret != 30);
|
||||
printf("Ret is %d\n", ret);
|
||||
printf("Remaining is %d\n", t->tcpq_out.frames);
|
||||
fail_if(t->tcpq_out.frames != 2);
|
||||
|
||||
/* Test with input queue */
|
||||
for (i = 0; i < 32; i++) {
|
||||
f = pico_frame_alloc(84);
|
||||
fail_if(!f);
|
||||
f->transport_hdr = f->start;
|
||||
f->transport_len = (uint16_t)f->buffer_len;
|
||||
f->payload_len = f->transport_len;
|
||||
f->payload = f->start;
|
||||
((struct pico_tcp_hdr *)((f)->transport_hdr))->seq = long_be(0xaa00 + f->buffer_len * i);
|
||||
is = segment_from_frame(f);
|
||||
fail_if(!is);
|
||||
printf("inserting Input frame seq = %08x len = %d\n", long_be(is->seq), is->payload_len);
|
||||
fail_if(!is);
|
||||
fail_if(pico_enqueue_segment(&t->tcpq_in, is) <= 0);
|
||||
}
|
||||
ret = release_all_until(&t->tcpq_in, 0xaa00 + f->buffer_len * 30, &tm);
|
||||
printf("Release until %08x\n", 0xaa00 + f->buffer_len * 30);
|
||||
fail_if(ret != 30);
|
||||
printf("Ret is %d\n", ret);
|
||||
printf("Remaining is %d\n", t->tcpq_out.frames);
|
||||
fail_if(t->tcpq_out.frames != 2);
|
||||
|
||||
/* Test enqueue_segment with NULL segment */
|
||||
fail_if(pico_enqueue_segment(NULL, NULL) != -1);
|
||||
|
||||
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_send_fin)
|
||||
{
|
||||
/* TODO: test this: static void tcp_send_fin(struct pico_socket_tcp *t); */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_tcp_process_out)
|
||||
{
|
||||
/* TODO: test this: static int pico_tcp_process_out(struct pico_protocol *self, struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_paws)
|
||||
{
|
||||
pico_paws();
|
||||
/* Nothing to test for a random function...*/
|
||||
}
|
||||
END_TEST
|
||||
|
||||
|
||||
START_TEST(tc_tcp_add_options)
|
||||
{
|
||||
/* TODO: test this: static void tcp_add_options(struct pico_socket_tcp *ts, struct pico_frame *f, uint16_t flags, uint16_t optsiz) */
|
||||
struct pico_socket_tcp ts = { };
|
||||
struct pico_frame *f = pico_frame_alloc(100);
|
||||
uint16_t flags = 0;
|
||||
uint16_t optsiz = 50;
|
||||
uint8_t *frame_opt_buff;
|
||||
int i;
|
||||
struct tcp_sack_block *a, *b, *c;
|
||||
uint32_t al = 0xa0,
|
||||
ar = 0xaf,
|
||||
bl = 0xb0,
|
||||
br = 0xbf,
|
||||
cl = 0xc0,
|
||||
cr = 0xcf;
|
||||
f->transport_hdr = f->start;
|
||||
f->transport_len = (uint16_t)f->buffer_len;
|
||||
f->payload_len = f->transport_len;
|
||||
frame_opt_buff = f->transport_hdr + PICO_SIZE_TCPHDR;
|
||||
|
||||
/* Window scale only */
|
||||
printf("Testing window scale option\n");
|
||||
ts.wnd_scale = 66;
|
||||
tcp_add_options(&ts, f, flags, optsiz);
|
||||
fail_if(frame_opt_buff[0] != PICO_TCP_OPTION_WS);
|
||||
fail_if(frame_opt_buff[1] != PICO_TCPOPTLEN_WS);
|
||||
fail_if(frame_opt_buff[2] != 66);
|
||||
for (i = 3; i < optsiz - 1; i++)
|
||||
fail_if(frame_opt_buff[i] != PICO_TCP_OPTION_NOOP);
|
||||
fail_if(frame_opt_buff[optsiz - 1] != PICO_TCP_OPTION_END);
|
||||
|
||||
/* MSS + SACK_OK + WS + TIMESTAMPS */
|
||||
printf("Testing full SYN options\n");
|
||||
flags = PICO_TCP_SYN;
|
||||
ts.wnd_scale = 66;
|
||||
ts.mss = 0xAA88;
|
||||
tcp_add_options(&ts, f, flags, optsiz);
|
||||
fail_if(frame_opt_buff[0] != PICO_TCP_OPTION_MSS);
|
||||
fail_if(frame_opt_buff[1] != PICO_TCPOPTLEN_MSS);
|
||||
fail_if(frame_opt_buff[2] != 0xAA);
|
||||
fail_if(frame_opt_buff[3] != 0x88);
|
||||
fail_if(frame_opt_buff[4] != PICO_TCP_OPTION_SACK_OK);
|
||||
fail_if(frame_opt_buff[5] != PICO_TCPOPTLEN_SACK_OK);
|
||||
fail_if(frame_opt_buff[6] != PICO_TCP_OPTION_WS);
|
||||
fail_if(frame_opt_buff[7] != PICO_TCPOPTLEN_WS);
|
||||
fail_if(frame_opt_buff[8] != 66);
|
||||
fail_if(frame_opt_buff[9] != PICO_TCP_OPTION_TIMESTAMP);
|
||||
fail_if(frame_opt_buff[10] != PICO_TCPOPTLEN_TIMESTAMP);
|
||||
/* Timestamps: up to byte 18 */
|
||||
for (i = 19; i < optsiz - 1; i++)
|
||||
fail_if(frame_opt_buff[i] != PICO_TCP_OPTION_NOOP);
|
||||
fail_if(frame_opt_buff[optsiz - 1] != PICO_TCP_OPTION_END);
|
||||
|
||||
/* Testing SACKs */
|
||||
printf("Testing full SACK options\n");
|
||||
a = PICO_ZALLOC(sizeof (struct tcp_sack_block));
|
||||
b = PICO_ZALLOC(sizeof (struct tcp_sack_block));
|
||||
c = PICO_ZALLOC(sizeof (struct tcp_sack_block));
|
||||
a->left = al;
|
||||
a->right = ar;
|
||||
a->next = b;
|
||||
b->left = bl;
|
||||
b->right = br;
|
||||
b->next = c;
|
||||
c->left = cl;
|
||||
c->right = cr;
|
||||
c->next = NULL;
|
||||
|
||||
ts.sack_ok = 1;
|
||||
ts.sacks = a;
|
||||
flags = PICO_TCP_ACK;
|
||||
tcp_add_options(&ts, f, flags, optsiz);
|
||||
fail_if(frame_opt_buff[0] != PICO_TCP_OPTION_WS);
|
||||
fail_if(frame_opt_buff[1] != PICO_TCPOPTLEN_WS);
|
||||
fail_if(frame_opt_buff[2] != 66);
|
||||
fail_if(frame_opt_buff[3] != PICO_TCP_OPTION_SACK);
|
||||
fail_if(frame_opt_buff[4] != PICO_TCPOPTLEN_SACK + 6 * (sizeof(uint32_t)));
|
||||
fail_if(memcmp(frame_opt_buff + 5, &al, 4) != 0);
|
||||
fail_if(memcmp(frame_opt_buff + 9, &ar, 4) != 0);
|
||||
fail_if(memcmp(frame_opt_buff + 13, &bl, 4) != 0);
|
||||
fail_if(memcmp(frame_opt_buff + 17, &br, 4) != 0);
|
||||
fail_if(memcmp(frame_opt_buff + 21, &cl, 4) != 0);
|
||||
fail_if(memcmp(frame_opt_buff + 25, &cr, 4) != 0);
|
||||
fail_if(ts.sacks != NULL);
|
||||
for (i = 29; i < optsiz - 1; i++)
|
||||
fail_if(frame_opt_buff[i] != PICO_TCP_OPTION_NOOP);
|
||||
fail_if(frame_opt_buff[optsiz - 1] != PICO_TCP_OPTION_END);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_options_size_frame)
|
||||
{
|
||||
/* TODO: test this: static uint16_t tcp_options_size_frame(struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_add_options_frame)
|
||||
{
|
||||
/* TODO: test this: static void tcp_add_options_frame(struct pico_socket_tcp *ts, struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_send_ack)
|
||||
{
|
||||
/* TODO: test this: static void tcp_send_ack(struct pico_socket_tcp *t); */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_set_space)
|
||||
{
|
||||
/* TODO: test this: static void tcp_set_space(struct pico_socket_tcp *t) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_options_size)
|
||||
{
|
||||
/* TODO: test this: static uint16_t tcp_options_size(struct pico_socket_tcp *t, uint16_t flags) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_process_sack)
|
||||
{
|
||||
/* TODO: test this: static void tcp_process_sack(struct pico_socket_tcp *t, uint32_t start, uint32_t end) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_rcv_sack)
|
||||
{
|
||||
/* TODO: test this: static void tcp_rcv_sack(struct pico_socket_tcp *t, uint8_t *opt, int len) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_parse_options)
|
||||
{
|
||||
/* TODO: test this: static void tcp_parse_options(struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_send)
|
||||
{
|
||||
/* TODO: test this: static int tcp_send(struct pico_socket_tcp *ts, struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_sock_stats)
|
||||
{
|
||||
/* TODO: test this: static void sock_stats(uint32_t when, void *arg) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_initconn_retry)
|
||||
{
|
||||
/* TODO: test this: static void initconn_retry(pico_time when, void *arg) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_send_synack)
|
||||
{
|
||||
/* TODO: test this: static int tcp_send_synack(struct pico_socket *s) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_send_empty)
|
||||
{
|
||||
/* TODO: test this: static void tcp_send_empty(struct pico_socket_tcp *t, uint16_t flags, int is_keepalive) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_send_probe)
|
||||
{
|
||||
/* TODO: test this: static void tcp_send_probe(struct pico_socket_tcp *t) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_send_rst)
|
||||
{
|
||||
/* TODO: test this: static int tcp_send_rst(struct pico_socket *s, struct pico_frame *fr) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_nosync_rst)
|
||||
{
|
||||
/* TODO: test this: static int tcp_nosync_rst(struct pico_socket *s, struct pico_frame *fr) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_sack_prepare)
|
||||
{
|
||||
/* TODO: test this: static void tcp_sack_prepare(struct pico_socket_tcp *t) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_data_in)
|
||||
{
|
||||
/* TODO: test this: static int tcp_data_in(struct pico_socket *s, struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_ack_advance_una)
|
||||
{
|
||||
/* TODO: test this: static int tcp_ack_advance_una(struct pico_socket_tcp *t, struct pico_frame *f, pico_time *timestamp) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_time_diff)
|
||||
{
|
||||
/* TODO: test this: static uint16_t time_diff(pico_time a, pico_time b) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_rtt)
|
||||
{
|
||||
/* TODO: test this: static void tcp_rtt(struct pico_socket_tcp *t, uint32_t rtt) */
|
||||
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_congestion_control)
|
||||
{
|
||||
/* TODO: test this: static void tcp_congestion_control(struct pico_socket_tcp *t) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_add_retransmission_timer)
|
||||
{
|
||||
/* TODO: test this: static void add_retransmission_timer(struct pico_socket_tcp *t, pico_time next_ts); */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_first_timeout)
|
||||
{
|
||||
/* TODO: test this: static void tcp_first_timeout(struct pico_socket_tcp *t) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_rto_xmit)
|
||||
{
|
||||
/* TODO: test this: static int tcp_rto_xmit(struct pico_socket_tcp *t, struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_next_zerowindow_probe)
|
||||
{
|
||||
/* TODO: test this: static void tcp_next_zerowindow_probe(struct pico_socket_tcp *t) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_is_allowed_to_send)
|
||||
{
|
||||
/* TODO: test this: static int tcp_is_allowed_to_send(struct pico_socket_tcp *t) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_retrans_timeout)
|
||||
{
|
||||
/* TODO: test this: static void tcp_retrans_timeout(pico_time val, void *sock) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_retrans)
|
||||
{
|
||||
/* TODO: test this: static int tcp_retrans(struct pico_socket_tcp *t, struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_ack_dbg)
|
||||
{
|
||||
/* TODO: test this: static void tcp_ack_dbg(struct pico_socket *s, struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_ack)
|
||||
{
|
||||
/* TODO: test this: static int tcp_ack(struct pico_socket *s, struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_finwaitack)
|
||||
{
|
||||
/* TODO: test this: static int tcp_finwaitack(struct pico_socket *s, struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_deltcb)
|
||||
{
|
||||
/* TODO: test this: static void tcp_deltcb(pico_time when, void *arg) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_finwaitfin)
|
||||
{
|
||||
/* TODO: test this: static int tcp_finwaitfin(struct pico_socket *s, struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_closewaitack)
|
||||
{
|
||||
/* TODO: test this: static int tcp_closewaitack(struct pico_socket *s, struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_lastackwait)
|
||||
{
|
||||
/* TODO: test this: static int tcp_lastackwait(struct pico_socket *s, struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_syn)
|
||||
{
|
||||
/* TODO: test this: static int tcp_syn(struct pico_socket *s, struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_set_init_point)
|
||||
{
|
||||
/* TODO: test this: static void tcp_set_init_point(struct pico_socket *s) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_synack)
|
||||
{
|
||||
/* TODO: test this: static int tcp_synack(struct pico_socket *s, struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_first_ack)
|
||||
{
|
||||
/* TODO: test this: static int tcp_first_ack(struct pico_socket *s, struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_closewait)
|
||||
{
|
||||
/* TODO: test this: static int tcp_closewait(struct pico_socket *s, struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_fin)
|
||||
{
|
||||
/* TODO: test this: static int tcp_fin(struct pico_socket *s, struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_rcvfin)
|
||||
{
|
||||
/* TODO: test this: static int tcp_rcvfin(struct pico_socket *s, struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_finack)
|
||||
{
|
||||
/* TODO: test this: static int tcp_finack(struct pico_socket *s, struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_force_closed)
|
||||
{
|
||||
/* TODO: test this: static void tcp_force_closed(struct pico_socket *s) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_wakeup_pending)
|
||||
{
|
||||
/* TODO: test this: static void tcp_wakeup_pending(struct pico_socket *s, uint16_t ev) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_rst)
|
||||
{
|
||||
/* TODO: test this: static int tcp_rst(struct pico_socket *s, struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_halfopencon)
|
||||
{
|
||||
/* TODO: test this: static int tcp_halfopencon(struct pico_socket *s, struct pico_frame *fr) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_closeconn)
|
||||
{
|
||||
/* TODO: test this: static int tcp_closeconn(struct pico_socket *s, struct pico_frame *fr) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_invalid_flags)
|
||||
{
|
||||
/* TODO: test this: static uint8_t invalid_flags(struct pico_socket *s, uint8_t flags) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_checkLocalClosing)
|
||||
{
|
||||
/* TODO: test this: static int checkLocalClosing(struct pico_socket *s) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_checkRemoteClosing)
|
||||
{
|
||||
/* TODO: test this: static int checkRemoteClosing(struct pico_socket *s) */
|
||||
}
|
||||
END_TEST
|
||||
|
||||
Suite *pico_suite(void)
|
||||
{
|
||||
Suite *s = suite_create("PicoTCP");
|
||||
|
||||
TCase *TCase_input_segment_compare = tcase_create("Unit test for input_segment_compare");
|
||||
TCase *TCase_tcp_input_segment = tcase_create("Unit test for tcp_input_segment");
|
||||
TCase *TCase_segment_compare = tcase_create("Unit test for segment_compare");
|
||||
TCase *TCase_tcp_discard_all_segments = tcase_create("Unit test for tcp_discard_all_segments");
|
||||
TCase *TCase_release_until = tcase_create("Unit test for release_until");
|
||||
TCase *TCase_release_all_until = tcase_create("Unit test for release_all_until");
|
||||
TCase *TCase_tcp_send_fin = tcase_create("Unit test for tcp_send_fin");
|
||||
TCase *TCase_pico_tcp_process_out = tcase_create("Unit test for pico_tcp_process_out");
|
||||
TCase *TCase_pico_paws = tcase_create("Unit test for pico_paws");
|
||||
TCase *TCase_tcp_add_options = tcase_create("Unit test for tcp_add_options");
|
||||
TCase *TCase_tcp_options_size_frame = tcase_create("Unit test for tcp_options_size_frame");
|
||||
TCase *TCase_tcp_add_options_frame = tcase_create("Unit test for tcp_add_options_frame");
|
||||
TCase *TCase_tcp_send_ack = tcase_create("Unit test for tcp_send_ack");
|
||||
TCase *TCase_tcp_set_space = tcase_create("Unit test for tcp_set_space");
|
||||
TCase *TCase_tcp_options_size = tcase_create("Unit test for tcp_options_size");
|
||||
TCase *TCase_tcp_process_sack = tcase_create("Unit test for tcp_process_sack");
|
||||
TCase *TCase_tcp_rcv_sack = tcase_create("Unit test for tcp_rcv_sack");
|
||||
TCase *TCase_tcp_parse_options = tcase_create("Unit test for tcp_parse_options");
|
||||
TCase *TCase_tcp_send = tcase_create("Unit test for tcp_send");
|
||||
TCase *TCase_sock_stats = tcase_create("Unit test for sock_stats");
|
||||
TCase *TCase_initconn_retry = tcase_create("Unit test for initconn_retry");
|
||||
TCase *TCase_tcp_send_synack = tcase_create("Unit test for tcp_send_synack");
|
||||
TCase *TCase_tcp_send_empty = tcase_create("Unit test for tcp_send_empty");
|
||||
TCase *TCase_tcp_send_probe = tcase_create("Unit test for tcp_send_probe");
|
||||
TCase *TCase_tcp_send_rst = tcase_create("Unit test for tcp_send_rst");
|
||||
TCase *TCase_tcp_nosync_rst = tcase_create("Unit test for tcp_nosync_rst");
|
||||
TCase *TCase_tcp_sack_prepare = tcase_create("Unit test for tcp_sack_prepare");
|
||||
TCase *TCase_tcp_data_in = tcase_create("Unit test for tcp_data_in");
|
||||
TCase *TCase_tcp_ack_advance_una = tcase_create("Unit test for tcp_ack_advance_una");
|
||||
TCase *TCase_time_diff = tcase_create("Unit test for time_diff");
|
||||
TCase *TCase_tcp_rtt = tcase_create("Unit test for tcp_rtt");
|
||||
TCase *TCase_tcp_congestion_control = tcase_create("Unit test for tcp_congestion_control");
|
||||
TCase *TCase_add_retransmission_timer = tcase_create("Unit test for add_retransmission_timer");
|
||||
TCase *TCase_tcp_first_timeout = tcase_create("Unit test for tcp_first_timeout");
|
||||
TCase *TCase_tcp_rto_xmit = tcase_create("Unit test for tcp_rto_xmit");
|
||||
TCase *TCase_tcp_next_zerowindow_probe = tcase_create("Unit test for tcp_next_zerowindow_probe");
|
||||
TCase *TCase_tcp_is_allowed_to_send = tcase_create("Unit test for tcp_is_allowed_to_send");
|
||||
TCase *TCase_tcp_retrans_timeout = tcase_create("Unit test for tcp_retrans_timeout");
|
||||
TCase *TCase_tcp_retrans = tcase_create("Unit test for tcp_retrans");
|
||||
TCase *TCase_tcp_ack_dbg = tcase_create("Unit test for tcp_ack_dbg");
|
||||
TCase *TCase_tcp_ack = tcase_create("Unit test for tcp_ack");
|
||||
TCase *TCase_tcp_finwaitack = tcase_create("Unit test for tcp_finwaitack");
|
||||
TCase *TCase_tcp_deltcb = tcase_create("Unit test for tcp_deltcb");
|
||||
TCase *TCase_tcp_finwaitfin = tcase_create("Unit test for tcp_finwaitfin");
|
||||
TCase *TCase_tcp_closewaitack = tcase_create("Unit test for tcp_closewaitack");
|
||||
TCase *TCase_tcp_lastackwait = tcase_create("Unit test for tcp_lastackwait");
|
||||
TCase *TCase_tcp_syn = tcase_create("Unit test for tcp_syn");
|
||||
TCase *TCase_tcp_set_init_point = tcase_create("Unit test for tcp_set_init_point");
|
||||
TCase *TCase_tcp_synack = tcase_create("Unit test for tcp_synack");
|
||||
TCase *TCase_tcp_first_ack = tcase_create("Unit test for tcp_first_ack");
|
||||
TCase *TCase_tcp_closewait = tcase_create("Unit test for tcp_closewait");
|
||||
TCase *TCase_tcp_fin = tcase_create("Unit test for tcp_fin");
|
||||
TCase *TCase_tcp_rcvfin = tcase_create("Unit test for tcp_rcvfin");
|
||||
TCase *TCase_tcp_finack = tcase_create("Unit test for tcp_finack");
|
||||
TCase *TCase_tcp_force_closed = tcase_create("Unit test for tcp_force_closed");
|
||||
TCase *TCase_tcp_wakeup_pending = tcase_create("Unit test for tcp_wakeup_pending");
|
||||
TCase *TCase_tcp_rst = tcase_create("Unit test for tcp_rst");
|
||||
TCase *TCase_tcp_halfopencon = tcase_create("Unit test for tcp_halfopencon");
|
||||
TCase *TCase_tcp_closeconn = tcase_create("Unit test for tcp_closeconn");
|
||||
TCase *TCase_invalid_flags = tcase_create("Unit test for invalid_flags");
|
||||
TCase *TCase_checkLocalClosing = tcase_create("Unit test for checkLocalClosing");
|
||||
TCase *TCase_checkRemoteClosing = tcase_create("Unit test for checkRemoteClosing");
|
||||
|
||||
|
||||
tcase_add_test(TCase_input_segment_compare, tc_input_segment_compare);
|
||||
suite_add_tcase(s, TCase_input_segment_compare);
|
||||
tcase_add_test(TCase_tcp_input_segment, tc_tcp_input_segment);
|
||||
suite_add_tcase(s, TCase_tcp_input_segment);
|
||||
tcase_add_test(TCase_segment_compare, tc_segment_compare);
|
||||
suite_add_tcase(s, TCase_segment_compare);
|
||||
tcase_add_test(TCase_tcp_discard_all_segments, tc_tcp_discard_all_segments);
|
||||
suite_add_tcase(s, TCase_tcp_discard_all_segments);
|
||||
tcase_add_test(TCase_release_until, tc_release_until);
|
||||
suite_add_tcase(s, TCase_release_until);
|
||||
tcase_add_test(TCase_release_all_until, tc_release_all_until);
|
||||
suite_add_tcase(s, TCase_release_all_until);
|
||||
tcase_add_test(TCase_tcp_send_fin, tc_tcp_send_fin);
|
||||
suite_add_tcase(s, TCase_tcp_send_fin);
|
||||
tcase_add_test(TCase_pico_tcp_process_out, tc_pico_tcp_process_out);
|
||||
suite_add_tcase(s, TCase_pico_tcp_process_out);
|
||||
tcase_add_test(TCase_pico_paws, tc_pico_paws);
|
||||
suite_add_tcase(s, TCase_pico_paws);
|
||||
tcase_add_test(TCase_tcp_add_options, tc_tcp_add_options);
|
||||
suite_add_tcase(s, TCase_tcp_add_options);
|
||||
tcase_add_test(TCase_tcp_options_size_frame, tc_tcp_options_size_frame);
|
||||
suite_add_tcase(s, TCase_tcp_options_size_frame);
|
||||
tcase_add_test(TCase_tcp_add_options_frame, tc_tcp_add_options_frame);
|
||||
suite_add_tcase(s, TCase_tcp_add_options_frame);
|
||||
tcase_add_test(TCase_tcp_send_ack, tc_tcp_send_ack);
|
||||
suite_add_tcase(s, TCase_tcp_send_ack);
|
||||
tcase_add_test(TCase_tcp_set_space, tc_tcp_set_space);
|
||||
suite_add_tcase(s, TCase_tcp_set_space);
|
||||
tcase_add_test(TCase_tcp_options_size, tc_tcp_options_size);
|
||||
suite_add_tcase(s, TCase_tcp_options_size);
|
||||
tcase_add_test(TCase_tcp_process_sack, tc_tcp_process_sack);
|
||||
suite_add_tcase(s, TCase_tcp_process_sack);
|
||||
tcase_add_test(TCase_tcp_rcv_sack, tc_tcp_rcv_sack);
|
||||
suite_add_tcase(s, TCase_tcp_rcv_sack);
|
||||
tcase_add_test(TCase_tcp_parse_options, tc_tcp_parse_options);
|
||||
suite_add_tcase(s, TCase_tcp_parse_options);
|
||||
tcase_add_test(TCase_tcp_send, tc_tcp_send);
|
||||
suite_add_tcase(s, TCase_tcp_send);
|
||||
tcase_add_test(TCase_sock_stats, tc_sock_stats);
|
||||
suite_add_tcase(s, TCase_sock_stats);
|
||||
tcase_add_test(TCase_initconn_retry, tc_initconn_retry);
|
||||
suite_add_tcase(s, TCase_initconn_retry);
|
||||
tcase_add_test(TCase_tcp_send_synack, tc_tcp_send_synack);
|
||||
suite_add_tcase(s, TCase_tcp_send_synack);
|
||||
tcase_add_test(TCase_tcp_send_empty, tc_tcp_send_empty);
|
||||
suite_add_tcase(s, TCase_tcp_send_empty);
|
||||
tcase_add_test(TCase_tcp_send_probe, tc_tcp_send_probe);
|
||||
suite_add_tcase(s, TCase_tcp_send_probe);
|
||||
tcase_add_test(TCase_tcp_send_rst, tc_tcp_send_rst);
|
||||
suite_add_tcase(s, TCase_tcp_send_rst);
|
||||
tcase_add_test(TCase_tcp_nosync_rst, tc_tcp_nosync_rst);
|
||||
suite_add_tcase(s, TCase_tcp_nosync_rst);
|
||||
tcase_add_test(TCase_tcp_sack_prepare, tc_tcp_sack_prepare);
|
||||
suite_add_tcase(s, TCase_tcp_sack_prepare);
|
||||
tcase_add_test(TCase_tcp_data_in, tc_tcp_data_in);
|
||||
suite_add_tcase(s, TCase_tcp_data_in);
|
||||
tcase_add_test(TCase_tcp_ack_advance_una, tc_tcp_ack_advance_una);
|
||||
suite_add_tcase(s, TCase_tcp_ack_advance_una);
|
||||
tcase_add_test(TCase_time_diff, tc_time_diff);
|
||||
suite_add_tcase(s, TCase_time_diff);
|
||||
tcase_add_test(TCase_tcp_rtt, tc_tcp_rtt);
|
||||
suite_add_tcase(s, TCase_tcp_rtt);
|
||||
tcase_add_test(TCase_tcp_congestion_control, tc_tcp_congestion_control);
|
||||
suite_add_tcase(s, TCase_tcp_congestion_control);
|
||||
tcase_add_test(TCase_add_retransmission_timer, tc_add_retransmission_timer);
|
||||
suite_add_tcase(s, TCase_add_retransmission_timer);
|
||||
tcase_add_test(TCase_tcp_first_timeout, tc_tcp_first_timeout);
|
||||
suite_add_tcase(s, TCase_tcp_first_timeout);
|
||||
tcase_add_test(TCase_tcp_rto_xmit, tc_tcp_rto_xmit);
|
||||
suite_add_tcase(s, TCase_tcp_rto_xmit);
|
||||
tcase_add_test(TCase_tcp_next_zerowindow_probe, tc_tcp_next_zerowindow_probe);
|
||||
suite_add_tcase(s, TCase_tcp_next_zerowindow_probe);
|
||||
tcase_add_test(TCase_tcp_is_allowed_to_send, tc_tcp_is_allowed_to_send);
|
||||
suite_add_tcase(s, TCase_tcp_is_allowed_to_send);
|
||||
tcase_add_test(TCase_tcp_retrans_timeout, tc_tcp_retrans_timeout);
|
||||
suite_add_tcase(s, TCase_tcp_retrans_timeout);
|
||||
tcase_add_test(TCase_tcp_retrans, tc_tcp_retrans);
|
||||
suite_add_tcase(s, TCase_tcp_retrans);
|
||||
tcase_add_test(TCase_tcp_ack_dbg, tc_tcp_ack_dbg);
|
||||
suite_add_tcase(s, TCase_tcp_ack_dbg);
|
||||
tcase_add_test(TCase_tcp_ack, tc_tcp_ack);
|
||||
suite_add_tcase(s, TCase_tcp_ack);
|
||||
tcase_add_test(TCase_tcp_finwaitack, tc_tcp_finwaitack);
|
||||
suite_add_tcase(s, TCase_tcp_finwaitack);
|
||||
tcase_add_test(TCase_tcp_deltcb, tc_tcp_deltcb);
|
||||
suite_add_tcase(s, TCase_tcp_deltcb);
|
||||
tcase_add_test(TCase_tcp_finwaitfin, tc_tcp_finwaitfin);
|
||||
suite_add_tcase(s, TCase_tcp_finwaitfin);
|
||||
tcase_add_test(TCase_tcp_closewaitack, tc_tcp_closewaitack);
|
||||
suite_add_tcase(s, TCase_tcp_closewaitack);
|
||||
tcase_add_test(TCase_tcp_lastackwait, tc_tcp_lastackwait);
|
||||
suite_add_tcase(s, TCase_tcp_lastackwait);
|
||||
tcase_add_test(TCase_tcp_syn, tc_tcp_syn);
|
||||
suite_add_tcase(s, TCase_tcp_syn);
|
||||
tcase_add_test(TCase_tcp_set_init_point, tc_tcp_set_init_point);
|
||||
suite_add_tcase(s, TCase_tcp_set_init_point);
|
||||
tcase_add_test(TCase_tcp_synack, tc_tcp_synack);
|
||||
suite_add_tcase(s, TCase_tcp_synack);
|
||||
tcase_add_test(TCase_tcp_first_ack, tc_tcp_first_ack);
|
||||
suite_add_tcase(s, TCase_tcp_first_ack);
|
||||
tcase_add_test(TCase_tcp_closewait, tc_tcp_closewait);
|
||||
suite_add_tcase(s, TCase_tcp_closewait);
|
||||
tcase_add_test(TCase_tcp_fin, tc_tcp_fin);
|
||||
suite_add_tcase(s, TCase_tcp_fin);
|
||||
tcase_add_test(TCase_tcp_rcvfin, tc_tcp_rcvfin);
|
||||
suite_add_tcase(s, TCase_tcp_rcvfin);
|
||||
tcase_add_test(TCase_tcp_finack, tc_tcp_finack);
|
||||
suite_add_tcase(s, TCase_tcp_finack);
|
||||
tcase_add_test(TCase_tcp_force_closed, tc_tcp_force_closed);
|
||||
suite_add_tcase(s, TCase_tcp_force_closed);
|
||||
tcase_add_test(TCase_tcp_wakeup_pending, tc_tcp_wakeup_pending);
|
||||
suite_add_tcase(s, TCase_tcp_wakeup_pending);
|
||||
tcase_add_test(TCase_tcp_rst, tc_tcp_rst);
|
||||
suite_add_tcase(s, TCase_tcp_rst);
|
||||
tcase_add_test(TCase_tcp_halfopencon, tc_tcp_halfopencon);
|
||||
suite_add_tcase(s, TCase_tcp_halfopencon);
|
||||
tcase_add_test(TCase_tcp_closeconn, tc_tcp_closeconn);
|
||||
suite_add_tcase(s, TCase_tcp_closeconn);
|
||||
tcase_add_test(TCase_invalid_flags, tc_invalid_flags);
|
||||
suite_add_tcase(s, TCase_invalid_flags);
|
||||
tcase_add_test(TCase_checkLocalClosing, tc_checkLocalClosing);
|
||||
suite_add_tcase(s, TCase_checkLocalClosing);
|
||||
tcase_add_test(TCase_checkRemoteClosing, tc_checkRemoteClosing);
|
||||
suite_add_tcase(s, TCase_checkRemoteClosing);
|
||||
return s;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int fails;
|
||||
Suite *s = pico_suite();
|
||||
SRunner *sr = srunner_create(s);
|
||||
srunner_run_all(sr, CK_NORMAL);
|
||||
fails = srunner_ntests_failed(sr);
|
||||
srunner_free(sr);
|
||||
return fails;
|
||||
}
|
||||
375
kernel/picotcp/test/unit/modunit_pico_tftp.c
Normal file
375
kernel/picotcp/test/unit/modunit_pico_tftp.c
Normal file
@@ -0,0 +1,375 @@
|
||||
#include <pico_defines.h>
|
||||
#include <pico_stack.h>
|
||||
#include <pico_socket.h>
|
||||
#include <pico_tftp.h>
|
||||
#include "modules/pico_tftp.c"
|
||||
#include "check.h"
|
||||
|
||||
|
||||
Suite *pico_suite(void);
|
||||
int tftp_user_cb(struct pico_tftp_session *session, uint16_t err, uint8_t *block, int32_t len, void *arg);
|
||||
/* MOCKS */
|
||||
static int called_pico_socket_close = 0;
|
||||
static uint16_t expected_opcode = 0;
|
||||
static int called_user_cb = 0;
|
||||
static int called_sendto = 0;
|
||||
static uint32_t called_pico_timer_add = 0;
|
||||
static int called_pico_timer_cancel = 0;
|
||||
static struct pico_socket example_socket;
|
||||
static struct pico_tftp_session example_session;
|
||||
|
||||
int pico_socket_close(struct pico_socket *s)
|
||||
{
|
||||
fail_if(s != example_session.socket);
|
||||
called_pico_socket_close++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pico_socket_sendto(struct pico_socket *s, const void *buf, const int len, void *dst, uint16_t remote_port)
|
||||
{
|
||||
const struct pico_tftp_hdr *h = (const struct pico_tftp_hdr *)buf;
|
||||
fail_if(s != &example_socket);
|
||||
fail_if(short_be(h->opcode) != expected_opcode);
|
||||
fail_if(len <= 0);
|
||||
(void)dst;
|
||||
(void)remote_port;
|
||||
called_sendto++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tftp_user_cb(struct pico_tftp_session *session, uint16_t err, uint8_t *block, int32_t len, void *arg)
|
||||
{
|
||||
(void)session;
|
||||
(void)err;
|
||||
(void)block;
|
||||
(void)len;
|
||||
(void)arg;
|
||||
called_user_cb++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t pico_timer_add(pico_time expire, void (*timer)(pico_time, void *), void *arg)
|
||||
{
|
||||
(void)expire;
|
||||
(void)timer;
|
||||
(void)arg;
|
||||
|
||||
return ++called_pico_timer_add;
|
||||
}
|
||||
|
||||
void pico_timer_cancel(uint32_t t)
|
||||
{
|
||||
(void)t;
|
||||
called_pico_timer_cancel++;
|
||||
}
|
||||
|
||||
/* TESTS */
|
||||
|
||||
/* START_TEST(tc_check_opcode) */
|
||||
/* { */
|
||||
/* / * TODO: test this: static int check_opcode(struct pico_tftp_hdr *th) * / */
|
||||
/* struct pico_tftp_hdr th; */
|
||||
/* th.opcode = 0; */
|
||||
/* fail_unless(check_opcode(&th) == -1); */
|
||||
/* th.opcode = short_be(PICO_TFTP_RRQ); */
|
||||
/* fail_unless(check_opcode(&th) == 0); */
|
||||
/* th.opcode = short_be(0xFF); */
|
||||
/* fail_unless(check_opcode(&th) == -1); */
|
||||
/* } */
|
||||
/* END_TEST */
|
||||
|
||||
|
||||
START_TEST(tc_find_session_by_socket)
|
||||
{
|
||||
tftp_sessions = (struct pico_tftp_session *)PICO_ZALLOC(sizeof(struct pico_tftp_session));
|
||||
tftp_sessions->socket = &example_socket;
|
||||
tftp_sessions->next = (struct pico_tftp_session *)PICO_ZALLOC(sizeof(struct pico_tftp_session));
|
||||
tftp_sessions->socket = NULL;
|
||||
tftp_sessions->next = NULL;
|
||||
fail_if(find_session_by_socket(&example_socket) != tftp_sessions->next);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_tftp_finish)
|
||||
{
|
||||
tftp_sessions = 0;
|
||||
|
||||
/* Test case: client */
|
||||
example_session.socket = &example_socket;
|
||||
called_pico_socket_close = 0;
|
||||
tftp_finish(&example_session);
|
||||
fail_if(!called_pico_socket_close);
|
||||
|
||||
/* Test eval_finish() len is 5*/
|
||||
example_session.socket = &example_socket;
|
||||
called_pico_socket_close = 0;
|
||||
tftp_eval_finish(&example_session, 5);
|
||||
fail_if(example_session.state != TFTP_STATE_CLOSING);
|
||||
fail_if(!called_pico_socket_close);
|
||||
|
||||
/* Test eval_finish() len is PICO_TFTP_TOTAL_BLOCK_SIZE */
|
||||
example_session.socket = &example_socket;
|
||||
called_pico_socket_close = 0;
|
||||
tftp_eval_finish(&example_session, PICO_TFTP_TOTAL_BLOCK_SIZE);
|
||||
fail_if(called_pico_socket_close);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_tftp_send_ack)
|
||||
{
|
||||
example_session.socket = &example_socket;
|
||||
#ifdef PICO_FAULTY
|
||||
/* send_ack must not segfault when out of memory */
|
||||
pico_set_mm_failure(1);
|
||||
tftp_send_ack(&example_session);
|
||||
fail_if(called_sendto > 0);
|
||||
#endif
|
||||
expected_opcode = PICO_TFTP_ACK;
|
||||
tftp_send_ack(&example_session);
|
||||
fail_if(called_sendto < 1);
|
||||
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_tftp_send_req)
|
||||
{
|
||||
/* Not needed. The tftp_send_rx_req and tftp_send_tx_req cover this. */
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_tftp_send_rx_req)
|
||||
{
|
||||
char filename[14] = "some filename";
|
||||
|
||||
example_session.socket = &example_socket;
|
||||
called_user_cb = 0;
|
||||
called_pico_socket_close = 0;
|
||||
called_sendto = 0;
|
||||
#ifdef PICO_FAULTY
|
||||
example_session.callback = tftp_user_cb;
|
||||
|
||||
/* send_req must call error cb when out of memory */
|
||||
pico_set_mm_failure(1);
|
||||
tftp_send_rx_req(&example_session, NULL, 0, filename);
|
||||
fail_if(called_user_cb < 1);
|
||||
fail_if(called_sendto > 0);
|
||||
#endif
|
||||
expected_opcode = PICO_TFTP_RRQ;
|
||||
tftp_send_rx_req(&example_session, NULL, 0, NULL);
|
||||
fail_if(called_sendto > 0); /* Calling with filename = NULL: not good */
|
||||
|
||||
tftp_send_rx_req(&example_session, NULL, 0, filename);
|
||||
fail_if(called_sendto < 0);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_tftp_send_tx_req)
|
||||
{
|
||||
char filename[14] = "some filename";
|
||||
|
||||
example_session.socket = &example_socket;
|
||||
called_user_cb = 0;
|
||||
called_pico_socket_close = 0;
|
||||
called_sendto = 0;
|
||||
#ifdef PICO_FAULTY
|
||||
example_session.callback = tftp_user_cb;
|
||||
|
||||
/* send_req must call error cb when out of memory */
|
||||
pico_set_mm_failure(1);
|
||||
tftp_send_tx_req(&example_session, NULL, 0, filename);
|
||||
fail_if(called_user_cb < 1);
|
||||
fail_if(called_sendto > 0);
|
||||
#endif
|
||||
expected_opcode = PICO_TFTP_WRQ;
|
||||
tftp_send_tx_req(&example_session, NULL, 0, NULL);
|
||||
fail_if(called_sendto > 0); /* Calling with filename = NULL: not good */
|
||||
|
||||
tftp_send_tx_req(&example_session, NULL, 0, filename);
|
||||
fail_if(called_sendto < 0);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_tftp_send_error)
|
||||
{
|
||||
char longtext[1024];
|
||||
example_session.socket = &example_socket;
|
||||
called_user_cb = 0;
|
||||
called_pico_socket_close = 0;
|
||||
|
||||
/* Sending empty msg */
|
||||
called_sendto = 0;
|
||||
expected_opcode = PICO_TFTP_ERROR;
|
||||
tftp_send_error(&example_session, NULL, 0, 0, NULL);
|
||||
fail_if(called_sendto < 1);
|
||||
/* Sending some msg */
|
||||
called_sendto = 0;
|
||||
expected_opcode = PICO_TFTP_ERROR;
|
||||
tftp_send_error(&example_session, NULL, 0, 0, "some text here");
|
||||
fail_if(called_sendto < 1);
|
||||
|
||||
/* sending some very long msg */
|
||||
memset(longtext, 'a', 1023);
|
||||
longtext[1023] = (char)0;
|
||||
called_sendto = 0;
|
||||
expected_opcode = PICO_TFTP_ERROR;
|
||||
tftp_send_error(&example_session, NULL, 0, 0, longtext);
|
||||
fail_if(called_sendto < 1);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_tftp_send_data)
|
||||
{
|
||||
example_session.state = 0;
|
||||
example_session.socket = &example_socket;
|
||||
called_sendto = 0;
|
||||
expected_opcode = PICO_TFTP_DATA;
|
||||
tftp_send_data(&example_session, (const uint8_t*)"buffer", strlen("buffer"));
|
||||
fail_if(called_sendto < 1);
|
||||
fail_if(example_session.state != TFTP_STATE_WAIT_LAST_ACK);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_pico_tftp_abort)
|
||||
{
|
||||
int ret;
|
||||
server.listen_socket = NULL;
|
||||
|
||||
/*first case: no session and no listening socket*/
|
||||
ret = pico_tftp_abort(NULL, TFTP_ERR_EUSR, "test");
|
||||
fail_if(ret != -1);
|
||||
/*second case: no session but listening socket*/
|
||||
server.listen_socket = example_session.socket = &example_socket;
|
||||
pico_tftp_abort(NULL, TFTP_ERR_EUSR, "test");
|
||||
fail_if(ret != -1);
|
||||
/*tirdh case: session non into list*/
|
||||
ret = pico_tftp_abort(&example_session, TFTP_ERR_EUSR, "test");
|
||||
fail_if(ret != -1);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/* Receiving functions */
|
||||
|
||||
START_TEST(tc_tftp_data)
|
||||
{
|
||||
/* TODO: test this: static void tftp_data(uint8_t *block, uint32_t len, union pico_address *a, uint16_t port) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tftp_ack)
|
||||
{
|
||||
/* TODO: test this: static void tftp_ack(uint8_t *block, uint32_t len, union pico_address *a, uint16_t port) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tftp_timeout)
|
||||
{
|
||||
/* TODO: test this: static void tftp_timeout(pico_time t) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tftp_req)
|
||||
{
|
||||
/* TODO: test this: static void tftp_req(uint8_t *block, uint32_t len, union pico_address *a, uint16_t port) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tftp_data_err)
|
||||
{
|
||||
/* TODO: test this: static void tftp_data_err(uint8_t *block, uint32_t len, union pico_address *a, uint16_t port) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tftp_fsm_timeout)
|
||||
{
|
||||
/* TODO: test this: static void tftp_fsm_timeout(pico_time now, void *arg) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tftp_receive)
|
||||
{
|
||||
/* TODO: test this: static void tftp_receive(uint8_t *block, uint32_t r, union pico_address *a, uint16_t port) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tftp_cb)
|
||||
{
|
||||
/* TODO: test this: static void tftp_cb(uint16_t ev, struct pico_socket *s) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tftp_socket_open)
|
||||
{
|
||||
/* TODO: test this: static int tftp_socket_open(uint16_t family, union pico_address *a, uint16_t port) */
|
||||
fail_if(tftp_socket_open(0xFFFF, 21) != NULL);
|
||||
fail_if(tftp_socket_open(0xFFFF, 0xFFFF) != NULL);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
Suite *pico_suite(void)
|
||||
{
|
||||
Suite *s = suite_create("PicoTCP");
|
||||
|
||||
/* TCase *TCase_check_opcode = tcase_create("Unit test for check_opcode"); */
|
||||
TCase *TCase_find_session_by_socket = tcase_create("Unit test for find_session_by_socket");
|
||||
TCase *TCase_tftp_finish = tcase_create("Unit test for tftp_finish");
|
||||
TCase *TCase_tftp_send_ack = tcase_create("Unit test for tftp_send_ack");
|
||||
TCase *TCase_tftp_send_req = tcase_create("Unit test for tftp_send_req");
|
||||
TCase *TCase_tftp_send_rx_req = tcase_create("Unit test for tftp_send_rx_req");
|
||||
TCase *TCase_tftp_send_tx_req = tcase_create("Unit test for tftp_send_tx_req");
|
||||
TCase *TCase_tftp_send_error = tcase_create("Unit test for tftp_send_error");
|
||||
TCase *TCase_tftp_send_data = tcase_create("Unit test for tftp_send_data");
|
||||
TCase *Tcase_pico_tftp_abort = tcase_create("Unit test for pico_tftp_abort");
|
||||
TCase *TCase_tftp_data = tcase_create("Unit test for tftp_data");
|
||||
TCase *TCase_tftp_ack = tcase_create("Unit test for tftp_ack");
|
||||
TCase *TCase_tftp_timeout = tcase_create("Unit test for tftp_timeout");
|
||||
TCase *TCase_tftp_req = tcase_create("Unit test for tftp_req");
|
||||
TCase *TCase_tftp_data_err = tcase_create("Unit test for tftp_data_err");
|
||||
TCase *TCase_tftp_fsm_timeout = tcase_create("Unit test for tftp_fsm_timeout");
|
||||
TCase *TCase_tftp_receive = tcase_create("Unit test for tftp_receive");
|
||||
TCase *TCase_tftp_cb = tcase_create("Unit test for tftp_cb");
|
||||
TCase *TCase_tftp_socket_open = tcase_create("Unit test for tftp_socket_open");
|
||||
|
||||
|
||||
/* tcase_add_test(TCase_check_opcode, tc_check_opcode); */
|
||||
/* suite_add_tcase(s, TCase_check_opcode); */
|
||||
tcase_add_test(TCase_find_session_by_socket, tc_find_session_by_socket);
|
||||
suite_add_tcase(s, TCase_find_session_by_socket);
|
||||
tcase_add_test(TCase_tftp_finish, tc_tftp_finish);
|
||||
suite_add_tcase(s, TCase_tftp_finish);
|
||||
tcase_add_test(TCase_tftp_send_ack, tc_tftp_send_ack);
|
||||
suite_add_tcase(s, TCase_tftp_send_ack);
|
||||
tcase_add_test(TCase_tftp_send_req, tc_tftp_send_req);
|
||||
suite_add_tcase(s, TCase_tftp_send_req);
|
||||
tcase_add_test(TCase_tftp_send_rx_req, tc_tftp_send_rx_req);
|
||||
suite_add_tcase(s, TCase_tftp_send_rx_req);
|
||||
tcase_add_test(TCase_tftp_send_tx_req, tc_tftp_send_tx_req);
|
||||
suite_add_tcase(s, TCase_tftp_send_tx_req);
|
||||
tcase_add_test(TCase_tftp_send_error, tc_tftp_send_error);
|
||||
suite_add_tcase(s, TCase_tftp_send_error);
|
||||
tcase_add_test(TCase_tftp_send_data, tc_tftp_send_data);
|
||||
suite_add_tcase(s, TCase_tftp_send_data);
|
||||
tcase_add_test(TCase_tftp_data, tc_tftp_data);
|
||||
suite_add_tcase(s, Tcase_pico_tftp_abort);
|
||||
tcase_add_test(Tcase_pico_tftp_abort, tc_pico_tftp_abort);
|
||||
suite_add_tcase(s, TCase_tftp_data);
|
||||
tcase_add_test(TCase_tftp_ack, tc_tftp_ack);
|
||||
suite_add_tcase(s, TCase_tftp_ack);
|
||||
tcase_add_test(TCase_tftp_timeout, tc_tftp_timeout);
|
||||
suite_add_tcase(s, TCase_tftp_timeout);
|
||||
tcase_add_test(TCase_tftp_req, tc_tftp_req);
|
||||
suite_add_tcase(s, TCase_tftp_req);
|
||||
tcase_add_test(TCase_tftp_data_err, tc_tftp_data_err);
|
||||
suite_add_tcase(s, TCase_tftp_data_err);
|
||||
tcase_add_test(TCase_tftp_fsm_timeout, tc_tftp_fsm_timeout);
|
||||
suite_add_tcase(s, TCase_tftp_fsm_timeout);
|
||||
tcase_add_test(TCase_tftp_receive, tc_tftp_receive);
|
||||
suite_add_tcase(s, TCase_tftp_receive);
|
||||
tcase_add_test(TCase_tftp_cb, tc_tftp_cb);
|
||||
suite_add_tcase(s, TCase_tftp_cb);
|
||||
tcase_add_test(TCase_tftp_socket_open, tc_tftp_socket_open);
|
||||
suite_add_tcase(s, TCase_tftp_socket_open);
|
||||
return s;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int fails;
|
||||
Suite *s = pico_suite();
|
||||
SRunner *sr = srunner_create(s);
|
||||
srunner_run_all(sr, CK_NORMAL);
|
||||
fails = srunner_ntests_failed(sr);
|
||||
srunner_free(sr);
|
||||
return fails;
|
||||
}
|
||||
84
kernel/picotcp/test/unit/modunit_queue.c
Normal file
84
kernel/picotcp/test/unit/modunit_queue.c
Normal file
@@ -0,0 +1,84 @@
|
||||
#include "pico_frame.h"
|
||||
#include "pico_queue.h"
|
||||
#include "stack/pico_frame.c"
|
||||
#include "pico_stack.h"
|
||||
#include "check.h"
|
||||
|
||||
|
||||
Suite *pico_suite(void);
|
||||
|
||||
struct pico_queue q1 = {
|
||||
0
|
||||
}, q2 = {
|
||||
0
|
||||
};
|
||||
|
||||
START_TEST(tc_q)
|
||||
{
|
||||
struct pico_frame *f0 = pico_frame_alloc(100);
|
||||
struct pico_frame *f1 = pico_frame_alloc(100);
|
||||
struct pico_frame *f2 = pico_frame_alloc(100);
|
||||
struct pico_frame *f3 = pico_frame_alloc(100);
|
||||
struct pico_frame *f4 = pico_frame_alloc(100);
|
||||
|
||||
pico_queue_protect(&q1);
|
||||
|
||||
q1.max_frames = 4;
|
||||
q2.max_size = 4 * 100;
|
||||
|
||||
fail_if (pico_enqueue(&q1, pico_frame_copy(f0)) < 0);
|
||||
fail_if (pico_enqueue(&q1, pico_frame_copy(f1)) < 0);
|
||||
fail_if (pico_enqueue(&q1, pico_frame_copy(f2)) < 0);
|
||||
fail_if (pico_enqueue(&q1, pico_frame_copy(f3)) < 0);
|
||||
fail_if (pico_enqueue(&q1, pico_frame_copy(f4)) >= 0);
|
||||
|
||||
fail_if (pico_enqueue(&q2, pico_frame_copy(f0)) < 0);
|
||||
fail_if (pico_enqueue(&q2, pico_frame_copy(f1)) < 0);
|
||||
fail_if (pico_enqueue(&q2, pico_frame_copy(f2)) < 0);
|
||||
fail_if (pico_enqueue(&q2, pico_frame_copy(f3)) < 0);
|
||||
fail_if (pico_enqueue(&q2, pico_frame_copy(f4)) >= 0);
|
||||
|
||||
fail_if((pico_dequeue(&q1))->buffer != f0->buffer);
|
||||
fail_if((pico_dequeue(&q1))->buffer != f1->buffer);
|
||||
fail_if((pico_dequeue(&q1))->buffer != f2->buffer);
|
||||
fail_if((pico_dequeue(&q1))->buffer != f3->buffer);
|
||||
fail_if(pico_queue_peek(&q1) != NULL);
|
||||
fail_if(pico_dequeue(&q1) != NULL);
|
||||
fail_if(q1.size != 0);
|
||||
fail_if(q1.frames != 0);
|
||||
|
||||
|
||||
pico_queue_empty(&q2);
|
||||
fail_if(q2.size != 0);
|
||||
fail_if(q2.frames != 0);
|
||||
fail_if(pico_queue_peek(&q2) != NULL);
|
||||
fail_if(pico_dequeue(&q2) != NULL);
|
||||
|
||||
pico_queue_deinit(&q1);
|
||||
pico_queue_deinit(&q2);
|
||||
|
||||
|
||||
}
|
||||
END_TEST
|
||||
|
||||
|
||||
Suite *pico_suite(void)
|
||||
{
|
||||
Suite *s = suite_create("Packet Queues");
|
||||
|
||||
TCase *TCase_q = tcase_create("Unit test for pico_queue.c");
|
||||
tcase_add_test(TCase_q, tc_q);
|
||||
suite_add_tcase(s, TCase_q);
|
||||
return s;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int fails;
|
||||
Suite *s = pico_suite();
|
||||
SRunner *sr = srunner_create(s);
|
||||
srunner_run_all(sr, CK_NORMAL);
|
||||
fails = srunner_ntests_failed(sr);
|
||||
srunner_free(sr);
|
||||
return fails;
|
||||
}
|
||||
59
kernel/picotcp/test/unit/modunit_seq.c
Normal file
59
kernel/picotcp/test/unit/modunit_seq.c
Normal file
@@ -0,0 +1,59 @@
|
||||
#include "pico_tcp.c"
|
||||
#include <check.h>
|
||||
|
||||
Suite *pico_suite(void);
|
||||
|
||||
START_TEST(tc_seq_compare)
|
||||
{
|
||||
uint32_t big_a = 0xFFFFFF0alu;
|
||||
uint32_t big_b = 0xFFFFFF0blu;
|
||||
uint32_t small_a = 0xalu;
|
||||
uint32_t small_b = 0xblu;
|
||||
uint32_t under_thresh = 0x7ffffffflu;
|
||||
uint32_t over_thresh = 0x80000000lu;
|
||||
uint32_t zero = 0lu;
|
||||
|
||||
fail_if(pico_seq_compare(small_a, small_b) >= 0);
|
||||
fail_if(pico_seq_compare(small_b, small_a) <= 0);
|
||||
|
||||
fail_if(pico_seq_compare(over_thresh, under_thresh) <= 0);
|
||||
fail_if(pico_seq_compare(under_thresh, over_thresh) >= 0);
|
||||
|
||||
fail_if(pico_seq_compare(small_a, big_b) <= 0);
|
||||
fail_if(pico_seq_compare(big_b, small_a) >= 0);
|
||||
|
||||
fail_if(pico_seq_compare(small_a, zero) <= 0);
|
||||
fail_if(pico_seq_compare(zero, small_a) >= 0);
|
||||
|
||||
fail_if(pico_seq_compare(big_a, zero) >= 0);
|
||||
fail_if(pico_seq_compare(zero, big_a) <= 0);
|
||||
|
||||
fail_if(pico_seq_compare(big_a, big_b) >= 0);
|
||||
fail_if(pico_seq_compare(big_b, big_a) <= 0);
|
||||
|
||||
fail_if(pico_seq_compare(big_a, big_a) != 0);
|
||||
fail_if(pico_seq_compare(zero, zero) != 0);
|
||||
|
||||
}
|
||||
END_TEST
|
||||
|
||||
Suite *pico_suite(void)
|
||||
{
|
||||
Suite *s = suite_create("pico tcp sequence numbers");
|
||||
TCase *TCase_seq_compare = tcase_create("Unit test for pico_seq_compare");
|
||||
tcase_add_test(TCase_seq_compare, tc_seq_compare);
|
||||
suite_add_tcase(s, TCase_seq_compare);
|
||||
return s;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int fails;
|
||||
Suite *s = pico_suite();
|
||||
SRunner *sr = srunner_create(s);
|
||||
srunner_run_all(sr, CK_NORMAL);
|
||||
fails = srunner_ntests_failed(sr);
|
||||
srunner_free(sr);
|
||||
return fails;
|
||||
}
|
||||
|
||||
213
kernel/picotcp/test/unit/unit_arp.c
Normal file
213
kernel/picotcp/test/unit/unit_arp.c
Normal file
@@ -0,0 +1,213 @@
|
||||
#include "pico_ethernet.c"
|
||||
|
||||
static struct pico_frame *init_frame(struct pico_device *dev)
|
||||
{
|
||||
struct pico_frame *f = pico_frame_alloc(PICO_SIZE_ETHHDR + PICO_SIZE_ARPHDR);
|
||||
f->net_hdr = f->buffer + PICO_SIZE_ETHHDR;
|
||||
f->datalink_hdr = f->buffer;
|
||||
f->dev = dev;
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
START_TEST (arp_update_max_arp_reqs_test)
|
||||
{
|
||||
pico_stack_init();
|
||||
max_arp_reqs = 0;
|
||||
usleep((PICO_ARP_INTERVAL + 1) * 1000);
|
||||
pico_stack_tick();
|
||||
fail_unless(max_arp_reqs > 0);
|
||||
|
||||
max_arp_reqs = PICO_ARP_MAX_RATE;
|
||||
usleep((PICO_ARP_INTERVAL + 1) * 1000);
|
||||
pico_stack_tick();
|
||||
fail_unless(max_arp_reqs == PICO_ARP_MAX_RATE);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST (arp_compare_test)
|
||||
{
|
||||
struct pico_arp a, b;
|
||||
char ipstr[] = "192.168.1.1";
|
||||
|
||||
memset(&a, 0, sizeof(a));
|
||||
pico_string_to_ipv4(ipstr, &b.ipv4.addr);
|
||||
|
||||
fail_unless(arp_compare(&a, &b) == -1);
|
||||
fail_unless(arp_compare(&b, &a) == 1);
|
||||
fail_unless(arp_compare(&a, &a) == 0);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST (arp_lookup_test)
|
||||
{
|
||||
struct pico_ip4 ip;
|
||||
struct pico_eth *eth = NULL;
|
||||
char ipstr[] = "192.168.1.1";
|
||||
struct pico_arp entry;
|
||||
|
||||
eth = pico_arp_lookup(&ip);
|
||||
fail_unless(eth == NULL);
|
||||
|
||||
pico_string_to_ipv4(ipstr, &ip.addr);
|
||||
entry.ipv4 = ip;
|
||||
|
||||
pico_stack_init();
|
||||
fail_unless(pico_arp_add_entry(&entry) == 0);
|
||||
entry.arp_status = PICO_ARP_STATUS_STALE;
|
||||
eth = pico_arp_lookup(&ip);
|
||||
fail_unless(eth == NULL);
|
||||
pico_tree_delete(&arp_tree, &entry);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST (arp_expire_test)
|
||||
{
|
||||
struct pico_arp entry;
|
||||
entry.arp_status = PICO_ARP_STATUS_REACHABLE;
|
||||
entry.timestamp = 0;
|
||||
|
||||
arp_expire(PICO_ARP_TIMEOUT, &entry);
|
||||
fail_unless(entry.arp_status == PICO_ARP_STATUS_STALE);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_pico_arp_queue)
|
||||
{
|
||||
struct pico_ip4 addr = {
|
||||
.addr = 0xaabbccdd
|
||||
};
|
||||
int i;
|
||||
struct pico_frame *f = pico_frame_alloc(sizeof(struct pico_ipv4_hdr));
|
||||
struct pico_ipv4_hdr *h = (struct pico_ipv4_hdr *) f->buffer;
|
||||
fail_if(!f);
|
||||
f->net_hdr = (uint8_t *)h;
|
||||
h->dst.addr = addr.addr;
|
||||
|
||||
for (i = 0; i < PICO_ND_MAX_FRAMES_QUEUED; i++) {
|
||||
fail_if(frames_queued[i] != NULL);
|
||||
}
|
||||
pico_arp_unreachable(&addr);
|
||||
for (i = 0; i < PICO_ND_MAX_FRAMES_QUEUED; i++) {
|
||||
fail_if(frames_queued[i] != NULL);
|
||||
}
|
||||
pico_arp_postpone(f);
|
||||
fail_if(frames_queued[0]->buffer != f->buffer);
|
||||
pico_arp_unreachable(&addr);
|
||||
PICO_FREE(f);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
|
||||
|
||||
START_TEST (arp_receive_test)
|
||||
{
|
||||
struct mock_device *mock;
|
||||
struct pico_frame *f = NULL;
|
||||
struct pico_arp_hdr *ah = NULL;
|
||||
struct pico_eth_hdr *eh = NULL;
|
||||
uint8_t macaddr1[6] = {
|
||||
0, 0, 0, 0xa, 0xb, 0xf
|
||||
};
|
||||
uint8_t macaddr2[6] = {
|
||||
0, 0, 0, 0xc, 0xd, 0xf
|
||||
};
|
||||
struct pico_ip4 netmask = {
|
||||
.addr = long_be(0xffffff00)
|
||||
};
|
||||
struct pico_ip4 ip1 = {
|
||||
.addr = long_be(0x0A2800AA)
|
||||
};
|
||||
struct pico_ip4 ip2 = {
|
||||
.addr = long_be(0x0A2800AB)
|
||||
};
|
||||
|
||||
pico_stack_init();
|
||||
|
||||
/* Create mock device */
|
||||
mock = pico_mock_create(macaddr1);
|
||||
fail_if(!mock, "MOCK DEVICE creation failed");
|
||||
fail_if(pico_ipv4_link_add(mock->dev, ip1, netmask), "add link to mock device failed");
|
||||
|
||||
/* Normal ARP request */
|
||||
f = init_frame(mock->dev);
|
||||
fail_if(!f, "FRAME INIT failed");
|
||||
eh = (struct pico_eth_hdr *) f->datalink_hdr;
|
||||
ah = (struct pico_arp_hdr *) f->net_hdr;
|
||||
|
||||
memcpy(eh->saddr, macaddr2, PICO_SIZE_ETH);
|
||||
memcpy(eh->daddr, PICO_ETHADDR_ALL, PICO_SIZE_ETH);
|
||||
eh->proto = PICO_IDETH_ARP;
|
||||
|
||||
ah->htype = PICO_ARP_HTYPE_ETH;
|
||||
ah->ptype = PICO_IDETH_IPV4;
|
||||
ah->hsize = PICO_SIZE_ETH;
|
||||
ah->psize = PICO_SIZE_IP4;
|
||||
ah->opcode = PICO_ARP_REQUEST;
|
||||
memcpy(ah->s_mac, macaddr2, PICO_SIZE_ETH);
|
||||
ah->src.addr = ip2.addr;
|
||||
ah->dst.addr = ip1.addr;
|
||||
fail_unless(pico_arp_receive(f) == 0);
|
||||
|
||||
/* net_hdr is a nullpointer */
|
||||
f = init_frame(mock->dev);
|
||||
fail_if(!f, "FRAME INIT failed");
|
||||
f->net_hdr = NULL;
|
||||
fail_unless(pico_arp_receive(f) == -1);
|
||||
|
||||
/* wrong hardware type */
|
||||
f = init_frame(mock->dev);
|
||||
fail_if(!f, "FRAME INIT failed");
|
||||
ah = (struct pico_arp_hdr *) f->net_hdr;
|
||||
ah->htype = 0;
|
||||
fail_unless(pico_arp_receive(f) == -1);
|
||||
|
||||
/* wrong protocol type */
|
||||
f = init_frame(mock->dev);
|
||||
fail_if(!f, "FRAME INIT failed");
|
||||
ah = (struct pico_arp_hdr *) f->net_hdr;
|
||||
ah->ptype = 0;
|
||||
fail_unless(pico_arp_receive(f) == -1);
|
||||
|
||||
/* source mac address is multicast */
|
||||
f = init_frame(mock->dev);
|
||||
fail_if(!f, "FRAME INIT failed");
|
||||
ah = (struct pico_arp_hdr *) f->net_hdr;
|
||||
ah->s_mac[0] = 0x01;
|
||||
fail_unless(pico_arp_receive(f) == -1);
|
||||
pico_ipv4_link_del(mock->dev, ip1);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST (arp_get_test)
|
||||
{
|
||||
struct pico_frame *f = NULL;
|
||||
struct mock_device *mock;
|
||||
struct pico_ipv4_hdr *hdr = NULL;
|
||||
struct pico_eth *eth = NULL;
|
||||
uint8_t macaddr[6] = {
|
||||
0, 0, 0xa, 0xa, 0xb, 0xf
|
||||
};
|
||||
struct pico_ip4 netmask = {
|
||||
.addr = long_be(0xffffff00)
|
||||
};
|
||||
struct pico_ip4 ip = {
|
||||
.addr = long_be(0x0A28000B)
|
||||
};
|
||||
|
||||
mock = pico_mock_create(macaddr);
|
||||
fail_if(!mock, "MOCK DEVICE creation failed");
|
||||
fail_if(pico_ipv4_link_add(mock->dev, ip, netmask), "add link to mock device failed");
|
||||
|
||||
f = pico_frame_alloc(PICO_SIZE_ETHHDR + sizeof(struct pico_ipv4_hdr));
|
||||
f->net_hdr = f->start + PICO_SIZE_ETHHDR;
|
||||
f->datalink_hdr = f->start;
|
||||
f->dev = mock->dev;
|
||||
|
||||
hdr = (struct pico_ipv4_hdr *) f->net_hdr;
|
||||
hdr->dst.addr = ip.addr;
|
||||
eth = pico_arp_get(f);
|
||||
fail_unless(eth == &mock->dev->eth->mac);
|
||||
pico_ipv4_link_del(mock->dev, ip);
|
||||
}
|
||||
END_TEST
|
||||
554
kernel/picotcp/test/unit/unit_dhcp.c
Normal file
554
kernel/picotcp/test/unit/unit_dhcp.c
Normal file
@@ -0,0 +1,554 @@
|
||||
|
||||
static struct pico_dhcp_client_cookie*dhcp_client_ptr;
|
||||
|
||||
void callback_dhcpclient(void*cli, int code);
|
||||
int generate_dhcp_msg(uint8_t *buf, uint32_t *len, uint8_t type);
|
||||
|
||||
void callback_dhcpclient(void*cli, int code)
|
||||
{
|
||||
struct pico_ip4 gateway;
|
||||
char gw_txt_addr[30];
|
||||
IGNORE_PARAMETER(cli);
|
||||
|
||||
if(code == PICO_DHCP_SUCCESS) {
|
||||
gateway = pico_dhcp_get_gateway(&dhcp_client_ptr);
|
||||
pico_ipv4_to_string(gw_txt_addr, gateway.addr);
|
||||
}
|
||||
|
||||
printf("callback happened with code %d!\n", code);
|
||||
}
|
||||
|
||||
int generate_dhcp_msg(uint8_t *buf, uint32_t *len, uint8_t type)
|
||||
{
|
||||
if(type == DHCP_MSG_TYPE_DISCOVER) {
|
||||
uint8_t buffer[] = {
|
||||
0x01, 0x01, 0x06, 0x00, 0x0c, 0x10,
|
||||
0x53, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x0a, 0x0b, 0x0f, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, 0x53, 0x63, 0x35, 0x01, 0x01, 0x37, 0x07, 0x01,
|
||||
0x1c, 0x02, 0x03, 0x0c, 0x3a, 0x3b, 0x39, 0x02, 0x02, 0x40, 0xff, 0x00
|
||||
};
|
||||
*len = sizeof(buffer);
|
||||
memcpy(&(buf[0]), buffer, *len);
|
||||
}else if(type == DHCP_MSG_TYPE_OFFER) {
|
||||
return 1;
|
||||
}else if(type == DHCP_MSG_TYPE_REQUEST) {
|
||||
uint32_t i = 0;
|
||||
uint8_t buffer1[] = {
|
||||
/* 0x63,0x82,0x53,0x63,// MAGIC COOCKIE */
|
||||
/* 0x35,0x01,0x03, // DHCP REQUEST */
|
||||
/* 0x36,0x04,0x00,0x00,0x00,0x00 // SERVER ID */
|
||||
0x32, 0x04, buf[0x3a], buf[0x3b], buf[0x3c], buf[0x3e], /* requested ip */
|
||||
0x37, 0x04, 0x01, 0x03, 0x06, 0x2a, /* Parameter list */
|
||||
0x3d, 0x07, 0x01, buf[0x06], buf[0x07], buf[0x08], buf[0x09], buf[0x0a], buf[0x0b], /* Client id */
|
||||
0xff
|
||||
};
|
||||
|
||||
buf[0x02a] = 0x01; /* change to boot request */
|
||||
buf[0x11c] = 0x03; /* request */
|
||||
|
||||
memcpy(&(buf[0x123]), &(buffer1[0]), sizeof(buffer1));
|
||||
*len = sizeof(buffer1) + 0x123;
|
||||
for(i = *len; i < 0x150; i++) {
|
||||
buf[i + 10] = 0x00;
|
||||
}
|
||||
return 0;
|
||||
}else if(type == DHCP_MSG_TYPE_ACK) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
START_TEST (test_dhcp_server_api)
|
||||
{
|
||||
/************************************************************************
|
||||
* Check if dhcp recv works correctly if
|
||||
* MAC address of client is not in arp table yet
|
||||
* Status : Done
|
||||
************************************************************************/
|
||||
|
||||
struct mock_device *mock;
|
||||
uint8_t macaddr1[6] = {
|
||||
0xc1, 0, 0, 0xa, 0xb, 0xf
|
||||
};
|
||||
struct pico_ip4 netmask = {
|
||||
.addr = long_be(0xffffff00)
|
||||
};
|
||||
struct pico_ip4 serverip = {
|
||||
.addr = long_be(0x0A28000A)
|
||||
};
|
||||
uint8_t buf[600] = {
|
||||
0
|
||||
};
|
||||
/* Declaration test 1 */
|
||||
struct pico_dhcp_server_setting s1 = {
|
||||
0
|
||||
};
|
||||
/* Declaration test 2 */
|
||||
struct pico_dhcp_server_setting s2 = {
|
||||
0
|
||||
};
|
||||
|
||||
printf("*********************** starting %s * \n", __func__);
|
||||
|
||||
/* Create mock device */
|
||||
mock = pico_mock_create(macaddr1);
|
||||
fail_if(!mock, "MOCK DEVICE creation failed");
|
||||
fail_if(pico_mock_network_read(mock, buf, BUFLEN), "data on network that shouldn't be there");
|
||||
fail_if(pico_ipv4_link_add(mock->dev, serverip, netmask), "add link to mock device failed");
|
||||
|
||||
/* test 0 */
|
||||
/* Clear error code */
|
||||
pico_err = PICO_ERR_NOERR;
|
||||
/* Test 0 statements */
|
||||
fail_unless(pico_dhcp_server_initiate(NULL), "DHCP_SERVER> initiate succeeded after pointer to dev == NULL");
|
||||
fail_unless(pico_err == PICO_ERR_EINVAL, "DHCP_SERVER> initiate succeeded without PICO_ERR_EINVAL after wrong parameter");
|
||||
|
||||
/* test 1 */
|
||||
/* Clear error code */
|
||||
pico_err = PICO_ERR_NOERR;
|
||||
/* Store data in settings */
|
||||
s1.server_ip.addr = long_be(0x0A28000F); /* make sure this IP is not assigned */
|
||||
/* Test 1 statements */
|
||||
fail_unless(pico_dhcp_server_initiate(&s1), "DHCP_SERVER> initiate succeeded after pointer to dev == NULL");
|
||||
fail_unless(pico_err == PICO_ERR_EINVAL, "DHCP_SERVER> initiate succeeded without PICO_ERR_EINVAL after wrong parameter");
|
||||
|
||||
/* test 2 */
|
||||
/* Clear error code */
|
||||
pico_err = PICO_ERR_NOERR;
|
||||
/* Store data in settings */
|
||||
s2.server_ip = serverip;
|
||||
/* Test 2 statements */
|
||||
fail_if(pico_dhcp_server_initiate(&s2), "DHCP_SERVER> failed after correct parameter");
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST (test_dhcp)
|
||||
{
|
||||
/************************************************************************
|
||||
* Check if all states (offer, bound) are changed correctly
|
||||
* and if response messages are replied correctly
|
||||
* Status : Done
|
||||
*************************************************************************/
|
||||
struct mock_device*mock;
|
||||
struct pico_dhcp_server_setting s = {
|
||||
0
|
||||
};
|
||||
struct pico_ip4 xid = {
|
||||
.addr = long_be(0x00003d1d)
|
||||
};
|
||||
uint8_t macaddr1[6] = {
|
||||
0xc1, 0, 0, 0xa, 0xb, 0xf
|
||||
};
|
||||
uint8_t macaddr2[6] = {
|
||||
0xc6, 0, 0, 0xa, 0xb, 0xf
|
||||
};
|
||||
struct pico_ip4 netmask = {
|
||||
.addr = long_be(0xffffff00)
|
||||
};
|
||||
struct pico_ip4 serverip = {
|
||||
.addr = long_be(0x0A28000A)
|
||||
};
|
||||
struct pico_socket sock = { };
|
||||
struct pico_dhcp_server_negotiation *dn = NULL;
|
||||
struct pico_ip4 *stored_ipv4 = NULL;
|
||||
uint32_t len = 0;
|
||||
int network_read = 0;
|
||||
uint8_t *buf;
|
||||
uint8_t printbufactive = 0;
|
||||
|
||||
buf = PICO_ZALLOC(600);
|
||||
|
||||
printf("*********************** starting %s * \n", __func__);
|
||||
|
||||
/*Insert custom values in buffer*/
|
||||
fail_if(generate_dhcp_msg(buf, &len, DHCP_MSG_TYPE_DISCOVER), "DHCP_SERVER->failed to generate buffer");
|
||||
memcpy(&(buf[4]), &(xid.addr), sizeof(struct pico_ip4));
|
||||
memcpy(&(buf[28]), &(macaddr1[0]), sizeof(struct pico_ip4));
|
||||
printbuf(&(buf[0]), len, "DHCP-DISCOVER packet", printbufactive);
|
||||
|
||||
/*Initiate test setup*/
|
||||
pico_stack_init();
|
||||
|
||||
/* Create mock device */
|
||||
mock = pico_mock_create(macaddr2);
|
||||
fail_if(!mock, "MOCK DEVICE creation failed");
|
||||
fail_if(pico_mock_network_read(mock, buf, BUFLEN), "data on network that shouldn't be there");
|
||||
fail_if(pico_ipv4_link_add(mock->dev, serverip, netmask), "add link to mock device failed");
|
||||
|
||||
s.server_ip = serverip;
|
||||
|
||||
fail_if(pico_dhcp_server_initiate(&s), "DHCP_SERVER> server initiation failed");
|
||||
|
||||
dn = pico_dhcp_server_find_negotiation(xid.addr);
|
||||
fail_unless(dn == NULL, "DCHP SERVER -> negotiation data available befor discover msg recvd");
|
||||
|
||||
/* simulate reception of a DISCOVER packet */
|
||||
sock.local_addr.ip4 = serverip;
|
||||
pico_dhcp_server_recv(&sock, buf, len);
|
||||
|
||||
tick_it(3);
|
||||
|
||||
/* check if negotiation data is stored */
|
||||
dn = pico_dhcp_server_find_negotiation(xid.addr);
|
||||
fail_if(dn == NULL, "DCHP SERVER -> no negotiation stored after discover msg recvd");
|
||||
|
||||
/* check if new ip is in ARP cache */
|
||||
stored_ipv4 = pico_arp_reverse_lookup(&dn->hwaddr);
|
||||
fail_if(stored_ipv4 == NULL, "DCHP SERVER -> new address is not inserted in ARP");
|
||||
fail_unless(stored_ipv4->addr == dn->ciaddr.addr, "DCHP SERVER -> new ip not stored in negotiation data");
|
||||
|
||||
/* check if state is changed and reply is received */
|
||||
network_read = pico_mock_network_read(mock, buf, BUFLEN);
|
||||
fail_unless(network_read > 0, "received msg on network of %u bytes", network_read);
|
||||
printbuf(&(buf[0]), (uint32_t)network_read, "DHCP-OFFER msg", printbufactive);
|
||||
fail_unless(buf[0x011c] == 0x02, "No DHCP offer received after discovery");
|
||||
fail_unless(dn->state == PICO_DHCP_STATE_OFFER, "DCHP SERVER -> negotiation state not changed to OFFER");
|
||||
|
||||
/*change offer to request*/
|
||||
fail_if(generate_dhcp_msg(buf, &len, DHCP_MSG_TYPE_REQUEST), "DHCP_SERVER->failed to generate buffer");
|
||||
printbuf(&(buf[0x2a]), len - 0x2a, "request buffer", printbufactive);
|
||||
|
||||
/* simulate reception of a offer packet */
|
||||
pico_dhcp_server_recv(&sock, &(buf[0x2a]), len - 0x2a);
|
||||
fail_unless(dn->state == PICO_DHCP_STATE_BOUND, "DCHP SERVER -> negotiation state not changed to BOUND");
|
||||
|
||||
tick_it(3);
|
||||
|
||||
/* check if state is changed and reply is received */
|
||||
do {
|
||||
network_read = pico_mock_network_read(mock, buf, BUFLEN);
|
||||
} while (buf[0] == 0x33);
|
||||
printf("Received message: %d bytes\n", network_read);
|
||||
fail_unless(network_read > 0, "received msg on network of %d bytes", network_read);
|
||||
printbuf(&(buf[0]), (uint32_t)network_read, "DHCP-ACK msg", printbufactive);
|
||||
fail_unless(buf[0x11c] == 0x05, "No DHCP ACK received after discovery");
|
||||
}
|
||||
END_TEST
|
||||
|
||||
|
||||
START_TEST (test_dhcp_server_ipninarp)
|
||||
{
|
||||
/************************************************************************
|
||||
* Check if dhcp recv works correctly if
|
||||
* MAC address of client is not in arp table yet
|
||||
* Status : Done
|
||||
*************************************************************************/
|
||||
struct mock_device*mock;
|
||||
struct pico_dhcp_server_setting s = {
|
||||
0
|
||||
};
|
||||
struct pico_ip4 xid = {
|
||||
.addr = long_be(0x00003d1d)
|
||||
};
|
||||
struct pico_ip4 netmask = {
|
||||
.addr = long_be(0xffffff00)
|
||||
};
|
||||
struct pico_ip4 serverip = {
|
||||
.addr = long_be(0x0A28000A)
|
||||
};
|
||||
struct pico_socket sock = { };
|
||||
struct pico_dhcp_server_negotiation *dn = NULL;
|
||||
struct pico_ip4 *stored_ipv4 = NULL;
|
||||
unsigned char macaddr1[6] = {
|
||||
0xc1, 0, 0, 0xa, 0xb, 0xf
|
||||
};
|
||||
uint32_t len = 0;
|
||||
uint8_t buf[600] = {
|
||||
0
|
||||
};
|
||||
uint8_t printbufactive = 0;
|
||||
|
||||
printf("*********************** starting %s * \n", __func__);
|
||||
|
||||
/*Insert custom values in buffer*/
|
||||
fail_if(generate_dhcp_msg(buf, &len, DHCP_MSG_TYPE_DISCOVER), "DHCP_SERVER->failed to generate buffer");
|
||||
memcpy(&(buf[4]), &(xid.addr), sizeof(struct pico_ip4));
|
||||
memcpy(&(buf[28]), &(macaddr1[0]), sizeof(struct pico_ip4));
|
||||
printbuf(&(buf[0]), len, "DHCP-DISCOVER packet", printbufactive);
|
||||
|
||||
/*Initiate test setup*/
|
||||
pico_stack_init();
|
||||
|
||||
/* Create mock device */
|
||||
mock = pico_mock_create(macaddr1);
|
||||
fail_if(!mock, "MOCK DEVICE creation failed");
|
||||
fail_if(pico_mock_network_read(mock, buf, BUFLEN), "data on network that shouldn't be there");
|
||||
fail_if(pico_ipv4_link_add(mock->dev, serverip, netmask), "add link to mock device failed");
|
||||
s.server_ip = serverip;
|
||||
|
||||
fail_if(pico_dhcp_server_initiate(&s), "DHCP_SERVER> server initiation failed");
|
||||
|
||||
dn = pico_dhcp_server_find_negotiation(xid.addr);
|
||||
fail_unless(dn == NULL, "DCHP SERVER -> negotiation data available before discover msg recvd");
|
||||
|
||||
/* simulate reception of a DISCOVER packet */
|
||||
sock.local_addr.ip4 = serverip;
|
||||
pico_dhcp_server_recv(&sock, buf, len);
|
||||
|
||||
/* check if negotiation data is stored */
|
||||
dn = pico_dhcp_server_find_negotiation(xid.addr);
|
||||
fail_if(dn == NULL, "DCHP SERVER -> no negotiation stored after discover msg recvd");
|
||||
|
||||
/* check if new ip is in ARP cache */
|
||||
stored_ipv4 = pico_arp_reverse_lookup(&dn->hwaddr);
|
||||
fail_if(stored_ipv4 == NULL, "DCHP SERVER -> new address is not inserted in ARP");
|
||||
fail_unless(stored_ipv4->addr == dn->ciaddr.addr, "DCHP SERVER -> new ip not stored in negotiation data");
|
||||
|
||||
/* check if new ip is in ARP cache */
|
||||
fail_if(pico_arp_reverse_lookup(&dn->hwaddr) == NULL, "DCHP SERVER -> new address is not inserted in ARP");
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST (test_dhcp_server_ipinarp)
|
||||
{
|
||||
/************************************************************************
|
||||
* Check if dhcp recv works correctly if
|
||||
* MAC address of client is allready in arp table
|
||||
* Status : Done
|
||||
*************************************************************************/
|
||||
struct mock_device*mock;
|
||||
struct pico_dhcp_server_setting s = {
|
||||
0
|
||||
};
|
||||
struct pico_ip4 ipv4address = {
|
||||
.addr = long_be(0x0a280067)
|
||||
};
|
||||
struct pico_ip4 xid = {
|
||||
.addr = long_be(0x00003d1d)
|
||||
};
|
||||
struct pico_ip4 netmask = {
|
||||
.addr = long_be(0xffffff00)
|
||||
};
|
||||
struct pico_ip4 serverip = {
|
||||
.addr = long_be(0x0A28000A)
|
||||
};
|
||||
struct pico_socket sock = { };
|
||||
struct pico_ip4 *stored_ipv4 = NULL;
|
||||
struct pico_dhcp_server_negotiation *dn = NULL;
|
||||
struct pico_eth *arp_resp = NULL;
|
||||
unsigned char macaddr1[6] = {
|
||||
0xc1, 0, 0, 0xa, 0xb, 0xf
|
||||
};
|
||||
uint32_t len = 0;
|
||||
uint8_t buf[600] = {
|
||||
0
|
||||
};
|
||||
|
||||
printf("*********************** starting %s * \n", __func__);
|
||||
|
||||
/*Insert custom values in buffer*/
|
||||
fail_if(generate_dhcp_msg(buf, &len, DHCP_MSG_TYPE_DISCOVER), "DHCP_SERVER->failed to generate buffer");
|
||||
memcpy(&(buf[28]), &(macaddr1[0]), sizeof(struct pico_ip4));
|
||||
memcpy(&(buf[4]), &(xid.addr), sizeof(struct pico_ip4));
|
||||
|
||||
/* Create mock device */
|
||||
mock = pico_mock_create(macaddr1);
|
||||
fail_if(!mock, "MOCK DEVICE creation failed");
|
||||
fail_if(pico_ipv4_link_add(mock->dev, serverip, netmask), "add link to mock device failed");
|
||||
s.server_ip = serverip;
|
||||
|
||||
/*Initiate test setup*/
|
||||
pico_stack_init();
|
||||
pico_arp_create_entry(&(macaddr1[0]), ipv4address, s.dev);
|
||||
|
||||
fail_if(pico_dhcp_server_initiate(&s), "DHCP_SERVER> server initiation failed");
|
||||
|
||||
/* simulate reception of a DISCOVER packet */
|
||||
sock.local_addr.ip4 = serverip;
|
||||
pico_dhcp_server_recv(&sock, buf, len);
|
||||
|
||||
/* check if negotiation data is stored */
|
||||
dn = pico_dhcp_server_find_negotiation(xid.addr);
|
||||
fail_if(dn == NULL, "DCHP SERVER -> no negotiation stored after discover msg recvd");
|
||||
|
||||
/* check if new ip is in ARP cache */
|
||||
stored_ipv4 = pico_arp_reverse_lookup(&dn->hwaddr);
|
||||
fail_if(stored_ipv4 == NULL, "DCHP SERVER -> new address is not inserted in ARP");
|
||||
fail_unless(stored_ipv4->addr == dn->ciaddr.addr, "DCHP SERVER -> new ip not stored in negotiation data");
|
||||
|
||||
/* check if new ip is in ARP cache */
|
||||
arp_resp = pico_arp_lookup(&ipv4address);
|
||||
fail_if(arp_resp == NULL, "DCHP SERVER -> address unavailable in arp cache");
|
||||
}
|
||||
END_TEST
|
||||
|
||||
#if 0
|
||||
START_TEST (test_dhcp_client)
|
||||
{
|
||||
struct mock_device*mock;
|
||||
uint32_t dhcp_hdr_offset = PICO_SIZE_ETHHDR + PICO_SIZE_IP4HDR + PICO_UDPHDR_SIZE;
|
||||
unsigned char macaddr1[6] = {
|
||||
0xc1, 0, 0, 0xa, 0xb, 0xf
|
||||
};
|
||||
struct pico_ip4 address = {
|
||||
0
|
||||
};
|
||||
struct pico_ip4 yiaddr = {
|
||||
.addr = long_be(0xC0A8000A)
|
||||
};
|
||||
struct pico_ip4 gateway = {
|
||||
0
|
||||
};
|
||||
struct pico_ip4 router = {
|
||||
.addr = long_be(0xC0A800FE)
|
||||
};
|
||||
uint8_t buf[BUFLEN] = {
|
||||
0
|
||||
};
|
||||
uint8_t offer_buf1[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0xC0, 0xA8, 0x00, 0x01
|
||||
};
|
||||
uint8_t offer_buf2[] = {
|
||||
0x63, 0x82, 0x53, 0x63, 0x35, 0x01, 0x02, 0x01, 0x04, 0xff, 0xff, 0xff, 0x00, 0x3a, 0x04, 0x00, 0x00, 0x07, 0x08, 0x3b, 0x04, 0x00, 0x00, 0x0c, 0x4e, 0x33, 0x04, 0x00, 0x00, 0x0e, 0x10, 0x36, 0x04, 0xc0, 0xa8, 0x00, 0x01, 0xff
|
||||
};
|
||||
uint8_t routeropt_buf[] = {
|
||||
PICO_DHCPOPT_ROUTER, 0x04, 0xC0, 0xA8, 0x00, 0xFE, 0xFF
|
||||
};
|
||||
int type = 0;
|
||||
uint8_t printbufactive = 0;
|
||||
uint32_t len = 0;
|
||||
uint32_t xid = 0;
|
||||
struct pico_dhcp_client_cookie *cli = NULL;
|
||||
|
||||
pico_stack_init();
|
||||
|
||||
/* Create mock device */
|
||||
mock = pico_mock_create(macaddr1);
|
||||
fail_if(!mock, "MOCK DEVICE creation failed");
|
||||
fail_if(pico_mock_network_read(mock, buf, BUFLEN), "data on network that shouldn't be there");
|
||||
|
||||
/* initiate negotiation -> change state to */
|
||||
pico_dhcp_initiate_negotiation(mock->dev, &callback_dhcpclient, &xid);
|
||||
cli = get_cookie_by_xid(xid);
|
||||
dhcp_client_ptr = cli;
|
||||
fail_if(cli == NULL, "initiate fail");
|
||||
fail_unless(cli->state == DHCPSTATE_DISCOVER, "Not in discover state after init negotiate");
|
||||
fail_if(pico_mock_network_read(mock, buf, BUFLEN), "data on network that shouldn't be there");
|
||||
|
||||
/* push discover msg on network */
|
||||
tick_it(3);
|
||||
|
||||
/* read discover message from network */
|
||||
len = pico_mock_network_read(mock, buf, BUFLEN );
|
||||
fail_unless(len, "No msg received on network!");
|
||||
printbuf(&(buf[0]), len, "DHCP-DISCOVER packet", printbufactive);
|
||||
fail_unless(buf[0x011c] == 0x01, "No DHCP Discover received after initiate negotiation");
|
||||
mock_print_protocol(buf);
|
||||
fail_if(pico_mock_network_read(mock, buf, BUFLEN), "data on network that shouldn't be there");
|
||||
|
||||
/* check API access functions */
|
||||
address = pico_dhcp_get_address(cli);
|
||||
fail_unless(address.addr == 0, "Client address gets value at init -> should get it from dhcp server");
|
||||
|
||||
gateway = pico_dhcp_get_gateway(cli);
|
||||
fail_unless(gateway.addr == 0, "Gateway gets value at init -> should get it from dhcp server ");
|
||||
|
||||
/* Change received discovery msg to offer offer msg */
|
||||
buf[0x2a] = 0x02;
|
||||
memcpy(&(buf[0x3a]), &(offer_buf1[0]), sizeof(offer_buf1));
|
||||
memcpy(&(buf[0x3a]), &(yiaddr.addr), sizeof(struct pico_ip4));
|
||||
memcpy(&(buf[0x116]), &(offer_buf2[0]), sizeof(offer_buf2));
|
||||
memcpy(&(buf[0x13b]), &(routeropt_buf[0]), sizeof(routeropt_buf));
|
||||
memcpy(&(buf[0x13d]), &(router.addr), sizeof(struct pico_ip4));
|
||||
printbuf(&(buf[dhcp_hdr_offset]), len - dhcp_hdr_offset, "DHCP-OFFER message", printbufactive);
|
||||
|
||||
/* generate dhcp type from msg */
|
||||
type = pico_dhcp_verify_and_identify_type(&(buf[dhcp_hdr_offset]), len - dhcp_hdr_offset, cli);
|
||||
fail_if(type == 0, "unkown DHCP type");
|
||||
|
||||
/* simulate reception of a DHCP server offer */
|
||||
pico_dhcp_state_machine(type, cli, &(buf[dhcp_hdr_offset]), len - dhcp_hdr_offset);
|
||||
fail_if(cli->state == DHCPSTATE_DISCOVER, "still in discover state after dhcp server offer");
|
||||
fail_unless(cli->state == DHCPSTATE_REQUEST, "not in REQUEST state after dhcp server offer");
|
||||
|
||||
address = pico_dhcp_get_address(cli);
|
||||
fail_unless(address.addr == yiaddr.addr, "Client address incorrect => yiaddr or pico_dhcp_get_address incorrect");
|
||||
gateway = pico_dhcp_get_gateway(cli);
|
||||
fail_unless(gateway.addr == router.addr, "Gateway incorrect! => routeroption or pico_dhcp_get_gateway incorrect");
|
||||
tick_it(3);
|
||||
|
||||
len = pico_mock_network_read(mock, buf, BUFLEN);
|
||||
fail_unless(len, "received msg on network of %d bytes", len);
|
||||
printbuf(&(buf[0]), len, "DHCP-REQUEST packet", printbufactive);
|
||||
fail_unless(buf[0x011c] == 0x03, "No DHCP request received after offer");
|
||||
|
||||
}
|
||||
END_TEST
|
||||
#endif
|
||||
|
||||
START_TEST (test_dhcp_client_api)
|
||||
{
|
||||
/************************************************************************
|
||||
* Check API of pico_dhcp_initiate_negotiation
|
||||
* Status : Done
|
||||
************************************************************************/
|
||||
|
||||
/* Declaration test 0 */
|
||||
uint32_t xid0 = 0;
|
||||
struct pico_dhcp_client_cookie *cli0 = NULL;
|
||||
/* Declaration test 1 */
|
||||
uint32_t xid1 = 0;
|
||||
struct pico_dhcp_client_cookie *cli1 = NULL;
|
||||
|
||||
printf("*********************** starting %s * \n", __func__);
|
||||
|
||||
/* test 0 */
|
||||
/* Clear error code */
|
||||
pico_err = PICO_ERR_NOERR;
|
||||
/* Test 0 statements */
|
||||
pico_dhcp_initiate_negotiation(NULL, NULL, &xid0);
|
||||
cli0 = pico_dhcp_client_find_cookie(xid0);
|
||||
fail_unless(cli0 == NULL, "DHCP_CLIENT> initiate succeeded after pointer to dev == NULL");
|
||||
fail_unless(pico_err == PICO_ERR_EINVAL, "DHCP_SERVER> initiate succeeded without PICO_ERR_EINVAL after wrong parameter");
|
||||
|
||||
/* test 1 */
|
||||
/* Clear error code */
|
||||
pico_err = PICO_ERR_NOERR;
|
||||
/* Test 1 statements */
|
||||
pico_dhcp_initiate_negotiation(NULL, &callback_dhcpclient, &xid1);
|
||||
cli1 = pico_dhcp_client_find_cookie(xid1);
|
||||
fail_unless(cli1 == NULL, "DHCP_CLIENT> initiate succeeded after pointer to dev == NULL");
|
||||
fail_unless(pico_err == PICO_ERR_EINVAL, "DHCP_SERVER> initiate succeeded without PICO_ERR_EINVAL after wrong parameter");
|
||||
|
||||
#if 0
|
||||
/* not testable since we do not have a stub for the pico_socket_sendto */
|
||||
/* Declaration test 2 */
|
||||
uint32_t xid2 = 0;
|
||||
struct pico_dhcp_client_cookie *cli2 = NULL;
|
||||
struct pico_device *dev2;
|
||||
struct mock_device *mock2 = NULL;
|
||||
|
||||
/* test 2 */
|
||||
/* Create device */
|
||||
dev2 = pico_null_create("dummy");
|
||||
mock2 = pico_mock_create(NULL);
|
||||
fail_if(mock2 == NULL, "No device created");
|
||||
/* Clear error code */
|
||||
pico_err = PICO_ERR_NOERR;
|
||||
/* Test 2 statements */
|
||||
xid2 = pico_dhcp_initiate_negotiation(dev2, &callback_dhcpclient);
|
||||
cli2 = get_cookie_by_xid(xid2);
|
||||
fail_if(cli2 == NULL, "DHCP_CLIENT: error initiating: %s", strerror(pico_err));
|
||||
xid2 = pico_dhcp_initiate_negotiation(mock2->dev, &callback_dhcpclient);
|
||||
cli2 = get_cookie_by_xid(xid2);
|
||||
fail_if(cli2 == NULL, "DHCP_CLIENT: error initiating: %s", strerror(pico_err));
|
||||
xid2 = pico_dhcp_initiate_negotiation(dev2, &callback_dhcpclient);
|
||||
cli2 = get_cookie_by_xid(xid2);
|
||||
fail_if(cli2 == NULL, "DHCP_CLIENT: error initiating: %s", strerror(pico_err));
|
||||
#endif
|
||||
}
|
||||
END_TEST
|
||||
88
kernel/picotcp/test/unit/unit_dns.c
Normal file
88
kernel/picotcp/test/unit/unit_dns.c
Normal file
@@ -0,0 +1,88 @@
|
||||
void cb_dns(char *ip, void *arg);
|
||||
|
||||
void cb_dns(char *ip, void *arg)
|
||||
{
|
||||
if (!ip) {
|
||||
/* Error occured */
|
||||
printf("DNS error getaddr\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Do something */
|
||||
printf("DNS -> %s\n", ip);
|
||||
PICO_FREE(ip);
|
||||
if (arg)
|
||||
PICO_FREE(arg);
|
||||
}
|
||||
|
||||
|
||||
START_TEST (test_dns)
|
||||
{
|
||||
int ret;
|
||||
char url[] = "www.google.com";
|
||||
char ip[] = "8.8.4.4";
|
||||
struct pico_ip4 ns;
|
||||
|
||||
ns.addr = long_be(0x0a00280a); /* 10.40.0.10 */
|
||||
|
||||
pico_stack_init();
|
||||
|
||||
printf("START DNS TEST\n");
|
||||
|
||||
/* testing nameserver API */
|
||||
ret = pico_dns_client_nameserver(NULL, PICO_DNS_NS_ADD);
|
||||
fail_if(ret == 0, "dns> dns_client_nameserver add error");
|
||||
|
||||
ret = pico_dns_client_nameserver(NULL, PICO_DNS_NS_DEL);
|
||||
fail_if(ret == 0, "dns> dns_client_nameserver del error");
|
||||
|
||||
ret = pico_dns_client_nameserver(NULL, 99);
|
||||
fail_if(ret == 0, "dns> dns_client_nameserver wrong code");
|
||||
|
||||
ret = pico_dns_client_nameserver(NULL, 0xFF);
|
||||
fail_if(ret == 0, "dns> dns_client_nameserver wrong code");
|
||||
|
||||
ret = pico_dns_client_nameserver(&ns, PICO_DNS_NS_DEL); /* delete non added ns */
|
||||
fail_if(ret == 0, "dns> dns_client_nameserver del error");
|
||||
|
||||
ret = pico_dns_client_nameserver(&ns, 99);
|
||||
fail_if(ret == 0, "dns> dns_client_nameserver wrong code");
|
||||
|
||||
ret = pico_dns_client_nameserver(&ns, PICO_DNS_NS_ADD); /* add correct one */
|
||||
fail_if(ret < 0, "dns> dns_client_nameserver add error: %s", strerror(pico_err));
|
||||
|
||||
ret = pico_dns_client_nameserver(&ns, 99);
|
||||
fail_if(ret == 0, "dns> dns_client_nameserver wrong code");
|
||||
|
||||
ret = pico_dns_client_nameserver(&ns, PICO_DNS_NS_DEL);
|
||||
fail_if(ret < 0, "dns> dns_client_nameserver del error: %s", strerror(pico_err));
|
||||
|
||||
ret = pico_dns_client_nameserver(&ns, PICO_DNS_NS_ADD); /* add correct one */
|
||||
fail_if(ret < 0, "dns> dns_client_nameserver add error: %s", strerror(pico_err));
|
||||
|
||||
ret = pico_dns_client_nameserver(&ns, PICO_DNS_NS_ADD); /* add correct one again */
|
||||
fail_if(ret < 0, "dns> dns_client_nameserver add double failed");
|
||||
|
||||
/* testing getaddr API */
|
||||
/* not testable since we do not have a stub for the pico_socket_send */
|
||||
/* ret = pico_dns_client_getaddr(url, cb_dns, NULL); / * ask correct one * / */
|
||||
/* fail_if(ret < 0, "dns> dns_client_getaddr: %s",strerror(pico_err)); */
|
||||
|
||||
ret = pico_dns_client_getaddr(NULL, cb_dns, NULL);
|
||||
fail_if(ret == 0, "dns> dns_client_getaddr: no url");
|
||||
|
||||
ret = pico_dns_client_getaddr(url, NULL, NULL);
|
||||
fail_if(ret == 0, "dns> dns_client_getaddr: no cb");
|
||||
|
||||
/* testing getname API */
|
||||
/* not testable since we do not have a stub for the pico_socket_send */
|
||||
/* ret = pico_dns_client_getname(ip, cb_dns, NULL); / * ask correct one * / */
|
||||
/* fail_if(ret < 0, "dns> dns_client_getname: %s",strerror(pico_err)); */
|
||||
|
||||
ret = pico_dns_client_getname(NULL, cb_dns, NULL);
|
||||
fail_if(ret == 0, "dns> dns_client_getname: no ip");
|
||||
|
||||
ret = pico_dns_client_getname(ip, NULL, NULL);
|
||||
fail_if(ret == 0, "dns> dns_client_getname: no cb");
|
||||
}
|
||||
END_TEST
|
||||
401
kernel/picotcp/test/unit/unit_icmp4.c
Normal file
401
kernel/picotcp/test/unit/unit_icmp4.c
Normal file
@@ -0,0 +1,401 @@
|
||||
|
||||
#include "pico_icmp4.h"
|
||||
#define NUM_PING 1
|
||||
int ping_test_var = 0;
|
||||
|
||||
void cb_ping(struct pico_icmp4_stats *s);
|
||||
void icmp4_unreach_socket_cb(uint16_t ev, struct pico_socket *s);
|
||||
|
||||
void cb_ping(struct pico_icmp4_stats *s)
|
||||
{
|
||||
char host[30];
|
||||
pico_ipv4_to_string(host, s->dst.addr);
|
||||
if (s->err == 0) {
|
||||
dbg("%lu bytes from %s: icmp_req=%lu ttl=64 time=%lu ms\n", s->size, host, s->seq, s->time);
|
||||
if (s->seq == NUM_PING) {
|
||||
ping_test_var++;
|
||||
}
|
||||
|
||||
fail_if (s->seq > NUM_PING);
|
||||
} else {
|
||||
dbg("PING %lu to %s: Error %d\n", s->seq, host, s->err);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
START_TEST (test_icmp4_ping)
|
||||
{
|
||||
struct pico_ip4 local = {
|
||||
0
|
||||
};
|
||||
struct pico_ip4 remote = {
|
||||
0
|
||||
};
|
||||
struct pico_ip4 netmask = {
|
||||
0
|
||||
};
|
||||
struct mock_device *mock = NULL;
|
||||
char local_address[] = {
|
||||
"192.168.1.102"
|
||||
};
|
||||
char remote_address[] = {
|
||||
"192.168.1.103"
|
||||
};
|
||||
uint16_t interval = 1000;
|
||||
uint16_t timeout = 5000;
|
||||
uint8_t size = 48;
|
||||
|
||||
int bufferlen = 80;
|
||||
uint8_t buffer[bufferlen];
|
||||
int len;
|
||||
uint8_t temp_buf[4];
|
||||
printf("*********************** starting %s * \n", __func__);
|
||||
|
||||
pico_string_to_ipv4(local_address, &(local.addr));
|
||||
pico_string_to_ipv4("255.255.255.0", &(netmask.addr));
|
||||
|
||||
pico_string_to_ipv4(remote_address, &(remote.addr));
|
||||
pico_string_to_ipv4("255.255.255.0", &(netmask.addr));
|
||||
|
||||
pico_stack_init();
|
||||
|
||||
mock = pico_mock_create(NULL);
|
||||
fail_if(mock == NULL, "No device created");
|
||||
|
||||
pico_ipv4_link_add(mock->dev, local, netmask);
|
||||
|
||||
fail_if(pico_icmp4_ping(local_address, NUM_PING, interval, timeout, size, cb_ping) < 0);
|
||||
pico_stack_tick();
|
||||
pico_stack_tick();
|
||||
pico_stack_tick();
|
||||
|
||||
fail_if(ping_test_var != 1);
|
||||
|
||||
pico_icmp4_ping(remote_address, NUM_PING, interval, timeout, size, cb_ping);
|
||||
pico_stack_tick();
|
||||
pico_stack_tick();
|
||||
pico_stack_tick();
|
||||
|
||||
/* get the packet from the mock_device */
|
||||
memset(buffer, 0, (size_t)bufferlen);
|
||||
len = pico_mock_network_read(mock, buffer, bufferlen);
|
||||
fail_if(len < 20);
|
||||
/* inspect it */
|
||||
fail_unless(mock_ip_protocol(mock, buffer, len) == 1);
|
||||
fail_unless(mock_icmp_type(mock, buffer, len) == 8);
|
||||
fail_unless(mock_icmp_code(mock, buffer, len) == 0);
|
||||
fail_unless(pico_checksum(buffer + 20, (uint32_t)(len - 20)) == 0);
|
||||
|
||||
/* cobble up a reply */
|
||||
buffer[20] = 0; /* type 0 : reply */
|
||||
memcpy(temp_buf, buffer + 12, 4);
|
||||
memcpy(buffer + 12, buffer + 16, 4);
|
||||
memcpy(buffer + 16, temp_buf, 4);
|
||||
|
||||
/* using the mock-device because otherwise I have to put everything in a pico_frame correctly myself. */
|
||||
pico_mock_network_write(mock, buffer, len);
|
||||
/* check if it is received */
|
||||
pico_stack_tick();
|
||||
pico_stack_tick();
|
||||
pico_stack_tick();
|
||||
fail_unless(ping_test_var == 2);
|
||||
|
||||
/* repeat but make it an invalid reply... */
|
||||
|
||||
pico_icmp4_ping(remote_address, NUM_PING, interval, timeout, size, cb_ping);
|
||||
pico_stack_tick();
|
||||
pico_stack_tick();
|
||||
pico_stack_tick();
|
||||
|
||||
/* get the packet from the mock_device */
|
||||
memset(buffer, 0, (size_t)bufferlen);
|
||||
len = pico_mock_network_read(mock, buffer, bufferlen);
|
||||
/* inspect it */
|
||||
fail_unless(mock_ip_protocol(mock, buffer, len) == 1);
|
||||
fail_unless(mock_icmp_type(mock, buffer, len) == 8);
|
||||
fail_unless(mock_icmp_code(mock, buffer, len) == 0);
|
||||
fail_unless(pico_checksum(buffer + 20, (uint32_t)(len - 20)) == 0);
|
||||
|
||||
/* cobble up a reply */
|
||||
buffer[20] = 0; /* type 0 : reply */
|
||||
memcpy(temp_buf, buffer + 12, 4);
|
||||
memcpy(buffer + 12, buffer + 16, 4);
|
||||
memcpy(buffer + 16, temp_buf, 4);
|
||||
buffer[26] = (uint8_t)~buffer[26]; /* flip some bits in the sequence number, to see if the packet gets ignored properly */
|
||||
|
||||
/* using the mock-device because otherwise I have to put everything in a pico_frame correctly myself. */
|
||||
pico_mock_network_write(mock, buffer, len);
|
||||
/* check if it is received */
|
||||
pico_stack_tick();
|
||||
pico_stack_tick();
|
||||
pico_stack_tick();
|
||||
fail_unless(ping_test_var == 2);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
|
||||
START_TEST (test_icmp4_incoming_ping)
|
||||
{
|
||||
int bufferlen = 76;
|
||||
uint8_t buffer[76] = {
|
||||
0x45, 0x00, 0x00, 0x4c,
|
||||
0x91, 0xc3, 0x40, 0x00,
|
||||
0x40, 0x01, 0x24, 0xd0,
|
||||
0xc0, 0xa8, 0x01, 0x66,
|
||||
0xc0, 0xa8, 0x01, 0x64,
|
||||
0x08, 0x00, 0x66, 0x3c,
|
||||
0x91, 0xc2, 0x01, 0x01,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
int buffer2len = 76;
|
||||
int len;
|
||||
int cntr = 0;
|
||||
uint8_t buffer2[bufferlen];
|
||||
struct pico_ip4 local = {
|
||||
.addr = long_be(0xc0a80164)
|
||||
};
|
||||
struct pico_ip4 netmask = {
|
||||
.addr = long_be(0xffffff00)
|
||||
};
|
||||
struct mock_device*mock;
|
||||
struct pico_ipv4_hdr *hdr = (struct pico_ipv4_hdr *) buffer;
|
||||
printf("*********************** starting %s * \n", __func__);
|
||||
|
||||
pico_stack_init();
|
||||
|
||||
mock = pico_mock_create(NULL);
|
||||
fail_if(mock == NULL, "No device created");
|
||||
|
||||
pico_ipv4_link_add(mock->dev, local, netmask);
|
||||
|
||||
hdr->crc = 0;
|
||||
hdr->crc = short_be(pico_checksum(hdr, PICO_SIZE_IP4HDR));
|
||||
pico_mock_network_write(mock, buffer, bufferlen);
|
||||
/* check if it is received */
|
||||
pico_stack_tick();
|
||||
pico_stack_tick();
|
||||
pico_stack_tick();
|
||||
pico_stack_tick();
|
||||
pico_stack_tick();
|
||||
pico_stack_tick();
|
||||
|
||||
|
||||
len = pico_mock_network_read(mock, buffer2, buffer2len);
|
||||
/* inspect it */
|
||||
|
||||
while(cntr < len) {
|
||||
printf("0x%02x ", buffer2[cntr]);
|
||||
cntr++;
|
||||
if(cntr % 4 == 0)
|
||||
printf("\n");
|
||||
}
|
||||
fail_unless(len == buffer2len, "ping reply lenght does not match, expected len: %d, got: %d", buffer2len, len);
|
||||
fail_unless(mock_ip_protocol(mock, buffer2, len) == 1);
|
||||
fail_unless(mock_icmp_type(mock, buffer2, len) == 0);
|
||||
fail_unless(mock_icmp_code(mock, buffer2, len) == 0);
|
||||
fail_unless(pico_checksum(buffer2 + 20, (uint32_t)(len - 20)) == 0);
|
||||
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST (test_icmp4_unreachable_send)
|
||||
{
|
||||
struct pico_ip4 local = {
|
||||
.addr = long_be(0x0a280064)
|
||||
};
|
||||
struct pico_ip4 netmask = {
|
||||
.addr = long_be(0xffffff00)
|
||||
};
|
||||
struct mock_device*mock;
|
||||
int len = 0;
|
||||
int bufferlen = 80;
|
||||
uint8_t buffer2[bufferlen];
|
||||
|
||||
uint8_t buffer[32] = {
|
||||
0x45, 0x00, 0x00, 0x20, 0x91, 0xc0, 0x40, 0x00,
|
||||
0x40, 0x11, 0x94, 0xb4, 0x0a, 0x28, 0x00, 0x05,
|
||||
0x0a, 0x28, 0x00, 0x04, 0x15, 0xb3, 0x15, 0xb3,
|
||||
0x00, 0x0c, 0x00, 0x00, 'e', 'l', 'l', 'o'
|
||||
};
|
||||
|
||||
/* fake packet with bad upper-layer-protocol */
|
||||
uint8_t buffer3[20] = {
|
||||
0x45, 0x00, 0x00, 0x14, 0x91, 0xc0, 0x40, 0x00,
|
||||
0x40, 0xff, 0x94, 0xb4, 0x0a, 0x28, 0x00, 0x05,
|
||||
0x0a, 0x28, 0x00, 0x04
|
||||
};
|
||||
|
||||
struct pico_frame*f = PICO_ZALLOC(sizeof(struct pico_frame));
|
||||
printf("*********************** starting %s * \n", __func__);
|
||||
|
||||
f->net_hdr = buffer;
|
||||
f->buffer = buffer;
|
||||
|
||||
pico_stack_init();
|
||||
|
||||
mock = pico_mock_create(NULL);
|
||||
fail_if(mock == NULL, "No device created");
|
||||
|
||||
pico_ipv4_link_add(mock->dev, local, netmask);
|
||||
|
||||
|
||||
fail_if(pico_icmp4_dest_unreachable(f));
|
||||
pico_stack_tick();
|
||||
pico_stack_tick();
|
||||
pico_stack_tick();
|
||||
|
||||
len = pico_mock_network_read(mock, buffer2, bufferlen);
|
||||
|
||||
fail_unless(len == 56, "len is indeed %d\n", len);
|
||||
fail_unless(mock_ip_protocol(mock, buffer2, len) == 1);
|
||||
fail_unless(mock_icmp_type(mock, buffer2, len) == 3); /* destination unreachable */
|
||||
fail_unless(mock_icmp_code(mock, buffer2, len) == 1); /* host unreachable */
|
||||
fail_unless(pico_checksum(buffer2 + 20, (uint32_t)(len - 20)) == 0);
|
||||
|
||||
|
||||
fail_if(pico_icmp4_port_unreachable(f));
|
||||
pico_stack_tick();
|
||||
pico_stack_tick();
|
||||
pico_stack_tick();
|
||||
|
||||
len = pico_mock_network_read(mock, buffer2, bufferlen);
|
||||
|
||||
fail_unless(len == 56);
|
||||
fail_unless(mock_ip_protocol(mock, buffer2, len) == 1);
|
||||
fail_unless(mock_icmp_type(mock, buffer2, len) == 3); /* destination unreachable */
|
||||
fail_unless(mock_icmp_code(mock, buffer2, len) == 3); /* port unreachable */
|
||||
fail_unless(pico_checksum(buffer2 + 20, (uint32_t)(len - 20)) == 0);
|
||||
|
||||
|
||||
fail_if(pico_icmp4_proto_unreachable(f));
|
||||
pico_stack_tick();
|
||||
pico_stack_tick();
|
||||
pico_stack_tick();
|
||||
|
||||
len = pico_mock_network_read(mock, buffer2, bufferlen);
|
||||
|
||||
fail_unless(len == 56);
|
||||
fail_unless(mock_ip_protocol(mock, buffer2, len) == 1);
|
||||
fail_unless(mock_icmp_type(mock, buffer2, len) == 3); /* destination unreachable */
|
||||
fail_unless(mock_icmp_code(mock, buffer2, len) == 2); /* proto unreachable */
|
||||
fail_unless(pico_checksum(buffer2 + 20, (uint32_t)(len - 20)) == 0);
|
||||
|
||||
|
||||
fail_if(pico_icmp4_ttl_expired(f));
|
||||
pico_stack_tick();
|
||||
pico_stack_tick();
|
||||
pico_stack_tick();
|
||||
|
||||
len = pico_mock_network_read(mock, buffer2, bufferlen);
|
||||
|
||||
fail_unless(len == 56);
|
||||
fail_unless(mock_ip_protocol(mock, buffer2, len) == 1);
|
||||
fail_unless(mock_icmp_type(mock, buffer2, len) == 11); /* ttl expired */
|
||||
fail_unless(mock_icmp_code(mock, buffer2, len) == 0);
|
||||
fail_unless(pico_checksum(buffer2 + 20, (uint32_t)(len - 20)) == 0);
|
||||
|
||||
f->net_hdr = buffer3;
|
||||
f->buffer = buffer3;
|
||||
|
||||
fail_if(pico_icmp4_proto_unreachable(f));
|
||||
pico_stack_tick();
|
||||
pico_stack_tick();
|
||||
pico_stack_tick();
|
||||
|
||||
len = pico_mock_network_read(mock, buffer2, bufferlen);
|
||||
|
||||
fail_unless(len == 48); /* Buffer 3 is shorter, reply is shorter too... */
|
||||
fail_unless(mock_ip_protocol(mock, buffer2, len) == 1);
|
||||
fail_unless(mock_icmp_type(mock, buffer2, len) == 3); /* destination unreachable */
|
||||
fail_unless(mock_icmp_code(mock, buffer2, len) == 2); /* proto unreachable */
|
||||
fail_unless(pico_checksum(buffer2 + 20, (uint32_t)(len - 20)) == 0);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
int icmp4_socket_unreach_status = 0;
|
||||
void icmp4_unreach_socket_cb(uint16_t ev, struct pico_socket *s)
|
||||
{
|
||||
IGNORE_PARAMETER(s);
|
||||
|
||||
if (ev == PICO_SOCK_EV_ERR) {
|
||||
icmp4_socket_unreach_status = 1;
|
||||
}
|
||||
}
|
||||
|
||||
START_TEST (test_icmp4_unreachable_recv)
|
||||
{
|
||||
struct pico_ip4 local = {
|
||||
.addr = long_be(0x0a280064)
|
||||
};
|
||||
struct pico_ip4 remote = {
|
||||
.addr = long_be(0x0a280065)
|
||||
};
|
||||
struct pico_ip4 netmask = {
|
||||
.addr = long_be(0xffffff00)
|
||||
};
|
||||
struct mock_device*mock;
|
||||
struct pico_socket*sock;
|
||||
uint16_t port = short_be(7777);
|
||||
|
||||
/* put a host unreachable in the queue, run a few stack ticks */
|
||||
uint8_t buffer[] = {
|
||||
0x45, 0x00, 0x00, 0x20,
|
||||
0x91, 0xc0, 0x40, 0x00,
|
||||
0x40, 0x01, 0x94, 0xb4,
|
||||
0x0a, 0x28, 0x00, 0x65,
|
||||
0x0a, 0x28, 0x00, 0x64,
|
||||
0x03, 0x01, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
struct pico_ipv4_hdr *hdr = (struct pico_ipv4_hdr *) buffer;
|
||||
|
||||
printf("*********************** starting %s * \n", __func__);
|
||||
pico_stack_init();
|
||||
|
||||
mock = pico_mock_create(NULL);
|
||||
fail_if(mock == NULL, "No device created");
|
||||
|
||||
pico_ipv4_link_add(mock->dev, local, netmask);
|
||||
|
||||
/* open a socket */
|
||||
sock = pico_socket_open(PICO_PROTO_IPV4, PICO_PROTO_TCP, &icmp4_unreach_socket_cb);
|
||||
fail_if(sock == NULL);
|
||||
fail_if(pico_socket_bind(sock, &local, &port));
|
||||
pico_socket_connect(sock, &remote, port);
|
||||
pico_socket_write(sock, "fooo", 4);
|
||||
/* see if my callback was called with the proper code */
|
||||
|
||||
pico_stack_tick();
|
||||
pico_stack_tick();
|
||||
pico_stack_tick();
|
||||
/* filling in the IP header and first 8 bytes */
|
||||
hdr->crc = 0;
|
||||
hdr->crc = short_be(pico_checksum(hdr, PICO_SIZE_IP4HDR));
|
||||
printf("read %d bytes\n", pico_mock_network_read(mock, buffer + 28, 28));
|
||||
|
||||
printf("wrote %d bytes\n", pico_mock_network_write(mock, buffer, 56));
|
||||
pico_stack_tick();
|
||||
pico_stack_tick();
|
||||
pico_stack_tick();
|
||||
fail_unless(icmp4_socket_unreach_status == 1);
|
||||
}
|
||||
END_TEST
|
||||
852
kernel/picotcp/test/unit/unit_ipv4.c
Normal file
852
kernel/picotcp/test/unit/unit_ipv4.c
Normal file
@@ -0,0 +1,852 @@
|
||||
|
||||
START_TEST (test_ipv4)
|
||||
{
|
||||
#define IP_TST_SIZ 256
|
||||
uint32_t i;
|
||||
|
||||
struct pico_device *dev[IP_TST_SIZ];
|
||||
char devname[8];
|
||||
struct pico_ip4 a[IP_TST_SIZ], d[IP_TST_SIZ], *source[IP_TST_SIZ], nm16, nm32, gw[IP_TST_SIZ], r[IP_TST_SIZ], ret;
|
||||
struct pico_ipv4_link *l[IP_TST_SIZ];
|
||||
|
||||
char ipstr[] = "192.168.1.1";
|
||||
struct pico_ip4 ipaddr;
|
||||
|
||||
struct pico_frame *f_NULL = NULL;
|
||||
struct pico_ip4 *dst_NULL = NULL;
|
||||
|
||||
pico_stack_init();
|
||||
|
||||
nm16.addr = long_be(0xFFFF0000);
|
||||
nm32.addr = long_be(0xFFFFFFFF);
|
||||
|
||||
/*link_add*/
|
||||
for (i = 0; i < IP_TST_SIZ; i++) {
|
||||
snprintf(devname, 8, "nul%d", i);
|
||||
dev[i] = pico_null_create(devname);
|
||||
a[i].addr = long_be(0x0a000001u + (i << 16));
|
||||
d[i].addr = long_be(0x0a000002u + (i << 16));
|
||||
fail_if(pico_ipv4_link_add(dev[i], a[i], nm16) != 0, "Error adding link");
|
||||
}
|
||||
/*link_find + link_get + route_add*/
|
||||
for (i = 0; i < IP_TST_SIZ; i++) {
|
||||
gw[i].addr = long_be(0x0a0000f0u + (i << 16));
|
||||
r[i].addr = long_be(0x0c00001u + (i << 16));
|
||||
fail_unless(pico_ipv4_link_find(&a[i]) == dev[i], "Error finding link");
|
||||
l[i] = pico_ipv4_link_get(&a[i]);
|
||||
fail_if(l[i] == NULL, "Error getting link");
|
||||
fail_if(pico_ipv4_route_add(r[i], nm32, gw[i], 1, l[i]) != 0, "Error adding route");
|
||||
fail_if(pico_ipv4_route_add(d[i], nm32, gw[i], 1, l[i]) != 0, "Error adding route");
|
||||
}
|
||||
/*get_gateway + source_find*/
|
||||
for (i = 0; i < IP_TST_SIZ; i++) {
|
||||
ret = pico_ipv4_route_get_gateway(&r[i]);
|
||||
fail_if(ret.addr != gw[i].addr, "Error get gateway: returned wrong route");
|
||||
source[i] = pico_ipv4_source_find(&d[i]);
|
||||
fail_if(source[i]->addr != a[i].addr, "Error find source: returned wrong route");
|
||||
}
|
||||
/*route_del + link_del*/
|
||||
for (i = 0; i < IP_TST_SIZ; i++) {
|
||||
fail_if(pico_ipv4_route_del(r[i], nm32, 1) != 0, "Error deleting route");
|
||||
fail_if(pico_ipv4_link_del(dev[i], a[i]) != 0, "Error deleting link");
|
||||
}
|
||||
/*string_to_ipv4 + ipv4_to_string*/
|
||||
pico_string_to_ipv4(ipstr, &(ipaddr.addr));
|
||||
fail_if(ipaddr.addr != long_be(0xc0a80101), "Error string to ipv4");
|
||||
memset(ipstr, 0, 12);
|
||||
pico_ipv4_to_string(ipstr, ipaddr.addr);
|
||||
fail_if(strncmp(ipstr, "192.168.1.1", 11) != 0, "Error ipv4 to string");
|
||||
|
||||
/*valid_netmask*/
|
||||
fail_if(pico_ipv4_valid_netmask(long_be(nm32.addr)) != 32, "Error checking netmask");
|
||||
|
||||
/*is_unicast*/
|
||||
fail_if((pico_ipv4_is_unicast(long_be(0xc0a80101))) != 1, "Error checking unicast");
|
||||
fail_if((pico_ipv4_is_unicast(long_be(0xe0000001))) != 0, "Error checking unicast");
|
||||
|
||||
/*rebound*/
|
||||
fail_if(pico_ipv4_rebound(f_NULL) != -1, "Error rebound frame");
|
||||
|
||||
/*frame_push*/
|
||||
fail_if(pico_ipv4_frame_push(f_NULL, dst_NULL, PICO_PROTO_TCP) != -1, "Error push frame");
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST (test_nat_enable_disable)
|
||||
{
|
||||
struct pico_ipv4_link link = {
|
||||
.address = {.addr = long_be(0x0a320001)}
|
||||
}; /* 10.50.0.1 */
|
||||
struct pico_frame *f = pico_ipv4_alloc(&pico_proto_ipv4, NULL, PICO_UDPHDR_SIZE);
|
||||
struct pico_ipv4_hdr *net = (struct pico_ipv4_hdr *)f->net_hdr;
|
||||
struct pico_udp_hdr *udp = (struct pico_udp_hdr *)f->transport_hdr;
|
||||
const char *raw_data = "ello";
|
||||
|
||||
net->vhl = 0x45; /* version = 4, hdr len = 5 (32-bit words) */
|
||||
net->tos = 0;
|
||||
net->len = short_be(32); /* hdr + data (bytes) */
|
||||
net->id = short_be(0x91c0);
|
||||
net->frag = short_be(0x4000); /* don't fragment flag, offset = 0 */
|
||||
net->ttl = 64;
|
||||
net->proto = 17; /* UDP */
|
||||
net->crc = 0;
|
||||
net->src.addr = long_be(0x0a280008); /* 10.40.0.8 */
|
||||
net->dst.addr = long_be(0x0a320001); /* 10.50.0.1 */
|
||||
|
||||
udp->trans.sport = short_be(5555);
|
||||
udp->trans.dport = short_be(6667);
|
||||
udp->len = 12;
|
||||
udp->crc = 0;
|
||||
|
||||
f->payload = f->transport_hdr + PICO_UDPHDR_SIZE;
|
||||
memcpy(f->payload, raw_data, 4);
|
||||
|
||||
printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> NAT ENABLE/DISABLE TEST\n");
|
||||
pico_stack_init();
|
||||
|
||||
fail_if(pico_ipv4_nat_enable(&link));
|
||||
fail_unless(nat_link->address.addr == link.address.addr);
|
||||
fail_unless(pico_ipv4_nat_is_enabled(&link.address));
|
||||
|
||||
fail_if(pico_ipv4_nat_outbound(f, &net->dst));
|
||||
pico_ipv4_nat_table_cleanup(pico_tick, NULL);
|
||||
|
||||
fail_if(pico_ipv4_nat_disable());
|
||||
fail_if(pico_ipv4_nat_is_enabled(&link.address));
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST (test_nat_translation)
|
||||
{
|
||||
struct pico_ipv4_link link = {
|
||||
.address = {.addr = long_be(0x0a320001)}
|
||||
}; /* 10.50.0.1 */
|
||||
struct pico_frame *f = pico_ipv4_alloc(&pico_proto_ipv4, NULL, PICO_UDPHDR_SIZE);
|
||||
struct pico_ipv4_hdr *net = (struct pico_ipv4_hdr *)f->net_hdr;
|
||||
struct pico_udp_hdr *udp = (struct pico_udp_hdr *)f->transport_hdr;
|
||||
struct pico_ip4 src_ori = {
|
||||
.addr = long_be(0x0a280008)
|
||||
}; /* 10.40.0.8 */
|
||||
struct pico_ip4 dst_ori = {
|
||||
.addr = long_be(0x0a320009)
|
||||
}; /* 10.50.0.9 */
|
||||
struct pico_ip4 nat = {
|
||||
.addr = long_be(0x0a320001)
|
||||
}; /* 10.50.0.9 */
|
||||
const char *raw_data = "ello";
|
||||
uint16_t sport_ori = short_be(5555);
|
||||
uint16_t dport_ori = short_be(6667);
|
||||
uint16_t nat_port = 0;
|
||||
|
||||
net->vhl = 0x45; /* version = 4, hdr len = 5 (32-bit words) */
|
||||
net->tos = 0;
|
||||
net->len = short_be(32); /* hdr + data (bytes) */
|
||||
net->id = short_be(0x91c0);
|
||||
net->frag = short_be(0x4000); /* don't fragment flag, offset = 0 */
|
||||
net->ttl = 64;
|
||||
net->proto = 17; /* UDP */
|
||||
net->crc = 0;
|
||||
net->src = src_ori;
|
||||
net->dst = dst_ori;
|
||||
|
||||
udp->trans.sport = sport_ori;
|
||||
udp->trans.dport = dport_ori;
|
||||
udp->len = 12;
|
||||
udp->crc = 0;
|
||||
|
||||
f->payload = f->transport_hdr + PICO_UDPHDR_SIZE;
|
||||
memcpy(f->payload, raw_data, 4);
|
||||
|
||||
printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> NAT TRANSLATION TEST\n");
|
||||
pico_stack_init();
|
||||
fail_if(pico_ipv4_nat_enable(&link));
|
||||
|
||||
/* perform outbound translation, check if source IP got translated */
|
||||
fail_if(pico_ipv4_nat_outbound(f, &nat_link->address));
|
||||
fail_if(net->src.addr != link.address.addr, "source address not translated");
|
||||
|
||||
/* perform outbound translation of same packet, check if source IP and PORT got translated the same as previous packet */
|
||||
nat_port = udp->trans.sport;
|
||||
net->src = src_ori; /* restore original src */
|
||||
udp->trans.sport = sport_ori; /* restore original sport */
|
||||
fail_if(pico_ipv4_nat_outbound(f, &nat_link->address));
|
||||
fail_if(net->src.addr != link.address.addr, "source address not translated");
|
||||
fail_if(udp->trans.sport != nat_port, "frames with the same source IP, source PORT and PROTO did not get translated the same");
|
||||
|
||||
/* perform outbound translation of packet with changed source PORT, check if source PORT got translated differently as previous packet */
|
||||
nat_port = udp->trans.sport;
|
||||
net->src = src_ori; /* restore original src */
|
||||
udp->trans.sport = short_be(5556); /* change sport */
|
||||
fail_if(pico_ipv4_nat_outbound(f, &nat_link->address));
|
||||
fail_if(net->src.addr != link.address.addr, "source address not translated");
|
||||
fail_if(udp->trans.sport == short_be(sport_ori), "two frames with different sport get translated the same");
|
||||
|
||||
/* perform inbound translation of previous packet, check if destination IP and PORT got translated to the original source IP and PORT */
|
||||
nat_port = udp->trans.sport;
|
||||
net->src = dst_ori;
|
||||
net->dst = nat;
|
||||
udp->trans.sport = sport_ori;
|
||||
udp->trans.dport = nat_port;
|
||||
fail_if(pico_ipv4_nat_inbound(f, &nat_link->address));
|
||||
fail_if(net->dst.addr != src_ori.addr, "destination address not translated correctly");
|
||||
fail_if(udp->trans.dport != short_be(5556), "ports not translated correctly");
|
||||
pico_ipv4_nat_table_cleanup(pico_tick, NULL);
|
||||
|
||||
fail_if(pico_ipv4_nat_disable());
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST (test_nat_port_forwarding)
|
||||
{
|
||||
struct pico_ipv4_link link = {
|
||||
.address = {.addr = long_be(0x0a320001)}
|
||||
}; /* 10.50.0.1 */
|
||||
struct pico_frame *f = pico_ipv4_alloc(&pico_proto_ipv4, NULL, PICO_UDPHDR_SIZE);
|
||||
struct pico_ipv4_hdr *net = (struct pico_ipv4_hdr *)f->net_hdr;
|
||||
struct pico_udp_hdr *udp = (struct pico_udp_hdr *)f->transport_hdr;
|
||||
struct pico_ip4 src_addr = {
|
||||
.addr = long_be(0x0a280008)
|
||||
}; /* 10.40.0.8 */
|
||||
struct pico_ip4 dst_addr = {
|
||||
.addr = long_be(0x0a320009)
|
||||
}; /* 10.50.0.9 */
|
||||
struct pico_ip4 nat_addr = {
|
||||
.addr = long_be(0x0a320001)
|
||||
}; /* 10.50.0.9 */
|
||||
const char *raw_data = "ello";
|
||||
uint16_t sport_ori = short_be(5555);
|
||||
uint16_t fport_pub = short_be(80);
|
||||
uint16_t fport_priv = short_be(8080);
|
||||
|
||||
net->vhl = 0x45; /* version = 4, hdr len = 5 (32-bit words) */
|
||||
net->tos = 0;
|
||||
net->len = short_be(32); /* hdr + data (bytes) */
|
||||
net->id = short_be(0x91c0);
|
||||
net->frag = short_be(0x4000); /* don't fragment flag, offset = 0 */
|
||||
net->ttl = 64;
|
||||
net->proto = 17; /* UDP */
|
||||
net->crc = 0;
|
||||
net->src = dst_addr;
|
||||
net->dst = nat_addr;
|
||||
|
||||
udp->trans.sport = sport_ori;
|
||||
udp->trans.dport = fport_pub;
|
||||
udp->len = 12;
|
||||
udp->crc = 0;
|
||||
|
||||
f->payload = f->transport_hdr + PICO_UDPHDR_SIZE;
|
||||
memcpy(f->payload, raw_data, 4);
|
||||
|
||||
printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> NAT PORT FORWARD TEST\n");
|
||||
pico_stack_init();
|
||||
fail_if(pico_ipv4_nat_enable(&link));
|
||||
|
||||
fail_if(pico_ipv4_port_forward(nat_addr, fport_pub, src_addr, fport_priv, 17, PICO_NAT_PORT_FORWARD_ADD));
|
||||
|
||||
fail_if(pico_ipv4_nat_inbound(f, &nat_link->address));
|
||||
fail_if(net->dst.addr != src_addr.addr, "destination address not translated correctly");
|
||||
fail_if(udp->trans.dport != fport_priv, "destination port not translated correctly");
|
||||
|
||||
fail_if(pico_ipv4_port_forward(nat_addr, fport_pub, src_addr, fport_priv, 17, PICO_NAT_PORT_FORWARD_DEL));
|
||||
pico_ipv4_nat_table_cleanup(pico_tick, NULL);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST (test_ipfilter)
|
||||
{
|
||||
struct pico_device *dev = NULL;
|
||||
uint8_t proto = 0, tos = 0;
|
||||
uint16_t sport = 0, dport = 0;
|
||||
int8_t priority = 0;
|
||||
int ret = 0;
|
||||
|
||||
struct pico_ip4 src_addr = {
|
||||
0
|
||||
};
|
||||
struct pico_ip4 saddr_netmask = {
|
||||
0
|
||||
};
|
||||
struct pico_ip4 dst_addr = {
|
||||
0
|
||||
};
|
||||
struct pico_ip4 daddr_netmask = {
|
||||
0
|
||||
};
|
||||
|
||||
enum filter_action action = 1;
|
||||
|
||||
uint32_t filter_id1;
|
||||
|
||||
/* 192.168.1.2:16415 -> 192.168.1.109:1222 [sending a TCP syn] */
|
||||
uint8_t ipv4_buf[] = {
|
||||
0x00, 0x02, 0xf7, 0xf1, 0x79, 0x33, 0xe0, 0xdb, 0x55,
|
||||
0xd4, 0xb6, 0x27, 0x08, 0x00, 0x45, 0x00, 0x00, 0x28,
|
||||
0x00, 0x01, 0x00, 0x00, 0x40, 0x06, 0xf7, 0x0f, 0xc0,
|
||||
0xa8, 0x01, 0x02, 0xc0, 0xa8, 0x01, 0x6d, 0x40, 0x1f,
|
||||
0x04, 0xc6, 0x00, 0xb1, 0x56, 0x5a, 0x00, 0x00, 0x00,
|
||||
0x00, 0x50, 0x02, 0x20, 0x00, 0x70, 0x32, 0x00, 0x00
|
||||
};
|
||||
|
||||
struct pico_frame *f;
|
||||
|
||||
printf("IP Filter> Adding a new filter...\n");
|
||||
filter_id1 = pico_ipv4_filter_add(dev, proto, &src_addr, &saddr_netmask, &dst_addr, &daddr_netmask, sport, dport, priority, tos, action);
|
||||
fail_if(filter_id1 <= 0, "Error adding filter\n");
|
||||
printf("filter_id1 = %d\n", filter_id1);
|
||||
|
||||
printf("IP Filter> Trying to add the same filter...\n");
|
||||
filter_id1 = pico_ipv4_filter_add(dev, proto, &src_addr, &saddr_netmask, &dst_addr, &daddr_netmask, sport, dport, priority, tos, action);
|
||||
fail_if(ret > 0, "Error adding filter\n");
|
||||
|
||||
printf("IP Filter> Deleting added filter...\n");
|
||||
ret = pico_ipv4_filter_del(filter_id1);
|
||||
fail_if(ret != 0, "Error deleting the filter\n");
|
||||
|
||||
printf("IP Filter> Trying to delete the same filter\n");
|
||||
ret = pico_ipv4_filter_del(filter_id1);
|
||||
fail_if(ret != -1, "Deleting non existing filter failed\n");
|
||||
|
||||
f = (struct pico_frame *)PICO_ZALLOC(200);
|
||||
f->buffer = PICO_ZALLOC(20);
|
||||
f->usage_count = PICO_ZALLOC(sizeof(uint32_t));
|
||||
f->buffer = ipv4_buf;
|
||||
f->net_hdr = ipv4_buf + 14u; /* shifting to IP layer */
|
||||
f->transport_hdr = ipv4_buf + 34u; /* shifting to Transport layer */
|
||||
|
||||
/* adding exact filter */
|
||||
pico_string_to_ipv4("192.168.1.109", &src_addr.addr);
|
||||
pico_string_to_ipv4("255.255.255.255", &saddr_netmask.addr);
|
||||
sport = 1222u;
|
||||
filter_id1 = pico_ipv4_filter_add(dev, proto, &src_addr, &saddr_netmask, &dst_addr, &daddr_netmask, sport, dport, priority, tos, FILTER_REJECT);
|
||||
fail_if(filter_id1 <= 0, "Error adding exact filter\n");
|
||||
printf("Filter is added\n");
|
||||
sync();
|
||||
sleep(1);
|
||||
|
||||
ret = ipfilter(f);
|
||||
fail_if(ret != 1, "Frame wasn't filtered\n");
|
||||
|
||||
printf("IP Filter> Deleting added filter...\n");
|
||||
ret = pico_ipv4_filter_del(filter_id1);
|
||||
fail_if(ret != 0, "Error deleting the filter\n");
|
||||
|
||||
printf("IP Filter> Adding masked filter...\n");
|
||||
pico_string_to_ipv4("192.168.1.7", &src_addr.addr);
|
||||
pico_string_to_ipv4("255.255.255.0", &saddr_netmask.addr);
|
||||
sport = 1222u;
|
||||
|
||||
filter_id1 = pico_ipv4_filter_add(dev, proto, &src_addr, &saddr_netmask, &dst_addr, &daddr_netmask, sport, dport, priority, tos, FILTER_DROP);
|
||||
fail_if(filter_id1 <= 0, "Error adding masked filter\n");
|
||||
|
||||
f = (struct pico_frame *)PICO_ZALLOC(200);
|
||||
f->buffer = PICO_ZALLOC(20);
|
||||
f->usage_count = PICO_ZALLOC(sizeof(uint32_t));
|
||||
f->buffer = ipv4_buf;
|
||||
f->net_hdr = ipv4_buf + 14u; /* shifting to IP layer */
|
||||
f->transport_hdr = ipv4_buf + 34u; /* shifting to Transport layer */
|
||||
ret = ipfilter(f);
|
||||
fail_if(ret != 1, "Mask filter failed to filter\n");
|
||||
|
||||
printf("IP Filter> Deleting added filter...\n");
|
||||
ret = pico_ipv4_filter_del(filter_id1);
|
||||
fail_if(ret != 0, "Error deleting the filter\n");
|
||||
|
||||
printf("IP Filter> Adding bad filter..\n");
|
||||
pico_string_to_ipv4("191.1.1.7", &src_addr.addr);
|
||||
pico_string_to_ipv4("255.255.255.0", &saddr_netmask.addr);
|
||||
sport = 1991u;
|
||||
filter_id1 = pico_ipv4_filter_add(dev, proto, &src_addr, &saddr_netmask, &dst_addr, &daddr_netmask, sport, dport, priority, tos, FILTER_DROP);
|
||||
fail_if(filter_id1 <= 0, "Error adding bad filter\n");
|
||||
|
||||
f = (struct pico_frame *)PICO_ZALLOC(200);
|
||||
f->buffer = PICO_ZALLOC(20);
|
||||
f->usage_count = PICO_ZALLOC(sizeof(uint32_t));
|
||||
f->buffer = ipv4_buf;
|
||||
f->net_hdr = ipv4_buf + 14u; /* shifting to IP layer */
|
||||
f->transport_hdr = ipv4_buf + 34u; /* shifting to Transport layer */
|
||||
ret = ipfilter(f);
|
||||
fail_if(ret != 0, "Filter shouldn't have filtered this frame\n");
|
||||
|
||||
printf("IP Filter> Deleting added filter...\n");
|
||||
ret = pico_ipv4_filter_del(filter_id1);
|
||||
fail_if(ret != 0, "Error deleting the filter\n");
|
||||
|
||||
}
|
||||
END_TEST
|
||||
|
||||
#ifdef PICO_SUPPORT_MCAST
|
||||
START_TEST (test_igmp_sockopts)
|
||||
{
|
||||
int i = 0, j = 0, k = 0, ret = 0;
|
||||
struct pico_socket *s, *s1 = NULL;
|
||||
struct pico_device *dev = NULL;
|
||||
union pico_address *source = NULL;
|
||||
union pico_address inaddr_dst = {
|
||||
0
|
||||
}, inaddr_incorrect = {
|
||||
0
|
||||
}, inaddr_uni = {
|
||||
0
|
||||
}, inaddr_null = {
|
||||
0
|
||||
}, netmask = {
|
||||
0
|
||||
};
|
||||
union pico_address inaddr_link[2] = {0};
|
||||
union pico_address inaddr_mcast[8] = {0};
|
||||
union pico_address inaddr_source[8] = {0};
|
||||
struct pico_ip_mreq _mreq = {0}, mreq[16] = {0};
|
||||
struct pico_ip_mreq_source mreq_source[128] = {0};
|
||||
struct pico_tree_node *index = NULL;
|
||||
|
||||
int ttl = 64;
|
||||
int getttl = 0;
|
||||
int loop = 9;
|
||||
int getloop = 0;
|
||||
union pico_address mcast_def_link = {
|
||||
0
|
||||
};
|
||||
|
||||
pico_stack_init();
|
||||
|
||||
printf("START IGMP SOCKOPTS TEST\n");
|
||||
|
||||
pico_string_to_ipv4("224.7.7.7", &inaddr_dst.ip4.addr);
|
||||
pico_string_to_ipv4("10.40.0.2", &inaddr_uni.ip4.addr);
|
||||
pico_string_to_ipv4("224.8.8.8", &inaddr_incorrect.ip4.addr);
|
||||
pico_string_to_ipv4("0.0.0.0", &inaddr_null.ip4.addr);
|
||||
|
||||
pico_string_to_ipv4("10.40.0.1", &inaddr_link[0].ip4.addr); /* 0 */
|
||||
pico_string_to_ipv4("10.50.0.1", &inaddr_link[1].ip4.addr); /* 1 */
|
||||
|
||||
pico_string_to_ipv4("232.1.1.0", &inaddr_mcast[0].ip4.addr); /* 0 */
|
||||
pico_string_to_ipv4("232.2.2.1", &inaddr_mcast[1].ip4.addr); /* 1 */
|
||||
pico_string_to_ipv4("232.3.3.2", &inaddr_mcast[2].ip4.addr); /* 2 */
|
||||
pico_string_to_ipv4("232.4.4.3", &inaddr_mcast[3].ip4.addr); /* 3 */
|
||||
pico_string_to_ipv4("232.5.5.4", &inaddr_mcast[4].ip4.addr); /* 4 */
|
||||
pico_string_to_ipv4("232.6.6.5", &inaddr_mcast[5].ip4.addr); /* 5 */
|
||||
pico_string_to_ipv4("232.7.7.6", &inaddr_mcast[6].ip4.addr); /* 6 */
|
||||
pico_string_to_ipv4("232.8.8.7", &inaddr_mcast[7].ip4.addr); /* 7 */
|
||||
|
||||
pico_string_to_ipv4("10.40.1.0", &inaddr_source[0].ip4.addr); /* 0 */
|
||||
pico_string_to_ipv4("10.40.1.1", &inaddr_source[1].ip4.addr); /* 1 */
|
||||
pico_string_to_ipv4("10.40.1.2", &inaddr_source[2].ip4.addr); /* 2 */
|
||||
pico_string_to_ipv4("10.40.1.3", &inaddr_source[3].ip4.addr); /* 3 */
|
||||
pico_string_to_ipv4("10.40.1.4", &inaddr_source[4].ip4.addr); /* 4 */
|
||||
pico_string_to_ipv4("10.40.1.5", &inaddr_source[5].ip4.addr); /* 5 */
|
||||
pico_string_to_ipv4("10.40.1.6", &inaddr_source[6].ip4.addr); /* 6 */
|
||||
pico_string_to_ipv4("10.40.1.7", &inaddr_source[7].ip4.addr); /* 7 */
|
||||
|
||||
/* 00 01 02 03 04 05 06 07 | 10 11 12 13 14 15 16 17 */
|
||||
for (i = 0; i < 16; i++) {
|
||||
mreq[i].mcast_link_addr = inaddr_link[i / 8];
|
||||
mreq[i].mcast_group_addr = inaddr_mcast[i % 8];
|
||||
}
|
||||
/* 000 001 002 003 004 005 006 007 | 010 011 012 013 014 015 016 017 */
|
||||
for (i = 0; i < 16; i++) {
|
||||
for (j = 0; j < 8; j++) {
|
||||
/* printf(">>>>> mreq_source[%d]: link[%d] mcast[%d] source[%d]\n", (i*8)+j, i/8, i%8, j); */
|
||||
mreq_source[(i * 8) + j].mcast_link_addr = inaddr_link[i / 8];
|
||||
mreq_source[(i * 8) + j].mcast_group_addr = inaddr_mcast[i % 8];
|
||||
mreq_source[(i * 8) + j].mcast_source_addr = inaddr_source[j];
|
||||
}
|
||||
}
|
||||
dev = pico_null_create("dummy0");
|
||||
netmask.ip4.addr = long_be(0xFFFF0000);
|
||||
ret = pico_ipv4_link_add(dev, inaddr_link[0].ip4, netmask.ip4);
|
||||
fail_if(ret < 0, "link add failed");
|
||||
|
||||
dev = pico_null_create("dummy1");
|
||||
netmask.ip4.addr = long_be(0xFFFF0000);
|
||||
ret = pico_ipv4_link_add(dev, inaddr_link[1].ip4, netmask.ip4);
|
||||
fail_if(ret < 0, "link add failed");
|
||||
|
||||
s = pico_socket_open(PICO_PROTO_IPV4, PICO_PROTO_UDP, NULL);
|
||||
fail_if(s == NULL, "UDP socket open failed");
|
||||
s1 = pico_socket_open(PICO_PROTO_IPV4, PICO_PROTO_UDP, NULL);
|
||||
fail_if(s1 == NULL, "UDP socket open failed");
|
||||
|
||||
/* argument validation tests */
|
||||
printf("IGMP SETOPTION ARGUMENT VALIDATION TEST\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_MULTICAST_IF, &mcast_def_link);
|
||||
fail_if(ret == 0, "unsupported PICO_IP_MULTICAST_IF succeeded\n");
|
||||
ret = pico_socket_getoption(s, PICO_IP_MULTICAST_IF, &mcast_def_link);
|
||||
fail_if(ret == 0, "unsupported PICO_IP_MULTICAST_IF succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_MULTICAST_TTL, &ttl);
|
||||
fail_if(ret < 0, "supported PICO_IP_MULTICAST_TTL failed\n");
|
||||
|
||||
ret = pico_socket_getoption(s, PICO_IP_MULTICAST_TTL, &getttl);
|
||||
fail_if(ret < 0, "supported PICO_IP_MULTICAST_TTL failed\n");
|
||||
fail_if(getttl != ttl, "setoption ttl != getoption ttl\n");
|
||||
|
||||
ret = pico_socket_setoption(s, PICO_IP_MULTICAST_LOOP, &loop);
|
||||
fail_if(ret == 0, "PICO_IP_MULTICAST_LOOP succeeded with invalid (not 0 or 1) loop value\n");
|
||||
loop = 0;
|
||||
ret = pico_socket_setoption(s, PICO_IP_MULTICAST_LOOP, &loop);
|
||||
fail_if(ret < 0, "supported PICO_IP_MULTICAST_LOOP failed disabling\n");
|
||||
ret = pico_socket_getoption(s, PICO_IP_MULTICAST_LOOP, &getloop);
|
||||
fail_if(ret < 0, "supported PICO_IP_MULTICAST_LOOP failed getting value\n");
|
||||
fail_if(getloop != loop, "setoption loop != getoption loop\n");
|
||||
_mreq.mcast_group_addr = inaddr_dst;
|
||||
_mreq.mcast_link_addr = inaddr_link[0];
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_MEMBERSHIP, &_mreq);
|
||||
fail_if(ret < 0, "supported PICO_IP_ADD_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &_mreq);
|
||||
fail_if(ret < 0, "supported PICO_IP_DROP_MEMBERSHIP failed\n");
|
||||
_mreq.mcast_group_addr = inaddr_dst;
|
||||
_mreq.mcast_link_addr = inaddr_null;
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_MEMBERSHIP, &_mreq);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_MEMBERSHIP failed with valid NULL (use default) link address\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &_mreq);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_MEMBERSHIP failed with valid NULL (use default) link address\n");
|
||||
_mreq.mcast_group_addr = inaddr_uni;
|
||||
_mreq.mcast_link_addr = inaddr_link[0];
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_MEMBERSHIP, &_mreq);
|
||||
fail_if(ret == 0, "PICO_IP_ADD_MEMBERSHIP succeeded with invalid (unicast) group address\n");
|
||||
_mreq.mcast_group_addr = inaddr_null;
|
||||
_mreq.mcast_link_addr = inaddr_link[0];
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_MEMBERSHIP, &_mreq);
|
||||
fail_if(ret == 0, "PICO_IP_ADD_MEMBERSHIP succeeded with invalid (NULL) group address\n");
|
||||
_mreq.mcast_group_addr = inaddr_dst;
|
||||
_mreq.mcast_link_addr = inaddr_uni;
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_MEMBERSHIP, &_mreq);
|
||||
fail_if(ret == 0, "PICO_IP_ADD_MEMBERSHIP succeeded with invalid link address\n");
|
||||
_mreq.mcast_group_addr = inaddr_incorrect;
|
||||
_mreq.mcast_link_addr = inaddr_link[0];
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &_mreq);
|
||||
fail_if(ret == 0, "PICO_IP_DROP_MEMBERSHIP succeeded with invalid (not added) group address\n");
|
||||
_mreq.mcast_group_addr = inaddr_uni;
|
||||
_mreq.mcast_link_addr = inaddr_link[0];
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &_mreq);
|
||||
fail_if(ret == 0, "PICO_IP_DROP_MEMBERSHIP succeeded with invalid (unicast) group address\n");
|
||||
_mreq.mcast_group_addr = inaddr_null;
|
||||
_mreq.mcast_link_addr = inaddr_link[0];
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &_mreq);
|
||||
fail_if(ret == 0, "PICO_IP_DROP_MEMBERSHIP succeeded with invalid (NULL) group address\n");
|
||||
_mreq.mcast_group_addr = inaddr_dst;
|
||||
_mreq.mcast_link_addr = inaddr_uni;
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &_mreq);
|
||||
fail_if(ret == 0, "PICO_IP_DROP_MEMBERSHIP succeeded with invalid (unicast) link address\n");
|
||||
|
||||
/* flow validation tests */
|
||||
printf("IGMP SETOPTION FLOW VALIDATION TEST\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret == 0, "PICO_IP_ADD_MEMBERSHIP succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_UNBLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_UNBLOCK_SOURCE succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_BLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_BLOCK_SOURCE failed with err %s\n", strerror(pico_err));
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_ADD_SOURCE_MEMBERSHIP succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_DROP_SOURCE_MEMBERSHIP succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_MEMBERSHIP failed\n");
|
||||
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret == 0, "PICO_IP_DROP_MEMBERSHIP succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_UNBLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_UNBLOCK_SOURCE succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_BLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_BLOCK_SOURCE succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_SOURCE_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_SOURCE_MEMBERSHIP failed\n");
|
||||
|
||||
ret = pico_socket_setoption(s, PICO_IP_UNBLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_UNBLOCK_SOURCE succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_BLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_BLOCK_SOURCE succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_SOURCE_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_SOURCE_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_MEMBERSHIP failed\n");
|
||||
|
||||
ret = pico_socket_setoption(s, PICO_IP_BLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_BLOCK_SOURCE succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_SOURCE_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_SOURCE_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_UNBLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_UNBLOCK_SOURCE succeeded\n");
|
||||
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_SOURCE_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_ADD_SOURCE_MEMBERSHIP succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_SOURCE_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_UNBLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_UNBLOCK_SOURCE succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_BLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_BLOCK_SOURCE succeeded\n");
|
||||
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_DROP_SOURCE_MEMBERSHIP succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_UNBLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_UNBLOCK_MEMBERSHIP succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_BLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_BLOCK_MEMBERSHIP succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_SOURCE_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_MEMBERSHIP failed\n");
|
||||
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_SOURCE_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret == 0, "PICO_IP_ADD_MEMBERSHIP succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_UNBLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_UNBLOCK_SOURCE succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_BLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_BLOCK_SOURCE succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_SOURCE_MEMBERSHIP failed\n");
|
||||
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_ADD_SOURCE_MEMBERSHIP succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_BLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_BLOCK_SOURCE failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_UNBLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_UNBLOCK_SOURCE failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_DROP_SOURCE_MEMBERSHIP succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_MEMBERSHIP failed\n");
|
||||
|
||||
/* stress tests */
|
||||
printf("IGMP SETOPTION STRESS TEST\n");
|
||||
for (k = 0; k < 2; k++) {
|
||||
/* ADD for even combinations of group and link, ADD_SOURCE for uneven */
|
||||
for (i = 0; i < 16; i++) {
|
||||
if (i % 2) {
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_MEMBERSHIP, &mreq[i]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_MEMBERSHIP failed\n");
|
||||
for (j = 0; j < 8; j++) {
|
||||
ret = pico_socket_setoption(s, PICO_IP_BLOCK_SOURCE, &mreq_source[(i * 8) + j]);
|
||||
fail_if(ret < 0, "PICO_IP_BLOCK_SOURCE failed\n");
|
||||
}
|
||||
} else {
|
||||
for (j = 0; j < 8; j++) {
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source[(i * 8) + j]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_SOURCE_MEMBERSHIP failed\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
/* UNBLOCK and DROP for even combinations, DROP_SOURCE for uneven */
|
||||
for (i = 0; i < 16; i++) {
|
||||
if (i % 2) {
|
||||
for (j = 0; j < 8; j++) {
|
||||
ret = pico_socket_setoption(s, PICO_IP_UNBLOCK_SOURCE, &mreq_source[(i * 8) + j]);
|
||||
fail_if(ret < 0, "PICO_IP_UNBLOCK_SOURCE failed\n");
|
||||
}
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &mreq[i]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_MEMBERSHIP failed\n");
|
||||
} else {
|
||||
for (j = 0; j < 8; j++) {
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_SOURCE_MEMBERSHIP, &mreq_source[(i * 8) + j]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_SOURCE_MEMBERSHIP failed\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
/* everything should be cleanup up, next iteration will fail if not */
|
||||
}
|
||||
/* filter validation tests */
|
||||
printf("IGMP SETOPTION FILTER VALIDATION TEST\n");
|
||||
/* INCLUDE + INCLUDE expected filter: source of 0 and 1*/
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_SOURCE_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s1, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_SOURCE_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s1, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source[1]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_SOURCE_MEMBERSHIP failed\n");
|
||||
i = 0;
|
||||
pico_tree_foreach(index, &MCASTFilter)
|
||||
{
|
||||
if (++i > 2)
|
||||
fail("MCASTFilter (INCLUDE + INCLUDE) too many elements\n");
|
||||
|
||||
source = index->keyValue;
|
||||
if (source->ip4.addr == mreq_source[0].mcast_source_addr.ip4.addr) { /* OK */
|
||||
}
|
||||
else if (source->ip4.addr == mreq_source[1].mcast_source_addr.ip4.addr) { /* OK */
|
||||
}
|
||||
else {
|
||||
fail("MCASTFilter (INCLUDE + INCLUDE) incorrect\n");
|
||||
}
|
||||
}
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s1, PICO_IP_DROP_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_MEMBERSHIP failed\n");
|
||||
|
||||
/* INCLUDE + EXCLUDE expected filter: source of 2 */
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_SOURCE_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source[1]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_SOURCE_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s1, PICO_IP_ADD_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s1, PICO_IP_BLOCK_SOURCE, &mreq_source[1]);
|
||||
fail_if(ret < 0, "PICO_IP_BLOCK_SOURCE failed\n");
|
||||
ret = pico_socket_setoption(s1, PICO_IP_BLOCK_SOURCE, &mreq_source[2]);
|
||||
fail_if(ret < 0, "PICO_IP_BLOCK_SOURCE failed\n");
|
||||
i = 0;
|
||||
pico_tree_foreach(index, &MCASTFilter)
|
||||
{
|
||||
if (++i > 1)
|
||||
fail("MCASTFilter (INCLUDE + EXCLUDE) too many elements\n");
|
||||
|
||||
source = index->keyValue;
|
||||
if (source->ip4.addr == mreq_source[2].mcast_source_addr.ip4.addr) { /* OK */
|
||||
}
|
||||
else {
|
||||
fail("MCASTFilter (INCLUDE + EXCLUDE) incorrect\n");
|
||||
}
|
||||
}
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s1, PICO_IP_DROP_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_MEMBERSHIP failed\n");
|
||||
|
||||
/* EXCLUDE + INCLUDE expected filter: source of 0 and 1 */
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_BLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_BLOCK_SOURCE failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_BLOCK_SOURCE, &mreq_source[1]);
|
||||
fail_if(ret < 0, "PICO_IP_BLOCK_SOURCE failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_BLOCK_SOURCE, &mreq_source[3]);
|
||||
fail_if(ret < 0, "PICO_IP_BLOCK_SOURCE failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_BLOCK_SOURCE, &mreq_source[4]);
|
||||
fail_if(ret < 0, "PICO_IP_BLOCK_SOURCE failed\n");
|
||||
ret = pico_socket_setoption(s1, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source[3]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_SOURCE_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s1, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source[4]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_SOURCE_MEMBERSHIP failed\n");
|
||||
i = 0;
|
||||
pico_tree_foreach(index, &MCASTFilter)
|
||||
{
|
||||
if (++i > 2)
|
||||
fail("MCASTFilter (EXCLUDE + INCLUDE) too many elements\n");
|
||||
|
||||
source = index->keyValue;
|
||||
if (source->ip4.addr == mreq_source[0].mcast_source_addr.ip4.addr) { /* OK */
|
||||
}
|
||||
else if (source->ip4.addr == mreq_source[1].mcast_source_addr.ip4.addr) { /* OK */
|
||||
}
|
||||
else {
|
||||
fail("MCASTFilter (EXCLUDE + INCLUDE) incorrect\n");
|
||||
}
|
||||
}
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s1, PICO_IP_DROP_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_MEMBERSHIP failed\n");
|
||||
|
||||
/* EXCLUDE + EXCLUDE expected filter: source of 3 and 4 */
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_BLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_BLOCK_SOURCE failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_BLOCK_SOURCE, &mreq_source[1]);
|
||||
fail_if(ret < 0, "PICO_IP_BLOCK_SOURCE failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_BLOCK_SOURCE, &mreq_source[3]);
|
||||
fail_if(ret < 0, "PICO_IP_BLOCK_SOURCE failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_BLOCK_SOURCE, &mreq_source[4]);
|
||||
fail_if(ret < 0, "PICO_IP_BLOCK_SOURCE failed\n");
|
||||
ret = pico_socket_setoption(s1, PICO_IP_ADD_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s1, PICO_IP_BLOCK_SOURCE, &mreq_source[3]);
|
||||
fail_if(ret < 0, "PICO_IP_BLOCK_SOURCE failed\n");
|
||||
ret = pico_socket_setoption(s1, PICO_IP_BLOCK_SOURCE, &mreq_source[4]);
|
||||
fail_if(ret < 0, "PICO_IP_BLOCK_SOURCE failed\n");
|
||||
ret = pico_socket_setoption(s1, PICO_IP_BLOCK_SOURCE, &mreq_source[5]);
|
||||
fail_if(ret < 0, "PICO_IP_BLOCK_SOURCE failed\n");
|
||||
ret = pico_socket_setoption(s1, PICO_IP_BLOCK_SOURCE, &mreq_source[6]);
|
||||
fail_if(ret < 0, "PICO_IP_BLOCK_SOURCE failed\n");
|
||||
i = 0;
|
||||
pico_tree_foreach(index, &MCASTFilter)
|
||||
{
|
||||
if (++i > 2)
|
||||
fail("MCASTFilter (EXCLUDE + EXCLUDE) too many elements\n");
|
||||
|
||||
source = index->keyValue;
|
||||
if (source->ip4.addr == mreq_source[3].mcast_source_addr.ip4.addr) { /* OK */
|
||||
}
|
||||
else if (source->ip4.addr == mreq_source[4].mcast_source_addr.ip4.addr) { /* OK */
|
||||
}
|
||||
else {
|
||||
fail("MCASTFilter (EXCLUDE + EXCLUDE) incorrect\n");
|
||||
}
|
||||
}
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s1, PICO_IP_DROP_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_MEMBERSHIP failed\n");
|
||||
|
||||
|
||||
ret = pico_socket_close(s);
|
||||
fail_if(ret < 0, "socket close failed: %s\n", strerror(pico_err));
|
||||
ret = pico_socket_close(s1);
|
||||
fail_if(ret < 0, "socket close failed: %s\n", strerror(pico_err));
|
||||
}
|
||||
END_TEST
|
||||
#endif
|
||||
|
||||
START_TEST (test_slaacv4)
|
||||
{
|
||||
uint32_t tmp;
|
||||
struct pico_device *dev;
|
||||
struct mock_device *mock;
|
||||
char ip_addr[20];
|
||||
uint8_t macaddr1[6] = {
|
||||
0xc3, 0, 0, 0xa, 0xc, 0xf
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* verify min boundary*/
|
||||
tmp = SLAACV4_CREATE_IPV4(0);
|
||||
pico_ipv4_to_string(ip_addr, tmp);
|
||||
printf("IP address generated by slaac: %s\n", ip_addr);
|
||||
|
||||
fail_if(long_be(tmp) < (long_be(SLAACV4_NETWORK) | SLAACV4_MINRANGE));
|
||||
|
||||
/* verify max boundary*/
|
||||
tmp = SLAACV4_CREATE_IPV4(0x00FD);
|
||||
fail_if(long_be(tmp) > (long_be(SLAACV4_NETWORK) | 0x0000FEFF));
|
||||
|
||||
/* verify case where dev->eth is NULL */
|
||||
dev = pico_null_create("dummy");
|
||||
tmp = pico_slaacv4_getip(dev, 0);
|
||||
fail_if(long_be(tmp) != (long_be(SLAACV4_NETWORK) | SLAACV4_MINRANGE));
|
||||
/* verify nominal case; two runs of slaacv4_get_ip need to return same value */
|
||||
mock = pico_mock_create(macaddr1);
|
||||
tmp = pico_slaacv4_getip(mock->dev, 0);
|
||||
fail_if(tmp != pico_slaacv4_getip(mock->dev, 0));
|
||||
|
||||
}
|
||||
END_TEST
|
||||
760
kernel/picotcp/test/unit/unit_ipv6.c
Normal file
760
kernel/picotcp/test/unit/unit_ipv6.c
Normal file
@@ -0,0 +1,760 @@
|
||||
|
||||
#ifdef PICO_SUPPORT_IPV6
|
||||
START_TEST (test_ipv6)
|
||||
{
|
||||
char ipstr[40] = {
|
||||
0
|
||||
};
|
||||
char ipstr0[] = "2001:0db8:130f:0000:0000:09c0:876a:130b";
|
||||
char ipstr0_t[] = "2001:0db8:130f:0000:0000:09c0:876a:130b";
|
||||
char ipstr1[] = "2001:db8:130f:0000:0000:09c0:876a:130b";
|
||||
char ipstr1_t[] = "2001:0db8:130f:0000:0000:09c0:876a:130b";
|
||||
char ipstr2[] = "2001:b8:130f:0000:0000:09c0:876a:130b";
|
||||
char ipstr2_t[] = "2001:00b8:130f:0000:0000:09c0:876a:130b";
|
||||
char ipstr3[] = "2001:8:130f:0000:0000:09c0:876a:130b";
|
||||
char ipstr3_t[] = "2001:0008:130f:0000:0000:09c0:876a:130b";
|
||||
char ipstr4[] = "2001:8:130f:0:0:09c0:876a:130b";
|
||||
char ipstr4_t[] = "2001:0008:130f:0000:0000:09c0:876a:130b";
|
||||
char ipstr5[] = "2001::8:130f:09c0:876a:130b";
|
||||
char ipstr5_t[] = "2001:0000:0000:0008:130f:09c0:876a:130b";
|
||||
char ipstr6[] = "2001::8:09c0:876a:130b";
|
||||
char ipstr6_t[] = "2001:0000:0000:0000:0008:09c0:876a:130b";
|
||||
char ipstr7[] = "2001::8:876a:130b";
|
||||
char ipstr7_t[] = "2001:0000:0000:0000:0000:0008:876a:130b";
|
||||
char ipstr8[] = "2001::876a:130b";
|
||||
char ipstr8_t[] = "2001:0000:0000:0000:0000:0000:876a:130b";
|
||||
char ipstr9[] = "ff01::1";
|
||||
char ipstr9_t[] = "ff01:0000:0000:0000:0000:0000:0000:0001";
|
||||
char ipstr10[] = "::1";
|
||||
char ipstr10_t[] = "0000:0000:0000:0000:0000:0000:0000:0001";
|
||||
char ipstr11[] = "fe80::";
|
||||
char ipstr11_t[] = "fe80:0000:0000:0000:0000:0000:0000:0000";
|
||||
char ipstr12[] = "::";
|
||||
char ipstr12_t[] = "0000:0000:0000:0000:0000:0000:0000:0000";
|
||||
char ipstr13[] = "2001:8:130f::09c0::130b"; /* invalid */
|
||||
char ipstr14[] = "2001:8:xxxx::09c0:130b"; /* invalid */
|
||||
char ipstr15[] = "2001:8:$$$$::09c0:130b"; /* invalid */
|
||||
char ipstr16[] = "2001:8:!@#$::%^&*:()0b"; /* invalid */
|
||||
char ipstr17[] = "2001:1"; /* invalid */
|
||||
char ipstr18[] = "20010db8:130f:0000:0000:09c0:876a:130b"; /* invalid */
|
||||
char ipstr19[] = "20010db8130f0000000009c0876a130b"; /* invalid */
|
||||
char ipstr20[] = "2001;0db8;130f;0000;0000;09c0;876a;130b"; /* invalid */
|
||||
uint8_t iphex0[PICO_SIZE_IP6] = {
|
||||
0x20, 0x01, 0x0d, 0xb8, 0x13, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x09, 0xc0, 0x87, 0x6a, 0x13, 0x0b
|
||||
};
|
||||
uint8_t iphex1[PICO_SIZE_IP6] = {
|
||||
0x20, 0x01, 0x0d, 0xb8, 0x13, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x09, 0xc0, 0x87, 0x6a, 0x13, 0x0b
|
||||
};
|
||||
uint8_t iphex2[PICO_SIZE_IP6] = {
|
||||
0x20, 0x01, 0x00, 0xb8, 0x13, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x09, 0xc0, 0x87, 0x6a, 0x13, 0x0b
|
||||
};
|
||||
uint8_t iphex3[PICO_SIZE_IP6] = {
|
||||
0x20, 0x01, 0x00, 0x08, 0x13, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x09, 0xc0, 0x87, 0x6a, 0x13, 0x0b
|
||||
};
|
||||
uint8_t iphex4[PICO_SIZE_IP6] = {
|
||||
0x20, 0x01, 0x00, 0x08, 0x13, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x09, 0xc0, 0x87, 0x6a, 0x13, 0x0b
|
||||
};
|
||||
uint8_t iphex5[PICO_SIZE_IP6] = {
|
||||
0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x13, 0x0f, 0x09, 0xc0, 0x87, 0x6a, 0x13, 0x0b
|
||||
};
|
||||
uint8_t iphex6[PICO_SIZE_IP6] = {
|
||||
0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0xc0, 0x87, 0x6a, 0x13, 0x0b
|
||||
};
|
||||
uint8_t iphex7[PICO_SIZE_IP6] = {
|
||||
0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x87, 0x6a, 0x13, 0x0b
|
||||
};
|
||||
uint8_t iphex8[PICO_SIZE_IP6] = {
|
||||
0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, 0x6a, 0x13, 0x0b
|
||||
};
|
||||
uint8_t iphex9[PICO_SIZE_IP6] = {
|
||||
0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
|
||||
};
|
||||
uint8_t iphex10[PICO_SIZE_IP6] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
|
||||
};
|
||||
uint8_t iphex11[PICO_SIZE_IP6] = {
|
||||
0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
uint8_t iphex12[PICO_SIZE_IP6] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
struct pico_ip6 iphex_a = {{ 0x20, 0x01, 0x0d, 0xb8, 0x13, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }};
|
||||
struct pico_ip6 iphex_r = {{ 0x40, 0x02, 0x0d, 0xb8, 0x13, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 }};
|
||||
struct pico_ip6 iphex_gw = {{ 0x20, 0x01, 0x0d, 0xb8, 0x13, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f }};
|
||||
struct pico_ip6 nm64 = {{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }};
|
||||
struct pico_ip6 nm128 = {{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }};
|
||||
struct pico_ip6 ipaddr = {{0}};
|
||||
|
||||
struct pico_ip6 _gw, r[IP_TST_SIZ], a[IP_TST_SIZ], gw[IP_TST_SIZ], *source[IP_TST_SIZ];
|
||||
struct pico_device *dev[IP_TST_SIZ];
|
||||
struct pico_ipv6_link *l[IP_TST_SIZ];
|
||||
struct pico_ipv6_link *_link = NULL;
|
||||
struct pico_ipv6_route *_route = NULL;
|
||||
char devname[8];
|
||||
int ret = 0;
|
||||
int i = 0;
|
||||
|
||||
pico_stack_init();
|
||||
|
||||
/* pico_string_to_ipv6 and pico_ipv6_to_string */
|
||||
printf("pico_string_to_ipv6 valid conversion of %s\n", ipstr0);
|
||||
pico_string_to_ipv6(ipstr0, ipaddr.addr);
|
||||
fail_if(memcmp(ipaddr.addr, iphex0, PICO_SIZE_IP6), "Error string to ipv6");
|
||||
pico_ipv6_to_string(ipstr, ipaddr.addr);
|
||||
printf("pico_ipv6_to_string valid conversion to %s\n", ipstr);
|
||||
fail_if(strncmp(ipstr, ipstr0_t, 40) != 0, "Error ipv6 to string");
|
||||
|
||||
printf("pico_string_to_ipv6 valid conversion of %s\n", ipstr1);
|
||||
pico_string_to_ipv6(ipstr1, ipaddr.addr);
|
||||
fail_if(memcmp(ipaddr.addr, iphex1, PICO_SIZE_IP6), "Error string to ipv6");
|
||||
pico_ipv6_to_string(ipstr, ipaddr.addr);
|
||||
printf("pico_ipv6_to_string valid conversion to %s\n", ipstr);
|
||||
fail_if(strncmp(ipstr, ipstr1_t, 40) != 0, "Error ipv6 to string");
|
||||
|
||||
printf("pico_string_to_ipv6 valid conversion of %s\n", ipstr2);
|
||||
pico_string_to_ipv6(ipstr2, ipaddr.addr);
|
||||
fail_if(memcmp(ipaddr.addr, iphex2, PICO_SIZE_IP6), "Error string to ipv6");
|
||||
pico_ipv6_to_string(ipstr, ipaddr.addr);
|
||||
printf("pico_ipv6_to_string valid conversion to %s\n", ipstr);
|
||||
fail_if(strncmp(ipstr, ipstr2_t, 40) != 0, "Error ipv6 to string");
|
||||
|
||||
printf("pico_string_to_ipv6 valid conversion of %s\n", ipstr3);
|
||||
pico_string_to_ipv6(ipstr3, ipaddr.addr);
|
||||
fail_if(memcmp(ipaddr.addr, iphex3, PICO_SIZE_IP6), "Error string to ipv6");
|
||||
pico_ipv6_to_string(ipstr, ipaddr.addr);
|
||||
printf("pico_ipv6_to_string valid conversion to %s\n", ipstr);
|
||||
fail_if(strncmp(ipstr, ipstr3_t, 40) != 0, "Error ipv6 to string");
|
||||
|
||||
printf("pico_string_to_ipv6 valid conversion of %s\n", ipstr4);
|
||||
pico_string_to_ipv6(ipstr4, ipaddr.addr);
|
||||
fail_if(memcmp(ipaddr.addr, iphex4, PICO_SIZE_IP6), "Error string to ipv6");
|
||||
pico_ipv6_to_string(ipstr, ipaddr.addr);
|
||||
printf("pico_ipv6_to_string valid conversion to %s\n", ipstr);
|
||||
fail_if(strncmp(ipstr, ipstr4_t, 40) != 0, "Error ipv6 to string");
|
||||
|
||||
printf("pico_string_to_ipv6 valid conversion of %s\n", ipstr5);
|
||||
pico_string_to_ipv6(ipstr5, ipaddr.addr);
|
||||
fail_if(memcmp(ipaddr.addr, iphex5, PICO_SIZE_IP6), "Error string to ipv6");
|
||||
pico_ipv6_to_string(ipstr, ipaddr.addr);
|
||||
printf("pico_ipv6_to_string valid conversion to %s\n", ipstr);
|
||||
fail_if(strncmp(ipstr, ipstr5_t, 40) != 0, "Error ipv6 to string");
|
||||
|
||||
printf("pico_string_to_ipv6 valid conversion of %s\n", ipstr6);
|
||||
pico_string_to_ipv6(ipstr6, ipaddr.addr);
|
||||
fail_if(memcmp(ipaddr.addr, iphex6, PICO_SIZE_IP6), "Error string to ipv6");
|
||||
pico_ipv6_to_string(ipstr, ipaddr.addr);
|
||||
printf("pico_ipv6_to_string valid conversion to %s\n", ipstr);
|
||||
fail_if(strncmp(ipstr, ipstr6_t, 40) != 0, "Error ipv6 to string");
|
||||
|
||||
printf("pico_string_to_ipv6 valid conversion of %s\n", ipstr7);
|
||||
pico_string_to_ipv6(ipstr7, ipaddr.addr);
|
||||
fail_if(memcmp(ipaddr.addr, iphex7, PICO_SIZE_IP6), "Error string to ipv6");
|
||||
pico_ipv6_to_string(ipstr, ipaddr.addr);
|
||||
printf("pico_ipv6_to_string valid conversion to %s\n", ipstr);
|
||||
fail_if(strncmp(ipstr, ipstr7_t, 40) != 0, "Error ipv6 to string");
|
||||
|
||||
printf("pico_string_to_ipv6 valid conversion of %s\n", ipstr8);
|
||||
pico_string_to_ipv6(ipstr8, ipaddr.addr);
|
||||
fail_if(memcmp(ipaddr.addr, iphex8, PICO_SIZE_IP6), "Error string to ipv6");
|
||||
pico_ipv6_to_string(ipstr, ipaddr.addr);
|
||||
printf("pico_ipv6_to_string valid conversion to %s\n", ipstr);
|
||||
fail_if(strncmp(ipstr, ipstr8_t, 40) != 0, "Error ipv6 to string");
|
||||
|
||||
printf("pico_string_to_ipv6 valid conversion of %s\n", ipstr9);
|
||||
pico_string_to_ipv6(ipstr9, ipaddr.addr);
|
||||
fail_if(memcmp(ipaddr.addr, iphex9, PICO_SIZE_IP6), "Error string to ipv6");
|
||||
pico_ipv6_to_string(ipstr, ipaddr.addr);
|
||||
printf("pico_ipv6_to_string valid conversion to %s\n", ipstr);
|
||||
fail_if(strncmp(ipstr, ipstr9_t, 40) != 0, "Error ipv6 to string");
|
||||
|
||||
printf("pico_string_to_ipv6 valid conversion of %s\n", ipstr10);
|
||||
pico_string_to_ipv6(ipstr10, ipaddr.addr);
|
||||
fail_if(memcmp(ipaddr.addr, iphex10, PICO_SIZE_IP6), "Error string to ipv6");
|
||||
pico_ipv6_to_string(ipstr, ipaddr.addr);
|
||||
printf("pico_ipv6_to_string valid conversion to %s\n", ipstr);
|
||||
fail_if(strncmp(ipstr, ipstr10_t, 40) != 0, "Error ipv6 to string");
|
||||
|
||||
printf("pico_string_to_ipv6 valid conversion of %s\n", ipstr11);
|
||||
pico_string_to_ipv6(ipstr11, ipaddr.addr);
|
||||
fail_if(memcmp(ipaddr.addr, iphex11, PICO_SIZE_IP6), "Error string to ipv6");
|
||||
pico_ipv6_to_string(ipstr, ipaddr.addr);
|
||||
printf("pico_ipv6_to_string valid conversion to %s\n", ipstr);
|
||||
fail_if(strncmp(ipstr, ipstr11_t, 40) != 0, "Error ipv6 to string");
|
||||
|
||||
printf("pico_string_to_ipv6 valid conversion of %s\n", ipstr12);
|
||||
pico_string_to_ipv6(ipstr12, ipaddr.addr);
|
||||
fail_if(memcmp(ipaddr.addr, iphex12, PICO_SIZE_IP6), "Error string to ipv6");
|
||||
pico_ipv6_to_string(ipstr, ipaddr.addr);
|
||||
printf("pico_ipv6_to_string valid conversion to %s\n", ipstr);
|
||||
fail_if(strncmp(ipstr, ipstr12_t, 40) != 0, "Error ipv6 to string");
|
||||
|
||||
printf("pico_string_to_ipv6 invalid conversion of %s\n", ipstr13);
|
||||
ret = pico_string_to_ipv6(ipstr13, ipaddr.addr);
|
||||
fail_if(ret == 0, "Error string to ipv6");
|
||||
|
||||
printf("pico_string_to_ipv6 invalid conversion of %s\n", ipstr14);
|
||||
ret = pico_string_to_ipv6(ipstr14, ipaddr.addr);
|
||||
fail_if(ret == 0, "Error string to ipv6");
|
||||
|
||||
printf("pico_string_to_ipv6 invalid conversion of %s\n", ipstr15);
|
||||
ret = pico_string_to_ipv6(ipstr15, ipaddr.addr);
|
||||
fail_if(ret == 0, "Error string to ipv6");
|
||||
|
||||
printf("pico_string_to_ipv6 invalid conversion of %s\n", ipstr16);
|
||||
ret = pico_string_to_ipv6(ipstr16, ipaddr.addr);
|
||||
fail_if(ret == 0, "Error string to ipv6");
|
||||
|
||||
printf("pico_string_to_ipv6 invalid conversion of %s\n", ipstr17);
|
||||
ret = pico_string_to_ipv6(ipstr17, ipaddr.addr);
|
||||
fail_if(ret == 0, "Error string to ipv6");
|
||||
|
||||
printf("pico_string_to_ipv6 invalid conversion of %s\n", ipstr18);
|
||||
ret = pico_string_to_ipv6(ipstr18, ipaddr.addr);
|
||||
fail_if(ret == 0, "Error string to ipv6");
|
||||
|
||||
printf("pico_string_to_ipv6 invalid conversion of %s\n", ipstr19);
|
||||
ret = pico_string_to_ipv6(ipstr19, ipaddr.addr);
|
||||
fail_if(ret == 0, "Error string to ipv6");
|
||||
|
||||
printf("pico_string_to_ipv6 invalid conversion of %s\n", ipstr20);
|
||||
ret = pico_string_to_ipv6(ipstr20, ipaddr.addr);
|
||||
fail_if(ret == 0, "Error string to ipv6");
|
||||
|
||||
/*link_add*/
|
||||
for (i = 0; i < 10; ++i) {
|
||||
snprintf(devname, 8, "nul%d", i);
|
||||
dev[i] = pico_null_create(devname);
|
||||
a[i] = iphex_a;
|
||||
a[i].addr[4] = (uint8_t)(a[i].addr[4] + i);
|
||||
fail_if(pico_ipv6_link_add(dev[i], a[i], nm64) == NULL, "Error adding link");
|
||||
}
|
||||
/*link_find + link_get + route_add*/
|
||||
for (i = 0; i < 10; ++i) {
|
||||
gw[i] = iphex_gw;
|
||||
gw[i].addr[4] = (uint8_t)(gw[i].addr[4] + i);
|
||||
fail_unless(pico_ipv6_link_find(&a[i]) == dev[i], "Error finding link");
|
||||
l[i] = pico_ipv6_link_get(&a[i]);
|
||||
fail_if(l[i] == NULL, "Error getting link");
|
||||
r[i] = iphex_r;
|
||||
r[i].addr[4] = (uint8_t)(r[i].addr[4] + i);
|
||||
fail_if(pico_ipv6_route_add(r[i], nm128, a[i], 1, l[i]) != 0, "Error adding route");
|
||||
}
|
||||
/*get_gateway*/
|
||||
for (i = 0; i < 10; i++) {
|
||||
_gw = pico_ipv6_route_get_gateway(&r[i]);
|
||||
fail_if(memcmp(_gw.addr, a[i].addr, PICO_SIZE_IP6) != 0, "Error get gateway: returned wrong route");
|
||||
source[i] = pico_ipv6_source_find(&r[i]);
|
||||
fail_if(memcmp(source[i]->addr, a[i].addr, PICO_SIZE_IP6) != 0, "Error find source: returned wrong route");
|
||||
}
|
||||
/*route_del + link_del*/
|
||||
for (i = 0; i < 10; i++) {
|
||||
fail_if(pico_ipv6_route_del(r[i], nm128, a[i], 1, l[i]) != 0, "Error deleting route");
|
||||
fail_if(pico_ipv6_link_del(dev[i], a[i]) != 0, "Error deleting link");
|
||||
}
|
||||
/* add 2 links to dev[0] */
|
||||
_link = pico_ipv6_link_add(dev[0], a[0], nm64);
|
||||
fail_if (!_link, "Error adding link");
|
||||
_link = pico_ipv6_link_add(dev[0], a[1], nm64);
|
||||
fail_if (!_link, "Error adding link");
|
||||
/* add 2 routes to each of the links */
|
||||
ret = pico_ipv6_route_add(r[0], nm128, a[0], 1, l[0]);
|
||||
fail_if(ret != 0, "Error adding route");
|
||||
ret = pico_ipv6_route_add(r[1], nm128, a[0], 1, l[0]);
|
||||
fail_if(ret != 0, "Error adding route");
|
||||
ret = pico_ipv6_route_add(r[2], nm128, a[1], 1, l[1]);
|
||||
fail_if(ret != 0, "Error adding route");
|
||||
ret = pico_ipv6_route_add(r[3], nm128, a[1], 1, l[1]);
|
||||
fail_if(ret != 0, "Error adding route");
|
||||
|
||||
/* add 2 links to dev[1] */
|
||||
_link = pico_ipv6_link_add(dev[1], a[8], nm64);
|
||||
fail_if (!_link, "Error adding link");
|
||||
_link = pico_ipv6_link_add(dev[1], a[9], nm64);
|
||||
fail_if (!_link, "Error adding link");
|
||||
/* add 2 routes to each of the links */
|
||||
ret = pico_ipv6_route_add(r[6], nm128, a[8], 1, l[8]);
|
||||
fail_if(ret != 0, "Error adding route");
|
||||
ret = pico_ipv6_route_add(r[7], nm128, a[8], 1, l[8]);
|
||||
fail_if(ret != 0, "Error adding route");
|
||||
ret = pico_ipv6_route_add(r[8], nm128, a[9], 1, l[9]);
|
||||
fail_if(ret != 0, "Error adding route");
|
||||
ret = pico_ipv6_route_add(r[9], nm128, a[9], 1, l[9]);
|
||||
fail_if(ret != 0, "Error adding route");
|
||||
|
||||
/* destroy device, should clean up all links and routes */
|
||||
pico_device_destroy(dev[0]);
|
||||
_link = pico_ipv6_link_get(&a[0]);
|
||||
fail_if(_link != NULL, "Error destroying device");
|
||||
_link = pico_ipv6_link_get(&a[1]);
|
||||
fail_if(_link != NULL, "Error destroying device");
|
||||
_link = pico_ipv6_link_get(&a[8]);
|
||||
fail_if(_link == NULL, "Error destroying device");
|
||||
_link = pico_ipv6_link_get(&a[9]);
|
||||
fail_if(_link == NULL, "Error destroying device");
|
||||
|
||||
_route = pico_ipv6_route_find(&r[0]);
|
||||
fail_if(_route != NULL, "Error destroying device");
|
||||
_route = pico_ipv6_route_find(&r[1]);
|
||||
fail_if(_route != NULL, "Error destroying device");
|
||||
_route = pico_ipv6_route_find(&r[2]);
|
||||
fail_if(_route != NULL, "Error destroying device");
|
||||
_route = pico_ipv6_route_find(&r[3]);
|
||||
fail_if(_route != NULL, "Error destroying device");
|
||||
|
||||
_route = pico_ipv6_route_find(&r[6]);
|
||||
fail_if(_route == NULL, "Error destroying device");
|
||||
_route = pico_ipv6_route_find(&r[7]);
|
||||
fail_if(_route == NULL, "Error destroying device");
|
||||
_route = pico_ipv6_route_find(&r[8]);
|
||||
fail_if(_route == NULL, "Error destroying device");
|
||||
_route = pico_ipv6_route_find(&r[9]);
|
||||
fail_if(_route == NULL, "Error destroying device");
|
||||
}
|
||||
END_TEST
|
||||
|
||||
#ifdef PICO_SUPPORT_MCAST
|
||||
START_TEST (test_mld_sockopts)
|
||||
{
|
||||
int i = 0, j = 0, k = 0, ret = 0;
|
||||
struct pico_socket *s, *s1 = NULL;
|
||||
struct pico_device *dev = NULL;
|
||||
union pico_address *source = NULL;
|
||||
union pico_address inaddr_dst = {
|
||||
0
|
||||
}, inaddr_incorrect = {
|
||||
0
|
||||
}, inaddr_uni = {
|
||||
0
|
||||
}, inaddr_null = {
|
||||
0
|
||||
};
|
||||
struct pico_ip6 netmask = {{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }};
|
||||
|
||||
union pico_address inaddr_link[2] = {0};
|
||||
union pico_address inaddr_mcast[8] = {0};
|
||||
union pico_address inaddr_source[8] = {0};
|
||||
struct pico_ip_mreq _mreq = {0}, mreq[16] = {0};
|
||||
struct pico_ip_mreq_source mreq_source[128] = {0};
|
||||
struct pico_tree_node *index = NULL;
|
||||
struct pico_ipv6_link *ret_link = NULL;
|
||||
int ttl = 64;
|
||||
int getttl = 0;
|
||||
int loop = 9;
|
||||
int getloop = 0;
|
||||
struct pico_ip6 mcast_def_link = {
|
||||
0
|
||||
};
|
||||
|
||||
pico_stack_init();
|
||||
|
||||
printf("START MLD SOCKOPTS TEST\n");
|
||||
|
||||
pico_string_to_ipv6("ff00:0:0:0:0:0:e007:707", inaddr_dst.ip6.addr);
|
||||
pico_string_to_ipv6("fe80:0:0:0:0:0:a28:2", inaddr_uni.ip6.addr);
|
||||
pico_string_to_ipv6("ff00:0:0:0:0:0:e008:808", inaddr_incorrect.ip6.addr);
|
||||
pico_string_to_ipv6("::", inaddr_null.ip6.addr);
|
||||
|
||||
pico_string_to_ipv6("fe80:0:0:0:0:0:a28:0001", inaddr_link[0].ip6.addr); /* 0 */
|
||||
pico_string_to_ipv6("fe80:0:0:0:0:0:a32:0001", inaddr_link[1].ip6.addr); /* 1 */
|
||||
|
||||
pico_string_to_ipv6("ff00:0:0:0:0:0:e801:100", inaddr_mcast[0].ip6.addr); /* 0 */
|
||||
pico_string_to_ipv6("ff00:0:0:0:0:0:e802:201", inaddr_mcast[1].ip6.addr); /* 1 */
|
||||
pico_string_to_ipv6("ff00:0:0:0:0:0:e803:302", inaddr_mcast[2].ip6.addr); /* 2 */
|
||||
pico_string_to_ipv6("ff00:0:0:0:0:0:e803:403", inaddr_mcast[3].ip6.addr); /* 3 */
|
||||
pico_string_to_ipv6("ff00:0:0:0:0:0:e803:504", inaddr_mcast[4].ip6.addr); /* 4 */
|
||||
pico_string_to_ipv6("ff00:0:0:0:0:0:e803:605", inaddr_mcast[5].ip6.addr); /* 5 */
|
||||
pico_string_to_ipv6("ff00:0:0:0:0:0:e803:706", inaddr_mcast[6].ip6.addr); /* 6 */
|
||||
pico_string_to_ipv6("ff00:0:0:0:0:0:e803:807", inaddr_mcast[7].ip6.addr); /* 7 */
|
||||
|
||||
pico_string_to_ipv6("fe80:0:0:0:0:0:a28:100", inaddr_source[0].ip6.addr); /* 0 */
|
||||
pico_string_to_ipv6("fe80:0:0:0:0:0:a28:101", inaddr_source[1].ip6.addr); /* 1 */
|
||||
pico_string_to_ipv6("fe80:0:0:0:0:0:a28:102", inaddr_source[2].ip6.addr); /* 2 */
|
||||
pico_string_to_ipv6("fe80:0:0:0:0:0:a28:103", inaddr_source[3].ip6.addr); /* 3 */
|
||||
pico_string_to_ipv6("fe80:0:0:0:0:0:a28:104", inaddr_source[4].ip6.addr); /* 4 */
|
||||
pico_string_to_ipv6("fe80:0:0:0:0:0:a28:105", inaddr_source[5].ip6.addr); /* 5 */
|
||||
pico_string_to_ipv6("fe80:0:0:0:0:0:a28:106", inaddr_source[6].ip6.addr); /* 6 */
|
||||
pico_string_to_ipv6("fe80:0:0:0:0:0:a28:107", inaddr_source[7].ip6.addr); /* 7 */
|
||||
|
||||
/* 00 01 02 03 04 05 06 07 | 10 11 12 13 14 15 16 17 */
|
||||
for (i = 0; i < 16; i++) {
|
||||
mreq[i].mcast_link_addr = inaddr_link[i / 8];
|
||||
mreq[i].mcast_group_addr = inaddr_mcast[i % 8];
|
||||
}
|
||||
/* 000 001 002 003 004 005 006 007 | 010 011 012 013 014 015 016 017 */
|
||||
for (i = 0; i < 16; i++) {
|
||||
for (j = 0; j < 8; j++) {
|
||||
/* printf(">>>>> mreq_source[%d]: link[%d] mcast[%d] source[%d]\n", (i*8)+j, i/8, i%8, j); */
|
||||
mreq_source[(i * 8) + j].mcast_link_addr = inaddr_link[i / 8];
|
||||
mreq_source[(i * 8) + j].mcast_group_addr = inaddr_mcast[i % 8];
|
||||
mreq_source[(i * 8) + j].mcast_source_addr = inaddr_source[j];
|
||||
}
|
||||
}
|
||||
dev = pico_null_create("dummy0");
|
||||
ret_link = pico_ipv6_link_add(dev, inaddr_link[0].ip6, netmask);
|
||||
fail_if(ret_link == NULL, "link add failed");
|
||||
dev = pico_null_create("dummy1");
|
||||
ret_link = pico_ipv6_link_add(dev, inaddr_link[1].ip6, netmask);
|
||||
fail_if(ret_link == NULL, "link add failed");
|
||||
|
||||
|
||||
s = pico_socket_open(PICO_PROTO_IPV6, PICO_PROTO_UDP, NULL);
|
||||
fail_if(s == NULL, "UDP socket open failed");
|
||||
s1 = pico_socket_open(PICO_PROTO_IPV6, PICO_PROTO_UDP, NULL);
|
||||
fail_if(s1 == NULL, "UDP socket open failed");
|
||||
|
||||
|
||||
/* argument validation tests */
|
||||
printf("MLD SETOPTION ARGUMENT VALIDATION TEST\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_MULTICAST_IF, &mcast_def_link);
|
||||
fail_if(ret == 0, "unsupported PICO_IP_MULTICAST_IF succeeded\n");
|
||||
ret = pico_socket_getoption(s, PICO_IP_MULTICAST_IF, &mcast_def_link);
|
||||
fail_if(ret == 0, "unsupported PICO_IP_MULTICAST_IF succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_MULTICAST_TTL, &ttl);
|
||||
fail_if(ret < 0, "supported PICO_IP_MULTICAST_TTL failed\n");
|
||||
|
||||
ret = pico_socket_getoption(s, PICO_IP_MULTICAST_TTL, &getttl);
|
||||
fail_if(ret < 0, "supported PICO_IP_MULTICAST_TTL failed\n");
|
||||
fail_if(getttl != ttl, "setoption ttl != getoption ttl\n");
|
||||
|
||||
ret = pico_socket_setoption(s, PICO_IP_MULTICAST_LOOP, &loop);
|
||||
fail_if(ret == 0, "PICO_IP_MULTICAST_LOOP succeeded with invalid (not 0 or 1) loop value\n");
|
||||
loop = 0;
|
||||
ret = pico_socket_setoption(s, PICO_IP_MULTICAST_LOOP, &loop);
|
||||
fail_if(ret < 0, "supported PICO_IP_MULTICAST_LOOP failed disabling\n");
|
||||
ret = pico_socket_getoption(s, PICO_IP_MULTICAST_LOOP, &getloop);
|
||||
fail_if(ret < 0, "supported PICO_IP_MULTICAST_LOOP failed getting value\n");
|
||||
fail_if(getloop != loop, "setoption loop != getoption loop\n");
|
||||
memcpy(&_mreq.mcast_group_addr, &inaddr_dst.ip6, sizeof(struct pico_ip6));
|
||||
memcpy(&_mreq.mcast_link_addr, &inaddr_link[0].ip6, sizeof(struct pico_ip6));
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_MEMBERSHIP, &_mreq);
|
||||
fail_if(ret < 0, "supported PICO_IP_ADD_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &_mreq);
|
||||
fail_if(ret < 0, "supported PICO_IP_DROP_MEMBERSHIP failed\n");
|
||||
memcpy(&_mreq.mcast_group_addr, &inaddr_dst.ip6, sizeof(struct pico_ip6));
|
||||
memcpy(&_mreq.mcast_link_addr, &inaddr_null.ip6, sizeof(struct pico_ip6));
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_MEMBERSHIP, &_mreq);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_MEMBERSHIP failed with valid NULL (use default) link address\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &_mreq);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_MEMBERSHIP failed with valid NULL (use default) link address\n");
|
||||
memcpy(&_mreq.mcast_group_addr, &inaddr_uni.ip6, sizeof(struct pico_ip6));
|
||||
memcpy(&_mreq.mcast_link_addr, &inaddr_link[0].ip6, sizeof(struct pico_ip6));
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_MEMBERSHIP, &_mreq);
|
||||
fail_if(ret == 0, "PICO_IP_ADD_MEMBERSHIP succeeded with invalid (unicast) group address\n");
|
||||
memcpy(&_mreq.mcast_group_addr, &inaddr_null.ip6, sizeof(struct pico_ip6));
|
||||
memcpy(&_mreq.mcast_link_addr, &inaddr_link[0].ip6, sizeof(struct pico_ip6));
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_MEMBERSHIP, &_mreq);
|
||||
fail_if(ret == 0, "PICO_IP_ADD_MEMBERSHIP succeeded with invalid (NULL) group address\n");
|
||||
memcpy(&_mreq.mcast_group_addr, &inaddr_dst.ip6, sizeof(struct pico_ip6));
|
||||
memcpy(&_mreq.mcast_link_addr, &inaddr_uni.ip6, sizeof(struct pico_ip6));
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_MEMBERSHIP, &_mreq);
|
||||
fail_if(ret == 0, "PICO_IP_ADD_MEMBERSHIP succeeded with invalid link address\n");
|
||||
memcpy(&_mreq.mcast_group_addr, &inaddr_incorrect.ip6, sizeof(struct pico_ip6));
|
||||
memcpy(&_mreq.mcast_link_addr, &inaddr_link[0].ip6, sizeof(struct pico_ip6));
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &_mreq);
|
||||
fail_if(ret == 0, "PICO_IP_DROP_MEMBERSHIP succeeded with invalid (not added) group address\n");
|
||||
memcpy(&_mreq.mcast_group_addr, &inaddr_uni.ip6, sizeof(struct pico_ip6));
|
||||
memcpy(&_mreq.mcast_link_addr, &inaddr_link[0].ip6, sizeof(struct pico_ip6));
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &_mreq);
|
||||
fail_if(ret == 0, "PICO_IP_DROP_MEMBERSHIP succeeded with invalid (unicast) group address\n");
|
||||
memcpy(&_mreq.mcast_group_addr, &inaddr_null.ip6, sizeof(struct pico_ip6));
|
||||
memcpy(&_mreq.mcast_link_addr, &inaddr_link[0].ip6, sizeof(struct pico_ip6));
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &_mreq);
|
||||
fail_if(ret == 0, "PICO_IP_DROP_MEMBERSHIP succeeded with invalid (NULL) group address\n");
|
||||
memcpy(&_mreq.mcast_group_addr, &inaddr_dst.ip6, sizeof(struct pico_ip6));
|
||||
memcpy(&_mreq.mcast_link_addr, &inaddr_uni.ip6, sizeof(struct pico_ip6));
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &_mreq);
|
||||
fail_if(ret == 0, "PICO_IP_DROP_MEMBERSHIP succeeded with invalid (unicast) link address\n");
|
||||
/* flow validation tests */
|
||||
printf("MLD SETOPTION FLOW VALIDATION TEST\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret == 0, "PICO_IP_ADD_MEMBERSHIP succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_UNBLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_UNBLOCK_SOURCE succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_BLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_BLOCK_SOURCE failed with err %s\n", strerror(pico_err));
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_ADD_SOURCE_MEMBERSHIP succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_DROP_SOURCE_MEMBERSHIP succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_MEMBERSHIP failed\n");
|
||||
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret == 0, "PICO_IP_DROP_MEMBERSHIP succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_UNBLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_UNBLOCK_SOURCE succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_BLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_BLOCK_SOURCE succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_SOURCE_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_SOURCE_MEMBERSHIP failed\n");
|
||||
|
||||
ret = pico_socket_setoption(s, PICO_IP_UNBLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_UNBLOCK_SOURCE succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_BLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_BLOCK_SOURCE succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_SOURCE_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_SOURCE_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_MEMBERSHIP failed\n");
|
||||
|
||||
ret = pico_socket_setoption(s, PICO_IP_BLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_BLOCK_SOURCE succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_SOURCE_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_SOURCE_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_UNBLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_UNBLOCK_SOURCE succeeded\n");
|
||||
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_SOURCE_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_ADD_SOURCE_MEMBERSHIP succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_SOURCE_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_UNBLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_UNBLOCK_SOURCE succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_BLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_BLOCK_SOURCE succeeded\n");
|
||||
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_DROP_SOURCE_MEMBERSHIP succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_UNBLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_UNBLOCK_MEMBERSHIP succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_BLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_BLOCK_MEMBERSHIP succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_SOURCE_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_MEMBERSHIP failed\n");
|
||||
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_SOURCE_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret == 0, "PICO_IP_ADD_MEMBERSHIP succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_UNBLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_UNBLOCK_SOURCE succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_BLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_BLOCK_SOURCE succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_SOURCE_MEMBERSHIP failed\n");
|
||||
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_ADD_SOURCE_MEMBERSHIP succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_BLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_BLOCK_SOURCE failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_UNBLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_UNBLOCK_SOURCE failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_DROP_SOURCE_MEMBERSHIP succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_MEMBERSHIP failed\n");
|
||||
/* stress tests */
|
||||
|
||||
printf("MLD SETOPTION STRESS TEST\n");
|
||||
for (k = 0; k < 2; k++) {
|
||||
/* ADD for even combinations of group and link, ADD_SOURCE for uneven */
|
||||
for (i = 0; i < 16; i++) {
|
||||
if (i % 2) {
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_MEMBERSHIP, &mreq[i]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_MEMBERSHIP failed\n");
|
||||
for (j = 0; j < 8; j++) {
|
||||
ret = pico_socket_setoption(s, PICO_IP_BLOCK_SOURCE, &mreq_source[(i * 8) + j]);
|
||||
fail_if(ret < 0, "PICO_IP_BLOCK_SOURCE failed\n");
|
||||
}
|
||||
} else {
|
||||
for (j = 0; j < 8; j++) {
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source[(i * 8) + j]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_SOURCE_MEMBERSHIP failed\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
/* UNBLOCK and DROP for even combinations, DROP_SOURCE for uneven */
|
||||
for (i = 0; i < 16; i++) {
|
||||
if (i % 2) {
|
||||
for (j = 0; j < 8; j++) {
|
||||
ret = pico_socket_setoption(s, PICO_IP_UNBLOCK_SOURCE, &mreq_source[(i * 8) + j]);
|
||||
fail_if(ret < 0, "PICO_IP_UNBLOCK_SOURCE failed\n");
|
||||
}
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &mreq[i]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_MEMBERSHIP failed\n");
|
||||
} else {
|
||||
for (j = 0; j < 8; j++) {
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_SOURCE_MEMBERSHIP, &mreq_source[(i * 8) + j]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_SOURCE_MEMBERSHIP failed\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
/* everything should be cleanup up, next iteration will fail if not */
|
||||
}
|
||||
/* filter validation tests */
|
||||
printf("MLD SETOPTION FILTER VALIDATION TEST\n");
|
||||
/* INCLUDE + INCLUDE expected filter: source of 0 and 1*/
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_SOURCE_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s1, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_SOURCE_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s1, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source[1]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_SOURCE_MEMBERSHIP failed\n");
|
||||
i = 0;
|
||||
|
||||
pico_tree_foreach(index, &MCASTFilter)
|
||||
{
|
||||
if (++i > 2)
|
||||
fail("MCASTFilter (INCLUDE + INCLUDE) too many elements\n");
|
||||
|
||||
source = index->keyValue;
|
||||
if (memcmp(&source->ip6, &mreq_source[0].mcast_source_addr, sizeof(struct pico_ip6)) == 0) { /* OK */
|
||||
}
|
||||
else if (memcmp(&source->ip6, &mreq_source[1].mcast_source_addr, sizeof(struct pico_ip6)) == 0) { /* OK */
|
||||
}
|
||||
else {
|
||||
fail("MCASTFilter (INCLUDE + INCLUDE) incorrect\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s1, PICO_IP_DROP_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_MEMBERSHIP failed\n");
|
||||
|
||||
/* INCLUDE + EXCLUDE expected filter: source of 2 */
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_SOURCE_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source[1]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_SOURCE_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s1, PICO_IP_ADD_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s1, PICO_IP_BLOCK_SOURCE, &mreq_source[1]);
|
||||
fail_if(ret < 0, "PICO_IP_BLOCK_SOURCE failed\n");
|
||||
ret = pico_socket_setoption(s1, PICO_IP_BLOCK_SOURCE, &mreq_source[2]);
|
||||
fail_if(ret < 0, "PICO_IP_BLOCK_SOURCE failed\n");
|
||||
i = 0;
|
||||
pico_tree_foreach(index, &MCASTFilter)
|
||||
{
|
||||
if (++i > 1)
|
||||
fail("MCASTFilter (INCLUDE + EXCLUDE) too many elements\n");
|
||||
|
||||
source = index->keyValue;
|
||||
if (memcmp(&source->ip6, &mreq_source[2].mcast_source_addr, sizeof(struct pico_ip6)) == 0) { /* OK */
|
||||
}
|
||||
else {
|
||||
fail("MCASTFilter (INCLUDE + EXCLUDE) incorrect\n");
|
||||
}
|
||||
}
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s1, PICO_IP_DROP_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_MEMBERSHIP failed\n");
|
||||
|
||||
/* EXCLUDE + INCLUDE expected filter: source of 0 and 1 */
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_BLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_BLOCK_SOURCE failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_BLOCK_SOURCE, &mreq_source[1]);
|
||||
fail_if(ret < 0, "PICO_IP_BLOCK_SOURCE failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_BLOCK_SOURCE, &mreq_source[3]);
|
||||
fail_if(ret < 0, "PICO_IP_BLOCK_SOURCE failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_BLOCK_SOURCE, &mreq_source[4]);
|
||||
fail_if(ret < 0, "PICO_IP_BLOCK_SOURCE failed\n");
|
||||
ret = pico_socket_setoption(s1, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source[3]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_SOURCE_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s1, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source[4]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_SOURCE_MEMBERSHIP failed\n");
|
||||
i = 0;
|
||||
|
||||
pico_tree_foreach(index, &MCASTFilter)
|
||||
{
|
||||
if (++i > 2)
|
||||
fail("MCASTFilter (EXCLUDE + INCLUDE) too many elements\n");
|
||||
|
||||
source = index->keyValue;
|
||||
if (memcmp(&source->ip6, &mreq_source[0].mcast_source_addr, sizeof(struct pico_ip6)) == 0) { /* OK */
|
||||
}
|
||||
else if (memcmp(&source->ip6, &mreq_source[1].mcast_source_addr, sizeof(struct pico_ip6)) == 0) { /* OK */
|
||||
}
|
||||
else {
|
||||
fail("MCASTFilter (EXCLUDE + INCLUDE) incorrect\n");
|
||||
}
|
||||
}
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s1, PICO_IP_DROP_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_MEMBERSHIP failed\n");
|
||||
|
||||
/* EXCLUDE + EXCLUDE expected filter: source of 3 and 4 */
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_BLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_BLOCK_SOURCE failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_BLOCK_SOURCE, &mreq_source[1]);
|
||||
fail_if(ret < 0, "PICO_IP_BLOCK_SOURCE failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_BLOCK_SOURCE, &mreq_source[3]);
|
||||
fail_if(ret < 0, "PICO_IP_BLOCK_SOURCE failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_BLOCK_SOURCE, &mreq_source[4]);
|
||||
fail_if(ret < 0, "PICO_IP_BLOCK_SOURCE failed\n");
|
||||
ret = pico_socket_setoption(s1, PICO_IP_ADD_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s1, PICO_IP_BLOCK_SOURCE, &mreq_source[3]);
|
||||
fail_if(ret < 0, "PICO_IP_BLOCK_SOURCE failed\n");
|
||||
ret = pico_socket_setoption(s1, PICO_IP_BLOCK_SOURCE, &mreq_source[4]);
|
||||
fail_if(ret < 0, "PICO_IP_BLOCK_SOURCE failed\n");
|
||||
ret = pico_socket_setoption(s1, PICO_IP_BLOCK_SOURCE, &mreq_source[5]);
|
||||
fail_if(ret < 0, "PICO_IP_BLOCK_SOURCE failed\n");
|
||||
ret = pico_socket_setoption(s1, PICO_IP_BLOCK_SOURCE, &mreq_source[6]);
|
||||
fail_if(ret < 0, "PICO_IP_BLOCK_SOURCE failed\n");
|
||||
i = 0;
|
||||
pico_tree_foreach(index, &MCASTFilter)
|
||||
{
|
||||
if (++i > 2)
|
||||
fail("MCASTFilter (EXCLUDE + EXCLUDE) too many elements\n");
|
||||
|
||||
source = index->keyValue;
|
||||
if (memcmp(&source->ip6, &mreq_source[3].mcast_source_addr, sizeof(struct pico_ip6) == 0)) { /* OK */
|
||||
}
|
||||
else if (memcmp(&source->ip6, &mreq_source[4].mcast_source_addr, sizeof(struct pico_ip6)) == 0) { /* OK */
|
||||
}
|
||||
else {
|
||||
fail("MCASTFilter (EXCLUDE + EXCLUDE) incorrect\n");
|
||||
}
|
||||
}
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s1, PICO_IP_DROP_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_MEMBERSHIP failed\n");
|
||||
|
||||
|
||||
ret = pico_socket_close(s);
|
||||
fail_if(ret < 0, "socket close failed: %s\n", strerror(pico_err));
|
||||
ret = pico_socket_close(s1);
|
||||
fail_if(ret < 0, "socket close failed: %s\n", strerror(pico_err));
|
||||
}
|
||||
END_TEST
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
2158
kernel/picotcp/test/unit/unit_mem_manager.c
Normal file
2158
kernel/picotcp/test/unit/unit_mem_manager.c
Normal file
File diff suppressed because it is too large
Load Diff
71
kernel/picotcp/test/unit/unit_mocks.c
Normal file
71
kernel/picotcp/test/unit/unit_mocks.c
Normal file
@@ -0,0 +1,71 @@
|
||||
#define BUFLEN (576 + 14 + 20 + 8)
|
||||
|
||||
int mock_print_protocol(uint8_t *buf);
|
||||
int printbuf(uint8_t *buf, uint32_t len, const char *str, uint8_t printbufactive);
|
||||
int tick_it(uint32_t nticks);
|
||||
|
||||
int mock_print_protocol(uint8_t *buf)
|
||||
{
|
||||
uint8_t pnr = buf[0x17]; /* protocol number */
|
||||
|
||||
printf("transport protocol: %s\n",
|
||||
(pnr == PICO_PROTO_ICMP4 ? "icmp4" :
|
||||
(pnr == PICO_PROTO_IGMP ? "igmp" :
|
||||
(pnr == PICO_PROTO_TCP ? "tcp" :
|
||||
(pnr == PICO_PROTO_UDP ? "udp" :
|
||||
(pnr == PICO_PROTO_ICMP6 ? "icmp6" :
|
||||
"unknown proto"))))));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int printbuf(uint8_t *buf, uint32_t len, const char *str, uint8_t printbufactive)
|
||||
{
|
||||
uint8_t printMethod = 0;
|
||||
uint32_t cntr = 0;
|
||||
uint32_t cntr2 = 0;
|
||||
if((printbufactive) && (printMethod == 0)) {
|
||||
printf("\n%s:\n", str);
|
||||
for(cntr = 0; cntr < len; cntr++) {
|
||||
if((cntr % 8) == 0 && cntr != 0)
|
||||
printf(" ");
|
||||
|
||||
if((cntr % 16) == 0 && cntr != 0)
|
||||
printf("\n");
|
||||
|
||||
if((cntr % 16) == 0)
|
||||
printf("%03x0 ", cntr2++);
|
||||
|
||||
printf("%02x ", buf[cntr]);
|
||||
}
|
||||
printf("\n");
|
||||
}else if((printbufactive) && (printMethod == 1)) {
|
||||
printf("\n%s:\n", str);
|
||||
printf("Buf = {");
|
||||
for(cntr = 0; cntr < len; cntr++) {
|
||||
if(cntr != 0)
|
||||
printf(",");
|
||||
|
||||
if((cntr % 16 == 0) && (cntr != 0))
|
||||
printf("\n");
|
||||
|
||||
printf("0x%02x", buf[cntr]);
|
||||
}
|
||||
printf("}\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define BUFLEN (576 + 14 + 20 + 8)
|
||||
#define DHCP_MSG_TYPE_DISCOVER (1)
|
||||
#define DHCP_MSG_TYPE_OFFER (2)
|
||||
#define DHCP_MSG_TYPE_REQUEST (3)
|
||||
#define DHCP_MSG_TYPE_ACK (4)
|
||||
int tick_it(uint32_t nticks)
|
||||
{
|
||||
uint32_t i = 0;
|
||||
for (i = 0; i < nticks; i++) {
|
||||
pico_stack_tick();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
93
kernel/picotcp/test/unit/unit_rbtree.c
Normal file
93
kernel/picotcp/test/unit/unit_rbtree.c
Normal file
@@ -0,0 +1,93 @@
|
||||
/* RB tree unit test */
|
||||
typedef struct
|
||||
{
|
||||
int value;
|
||||
}elem;
|
||||
|
||||
int compare(void *a, void *b);
|
||||
|
||||
int compare(void *a, void *b)
|
||||
{
|
||||
return ((elem *)a)->value - ((elem *)b)->value;
|
||||
}
|
||||
|
||||
static PICO_TREE_DECLARE(test_tree, compare);
|
||||
static PICO_TREE_DECLARE(test_tree2, compare);
|
||||
#define RBTEST_SIZE 20000
|
||||
|
||||
START_TEST (test_rbtree2)
|
||||
{
|
||||
struct pico_tree_node *s;
|
||||
elem *e;
|
||||
int i, last;
|
||||
struct timeval start, end;
|
||||
gettimeofday(&start, 0);
|
||||
|
||||
srand48(RBTEST_SIZE); /* use test-size as salt */
|
||||
for (i = 0; i < (RBTEST_SIZE >> 1); i++)
|
||||
{
|
||||
e = malloc(sizeof(elem));
|
||||
e->value = (int)lrand48() % RBTEST_SIZE;
|
||||
if (pico_tree_findKey(&test_tree2, e)) {
|
||||
free(e);
|
||||
} else {
|
||||
pico_tree_insert(&test_tree2, e);
|
||||
}
|
||||
}
|
||||
gettimeofday(&end, 0);
|
||||
printf("Rbtree test 2 inserted %d entries in %d milliseconds\n", RBTEST_SIZE,
|
||||
(int)((end.tv_sec - start.tv_sec) * 1000 + (end.tv_usec - start.tv_usec) / 1000));
|
||||
last = 0;
|
||||
pico_tree_foreach(s, &test_tree2){
|
||||
fail_if (last > ((elem *)(s->keyValue))->value, "error");
|
||||
last = ((elem *)(s->keyValue))->value;
|
||||
}
|
||||
|
||||
gettimeofday(&end, 0);
|
||||
printf("Rbtree test 2 duration with %d entries: %d milliseconds\n", RBTEST_SIZE,
|
||||
(int)((end.tv_sec - start.tv_sec) * 1000 + (end.tv_usec - start.tv_usec) / 1000));
|
||||
printf("Test finished.\n");
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST (test_rbtree)
|
||||
{
|
||||
struct pico_tree_node *s, *tmp;
|
||||
elem t, *e;
|
||||
int i;
|
||||
struct timeval start, end;
|
||||
printf("Started test...\n");
|
||||
gettimeofday(&start, 0);
|
||||
|
||||
for (i = 0; i < (RBTEST_SIZE >> 1); i++) {
|
||||
e = malloc(sizeof(elem));
|
||||
e->value = i;
|
||||
pico_tree_insert(&test_tree, e);
|
||||
/* RB_INSERT(rbtree, &RBTREE, e); */
|
||||
e = malloc(sizeof(elem));
|
||||
e->value = (RBTEST_SIZE - 1) - i;
|
||||
pico_tree_insert(&test_tree, e);
|
||||
}
|
||||
i = 0;
|
||||
pico_tree_foreach(s, &test_tree){
|
||||
fail_if (i++ != ((elem *)(s->keyValue))->value, "error");
|
||||
}
|
||||
t.value = RBTEST_SIZE >> 2;
|
||||
|
||||
e = pico_tree_findKey(&test_tree, &t);
|
||||
fail_if(!e, "Search failed...");
|
||||
fail_if(e->value != t.value, "Wrong element returned...");
|
||||
|
||||
pico_tree_foreach_reverse_safe(s, &test_tree, tmp){
|
||||
fail_if(!s, "Reverse safe returned null");
|
||||
e = (elem *)pico_tree_delete(&test_tree, s->keyValue);
|
||||
free(e);
|
||||
}
|
||||
|
||||
fail_if(!pico_tree_empty(&test_tree), "Not empty");
|
||||
gettimeofday(&end, 0);
|
||||
printf("Rbtree test duration with %d entries: %d milliseconds\n", RBTEST_SIZE,
|
||||
(int)((end.tv_sec - start.tv_sec) * 1000 + (end.tv_usec - start.tv_usec) / 1000));
|
||||
printf("Test finished...\n");
|
||||
}
|
||||
END_TEST
|
||||
521
kernel/picotcp/test/unit/unit_socket.c
Normal file
521
kernel/picotcp/test/unit/unit_socket.c
Normal file
@@ -0,0 +1,521 @@
|
||||
|
||||
int pico_aodv_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
START_TEST (test_socket)
|
||||
{
|
||||
int ret = 0;
|
||||
uint16_t port_be = 0, porta, proto, port_got;
|
||||
char buf[] = "test";
|
||||
struct pico_socket *sk_tcp, *sk_udp, *s, *sl, *sa;
|
||||
struct pico_device *dev;
|
||||
struct pico_ip4 inaddr_dst, inaddr_link, inaddr_incorrect, inaddr_uni, inaddr_null, netmask, orig, inaddr_got;
|
||||
|
||||
int getnodelay = -1;
|
||||
int nodelay = -1;
|
||||
int count = 0;
|
||||
|
||||
uint32_t getsocket_buffer = 0;
|
||||
uint32_t socket_buffer = 0;
|
||||
|
||||
pico_stack_init();
|
||||
|
||||
printf("START SOCKET TEST\n");
|
||||
|
||||
pico_string_to_ipv4("224.7.7.7", &inaddr_dst.addr);
|
||||
pico_string_to_ipv4("10.40.0.2", &inaddr_link.addr);
|
||||
pico_string_to_ipv4("224.8.8.8", &inaddr_incorrect.addr);
|
||||
pico_string_to_ipv4("0.0.0.0", &inaddr_null.addr);
|
||||
pico_string_to_ipv4("10.40.0.3", &inaddr_uni.addr);
|
||||
|
||||
dev = pico_null_create("dummy");
|
||||
netmask.addr = long_be(0xFFFF0000);
|
||||
ret = pico_ipv4_link_add(dev, inaddr_link, netmask);
|
||||
fail_if(ret < 0, "socket> error adding link");
|
||||
|
||||
|
||||
/* socket_open passing wrong parameters */
|
||||
s = pico_socket_open(PICO_PROTO_IPV4, 99, NULL);
|
||||
fail_if(s != NULL, "Error got socket wrong parameters");
|
||||
|
||||
s = pico_socket_open(PICO_PROTO_IPV4, 0xFFFF, NULL);
|
||||
fail_if(s != NULL, "Error got socket");
|
||||
|
||||
s = pico_socket_open(99, PICO_PROTO_UDP, NULL);
|
||||
fail_if(s != NULL, "Error got socket");
|
||||
|
||||
s = pico_socket_open(0xFFFF, PICO_PROTO_UDP, NULL);
|
||||
fail_if(s != NULL, "Error got socket");
|
||||
|
||||
|
||||
sk_tcp = pico_socket_open(PICO_PROTO_IPV4, PICO_PROTO_TCP, NULL);
|
||||
fail_if(sk_tcp == NULL, "socket> tcp socket open failed");
|
||||
|
||||
|
||||
port_be = short_be(5555);
|
||||
/* socket_bind passing wrong parameters */
|
||||
ret = pico_socket_bind(NULL, &inaddr_link, &port_be);
|
||||
fail_if(ret == 0, "socket> tcp socket bound wrong parameter");
|
||||
ret = pico_socket_bind(sk_tcp, NULL, &port_be);
|
||||
fail_if(ret == 0, "socket> tcp socket bound wrong parameter");
|
||||
ret = pico_socket_bind(sk_tcp, &inaddr_link, NULL);
|
||||
fail_if(ret == 0, "socket> tcp socket bound wrong parameter");
|
||||
/* socket_getname passing wrong parameters */
|
||||
ret = pico_socket_getname(NULL, &inaddr_link, &port_be, &proto);
|
||||
fail_if(ret == 0, "socket> tcp socket getname with wrong parameter");
|
||||
ret = pico_socket_getname(sk_tcp, NULL, &port_be, &proto);
|
||||
fail_if(ret == 0, "socket> tcp socket getname with wrong parameter");
|
||||
ret = pico_socket_getname(sk_tcp, &inaddr_link, NULL, &proto);
|
||||
fail_if(ret == 0, "socket> tcp socket getname with wrong parameter");
|
||||
ret = pico_socket_getname(sk_tcp, &inaddr_link, &port_be, NULL);
|
||||
fail_if(ret == 0, "socket> tcp socket getname with wrong parameter");
|
||||
/* socket_bind passing correct parameters */
|
||||
ret = pico_socket_bind(sk_tcp, &inaddr_link, &port_be);
|
||||
fail_if(ret < 0, "socket> tcp socket bind failed");
|
||||
count = pico_count_sockets(PICO_PROTO_TCP);
|
||||
printf("Count: %d\n", count);
|
||||
fail_unless(count == 1);
|
||||
count = pico_count_sockets(0);
|
||||
printf("Count: %d\n", count);
|
||||
fail_unless(count == 1);
|
||||
|
||||
sk_udp = pico_socket_open(PICO_PROTO_IPV4, PICO_PROTO_UDP, NULL);
|
||||
fail_if(sk_udp == NULL, "socket> udp socket open failed");
|
||||
|
||||
port_be = short_be(5555);
|
||||
ret = pico_socket_bind(sk_udp, &inaddr_link, &port_be);
|
||||
fail_if(ret < 0, "socket> udp socket bind failed");
|
||||
|
||||
fail_if (pico_count_sockets(PICO_PROTO_UDP) != 1);
|
||||
fail_if (pico_count_sockets(0) != 2);
|
||||
|
||||
|
||||
ret = pico_socket_getname(sk_udp, &inaddr_got, &port_got, &proto);
|
||||
fail_if(ret < 0, "socket> udp socket getname failed");
|
||||
fail_if(inaddr_got.addr != inaddr_link.addr, "Getname: Address is different");
|
||||
fail_if(port_be != port_got, "Getname: Port is different");
|
||||
fail_if(proto != PICO_PROTO_IPV4, "Getname: proto is wrong");
|
||||
|
||||
/* socket_close passing wrong parameter */
|
||||
ret = pico_socket_close(NULL);
|
||||
fail_if(ret == 0, "Error socket close with wrong parameters");
|
||||
|
||||
|
||||
/* socket_connect passing wrong parameters */
|
||||
ret = pico_socket_connect(sk_udp, NULL, port_be);
|
||||
fail_if(ret == 0, "Error socket connect with wrong parameters");
|
||||
ret = pico_socket_connect(NULL, &inaddr_dst, port_be);
|
||||
fail_if(ret == 0, "Error socket connect with wrong parameters");
|
||||
|
||||
/* socket_connect passing correct parameters */
|
||||
ret = pico_socket_connect(sk_udp, &inaddr_dst, port_be);
|
||||
fail_if(ret < 0, "Error socket connect");
|
||||
ret = pico_socket_connect(sk_tcp, &inaddr_dst, port_be);
|
||||
fail_if(ret < 0, "Error socket connect");
|
||||
|
||||
|
||||
/* testing listening socket */
|
||||
sl = pico_socket_open(PICO_PROTO_IPV4, PICO_PROTO_TCP, NULL);
|
||||
fail_if(sl == NULL, "socket> tcp socket open failed");
|
||||
port_be = short_be(6666);
|
||||
ret = pico_socket_bind(sl, &inaddr_link, &port_be);
|
||||
fail_if(ret < 0, "socket> tcp socket bind failed");
|
||||
/* socket_listen passing wrong parameters */
|
||||
ret = pico_socket_listen(sl, 0);
|
||||
fail_if(ret == 0, "Error socket tcp socket listen done, wrong parameter");
|
||||
ret = pico_socket_listen(NULL, 10);
|
||||
fail_if(ret == 0, "Error socket tcp socket listen done, wrong parameter");
|
||||
/* socket_listen passing correct parameters */
|
||||
ret = pico_socket_listen(sl, 10);
|
||||
fail_if(ret < 0, "socket> tcp socket listen failed: %s", strerror(pico_err));
|
||||
|
||||
/* socket_accept passing wrong parameters */
|
||||
sa = pico_socket_accept(sl, &orig, NULL);
|
||||
fail_if(sa != NULL, "Error socket tcp socket accept wrong argument");
|
||||
sa = pico_socket_accept(sl, NULL, &porta);
|
||||
fail_if(sa != NULL, "Error socket tcp socket accept wrong argument");
|
||||
/* socket_accept passing correct parameters */
|
||||
sa = pico_socket_accept(sl, &orig, &porta);
|
||||
fail_if(sa == NULL && pico_err != PICO_ERR_EAGAIN, "socket> tcp socket accept failed: %s", strerror(pico_err));
|
||||
|
||||
ret = pico_socket_close(sl);
|
||||
fail_if(ret < 0, "socket> tcp socket close failed: %s\n", strerror(pico_err));
|
||||
|
||||
|
||||
/* testing socket read/write */
|
||||
/* socket_write passing wrong parameters */
|
||||
ret = pico_socket_write(NULL, (void *)buf, sizeof(buf));
|
||||
fail_if(ret == 0, "Error socket write succeeded, wrong argument\n");
|
||||
ret = pico_socket_write(sk_tcp, NULL, sizeof(buf));
|
||||
fail_if(ret == 0, "Error socket write succeeded, wrong argument\n");
|
||||
ret = pico_socket_write(sk_tcp, (void *)buf, 0);
|
||||
fail_if(ret > 0, "Error socket write succeeded, wrong argument\n");
|
||||
/* socket_write passing correct parameters */
|
||||
ret = pico_socket_write(sk_tcp, (void *)buf, sizeof(buf));
|
||||
fail_if(ret < 0, "socket> tcp socket write failed: %s\n", strerror(pico_err));
|
||||
/* socket_read passing wrong parameters */
|
||||
ret = pico_socket_read(NULL, (void *)buf, sizeof(buf));
|
||||
fail_if(ret == 0, "Error socket read succeeded, wrong argument\n");
|
||||
ret = pico_socket_read(sk_tcp, NULL, sizeof(buf));
|
||||
fail_if(ret == 0, "Error socket read succeeded, wrong argument\n");
|
||||
ret = pico_socket_read(sk_tcp, (void *)buf, 0);
|
||||
fail_if(ret > 0, "Error socket read succeeded, wrong argument\n");
|
||||
/* socket_read passing correct parameters */
|
||||
ret = pico_socket_read(sk_tcp, (void *)buf, sizeof(buf));
|
||||
fail_if(ret < 0, "socket> tcp socket read failed, ret = %d: %s\n", ret, strerror(pico_err)); /* tcp_recv returns 0 when no frame !? */
|
||||
|
||||
|
||||
/* send/recv */
|
||||
/* socket_send passing wrong parameters */
|
||||
ret = pico_socket_send(NULL, (void *)buf, sizeof(buf));
|
||||
fail_if(ret == 0, "Error socket send succeeded, wrong argument\n");
|
||||
ret = pico_socket_send(sk_tcp, NULL, sizeof(buf));
|
||||
fail_if(ret == 0, "Error socket send succeeded, wrong argument\n");
|
||||
ret = pico_socket_send(sk_tcp, (void *)buf, 0);
|
||||
fail_if(ret > 0, "Error socket send succeeded, wrong argument\n");
|
||||
/* socket_write passing correct parameters */
|
||||
ret = pico_socket_send(sk_tcp, (void *)buf, sizeof(buf));
|
||||
fail_if(ret <= 0, "socket> tcp socket send failed: %s\n", strerror(pico_err));
|
||||
/* socket_recv passing wrong parameters */
|
||||
ret = pico_socket_recv(NULL, (void *)buf, sizeof(buf));
|
||||
fail_if(ret == 0, "Error socket recv succeeded, wrong argument\n");
|
||||
ret = pico_socket_recv(sk_tcp, NULL, sizeof(buf));
|
||||
fail_if(ret == 0, "Error socket recv succeeded, wrong argument\n");
|
||||
ret = pico_socket_recv(sk_tcp, (void *)buf, 0);
|
||||
fail_if(ret > 0, "Error socket recv succeeded, wrong argument\n");
|
||||
/* socket_recv passing correct parameters */
|
||||
ret = pico_socket_recv(sk_tcp, (void *)buf, sizeof(buf));
|
||||
fail_if(ret < 0, "socket> tcp socket recv failed, ret = %d: %s\n", ret, strerror(pico_err)); /* tcp_recv returns 0 when no frame !? */
|
||||
|
||||
|
||||
/* sendto/recvfrom */
|
||||
/* socket_sendto passing wrong parameters */
|
||||
ret = pico_socket_sendto(NULL, (void *)buf, sizeof(buf), &inaddr_dst, port_be);
|
||||
fail_if(ret >= 0, "Error socket sendto succeeded, wrong argument\n");
|
||||
ret = pico_socket_sendto(sk_tcp, NULL, sizeof(buf), &inaddr_dst, port_be);
|
||||
fail_if(ret >= 0, "Error socket sendto succeeded, wrong argument\n");
|
||||
ret = pico_socket_sendto(sk_tcp, (void *)buf, 0, &inaddr_dst, port_be);
|
||||
fail_if(ret > 0, "Error socket sendto succeeded, wrong argument\n");
|
||||
ret = pico_socket_sendto(sk_tcp, (void *)buf, sizeof(buf), NULL, port_be);
|
||||
fail_if(ret >= 0, "Error socket sendto succeeded, wrong argument\n");
|
||||
ret = pico_socket_sendto(sk_tcp, (void *)buf, sizeof(buf), &inaddr_dst, 0xFFFF);
|
||||
fail_if(ret >= 0, "Error socket sendto succeeded, wrong argument\n");
|
||||
/* socket_write passing correct parameters */
|
||||
ret = pico_socket_sendto(sk_tcp, (void *)buf, sizeof(buf), &inaddr_dst, short_be(5555));
|
||||
fail_if(ret <= 0, "socket> udp socket sendto failed, ret = %d: %s\n", ret, strerror(pico_err));
|
||||
/* socket_recvfrom passing wrong parameters */
|
||||
ret = pico_socket_recvfrom(NULL, (void *)buf, sizeof(buf), &orig, &porta);
|
||||
fail_if(ret >= 0, "Error socket recvfrom succeeded, wrong argument\n");
|
||||
ret = pico_socket_recvfrom(sk_tcp, NULL, sizeof(buf), &orig, &porta);
|
||||
fail_if(ret >= 0, "Error socket recvfrom succeeded, wrong argument\n");
|
||||
ret = pico_socket_recvfrom(sk_tcp, (void *)buf, 0, &orig, &porta);
|
||||
fail_if(ret > 0, "Error socket recvfrom succeeded, wrong argument\n");
|
||||
ret = pico_socket_recvfrom(sk_tcp, (void *)buf, sizeof(buf), NULL, &porta);
|
||||
fail_if(ret > 0, "Error socket recvfrom succeeded, wrong argument\n");
|
||||
ret = pico_socket_recvfrom(sk_tcp, (void *)buf, sizeof(buf), &orig, NULL);
|
||||
fail_if(ret > 0, "Error socket recvfrom succeeded, wrong argument\n");
|
||||
/* socket_recvfrom passing correct parameters */
|
||||
ret = pico_socket_recvfrom(sk_tcp, (void *)buf, sizeof(buf), &orig, &porta);
|
||||
fail_if(ret != 0, "socket> tcp socket recvfrom failed, ret = %d: %s\n", ret, strerror(pico_err)); /* tcp_recv returns -1 when no frame !? */
|
||||
|
||||
|
||||
/* testing socket read/write */
|
||||
/* socket_write passing wrong parameters */
|
||||
ret = pico_socket_write(NULL, (void *)buf, sizeof(buf));
|
||||
fail_if(ret == 0, "Error socket write succeeded, wrong argument\n");
|
||||
ret = pico_socket_write(sk_udp, NULL, sizeof(buf));
|
||||
fail_if(ret == 0, "Error socket write succeeded, wrong argument\n");
|
||||
ret = pico_socket_write(sk_udp, (void *)buf, 0);
|
||||
fail_if(ret > 0, "Error socket write succeeded, wrong argument\n");
|
||||
/* socket_write passing correct parameters */
|
||||
ret = pico_socket_write(sk_udp, (void *)buf, sizeof(buf));
|
||||
fail_if(ret < 0, "socket> tcp socket write failed: %s\n", strerror(pico_err));
|
||||
/* socket_read passing wrong parameters */
|
||||
ret = pico_socket_read(NULL, (void *)buf, sizeof(buf));
|
||||
fail_if(ret == 0, "Error socket read succeeded, wrong argument\n");
|
||||
ret = pico_socket_read(sk_udp, NULL, sizeof(buf));
|
||||
fail_if(ret == 0, "Error socket read succeeded, wrong argument\n");
|
||||
ret = pico_socket_read(sk_udp, (void *)buf, 0);
|
||||
fail_if(ret > 0, "Error socket read succeeded, wrong argument\n");
|
||||
ret = pico_socket_read(sk_udp, (void *)buf, 0xFFFF + 1);
|
||||
fail_if(ret >= 0, "Error socket read succeeded while len was > 0xFFFF");
|
||||
/* socket_read passing correct parameters */
|
||||
ret = pico_socket_read(sk_udp, (void *)buf, sizeof(buf));
|
||||
fail_if(ret != 0, "socket> udp socket read failed, ret = %d: %s\n", ret, strerror(pico_err));
|
||||
|
||||
|
||||
/* send/recv */
|
||||
/* socket_send passing wrong parameters */
|
||||
ret = pico_socket_send(NULL, (void *)buf, sizeof(buf));
|
||||
fail_if(ret == 0, "Error socket send succeeded, wrong argument\n");
|
||||
ret = pico_socket_send(sk_udp, NULL, sizeof(buf));
|
||||
fail_if(ret == 0, "Error socket send succeeded, wrong argument\n");
|
||||
ret = pico_socket_send(sk_udp, (void *)buf, 0);
|
||||
fail_if(ret > 0, "Error socket send succeeded, wrong argument\n");
|
||||
/* socket_write passing correct parameters */
|
||||
ret = pico_socket_send(sk_udp, (void *)buf, sizeof(buf));
|
||||
fail_if(ret <= 0, "socket> tcp socket send failed: %s\n", strerror(pico_err));
|
||||
/* socket_recv passing wrong parameters */
|
||||
ret = pico_socket_recv(NULL, (void *)buf, sizeof(buf));
|
||||
fail_if(ret == 0, "Error socket recv succeeded, wrong argument\n");
|
||||
ret = pico_socket_recv(sk_udp, NULL, sizeof(buf));
|
||||
fail_if(ret == 0, "Error socket recv succeeded, wrong argument\n");
|
||||
ret = pico_socket_recv(sk_udp, (void *)buf, 0);
|
||||
fail_if(ret > 0, "Error socket recv succeeded, wrong argument\n");
|
||||
ret = pico_socket_recv(sk_udp, (void *)buf, 0xFFFF + 1);
|
||||
fail_if(ret >= 0, "Error socket recv succeeded while len was > 0xFFFF");
|
||||
/* socket_recv passing correct parameters */
|
||||
ret = pico_socket_recv(sk_udp, (void *)buf, sizeof(buf));
|
||||
fail_if(ret != 0, "socket> udp socket recv failed, ret = %d: %s\n", ret, strerror(pico_err));
|
||||
|
||||
|
||||
/* sendto/recvfrom */
|
||||
/* socket_sendto passing wrong parameters */
|
||||
ret = pico_socket_sendto(NULL, (void *)buf, sizeof(buf), &inaddr_dst, port_be);
|
||||
fail_if(ret >= 0, "Error socket sendto succeeded, wrong argument\n");
|
||||
ret = pico_socket_sendto(sk_udp, NULL, sizeof(buf), &inaddr_dst, port_be);
|
||||
fail_if(ret >= 0, "Error socket sendto succeeded, wrong argument\n");
|
||||
ret = pico_socket_sendto(sk_udp, (void *)buf, 0, &inaddr_dst, port_be);
|
||||
fail_if(ret > 0, "Error socket sendto succeeded, wrong argument\n");
|
||||
ret = pico_socket_sendto(sk_udp, (void *)buf, sizeof(buf), NULL, port_be);
|
||||
fail_if(ret >= 0, "Error socket sendto succeeded, wrong argument\n");
|
||||
ret = pico_socket_sendto(sk_udp, (void *)buf, sizeof(buf), &inaddr_dst, 0xFFFF);
|
||||
fail_if(ret >= 0, "Error socket sendto succeeded, wrong argument\n");
|
||||
/* socket_write passing correct parameters */
|
||||
ret = pico_socket_sendto(sk_udp, (void *)buf, sizeof(buf), &inaddr_dst, short_be(5555));
|
||||
fail_if(ret <= 0, "socket> udp socket sendto failed, ret = %d: %s\n", ret, strerror(pico_err));
|
||||
/* socket_recvfrom passing wrong parameters */
|
||||
ret = pico_socket_recvfrom(NULL, (void *)buf, sizeof(buf), &orig, &porta);
|
||||
fail_if(ret >= 0, "Error socket recvfrom succeeded, wrong argument\n");
|
||||
ret = pico_socket_recvfrom(sk_udp, NULL, sizeof(buf), &orig, &porta);
|
||||
fail_if(ret >= 0, "Error socket recvfrom succeeded, wrong argument\n");
|
||||
ret = pico_socket_recvfrom(sk_udp, (void *)buf, 0xFFFF + 1, &orig, &porta);
|
||||
fail_if(ret >= 0, "Error socket recvfrom succeeded while len was > 0xFFFF");
|
||||
/* socket_recvfrom passing correct parameters */
|
||||
ret = pico_socket_recvfrom(sk_udp, (void *)buf, 0, &orig, &porta);
|
||||
fail_if(ret != 0, "socket> udp socket recvfrom failed, ret = %d: %s\n", ret, strerror(pico_err));
|
||||
ret = pico_socket_recvfrom(sk_udp, (void *)buf, sizeof(buf), &orig, &porta);
|
||||
fail_if(ret != 0, "socket> udp socket recvfrom failed, ret = %d: %s\n", ret, strerror(pico_err));
|
||||
|
||||
/* temporary fix, until Nagle problems are analyzed and fixed */
|
||||
{
|
||||
nodelay = 0;
|
||||
ret = pico_socket_setoption(sk_tcp, PICO_TCP_NODELAY, &nodelay);
|
||||
}
|
||||
|
||||
/* setoption/getoption */
|
||||
ret = pico_socket_getoption(sk_tcp, PICO_TCP_NODELAY, &getnodelay);
|
||||
fail_if(ret < 0, "socket> socket_getoption: supported PICO_TCP_NODELAY failed (err = %s)\n", strerror(pico_err));
|
||||
fail_if(getnodelay != 0, "socket> socket_setoption: default PICO_TCP_NODELAY != 0 (nagle disabled by default)\n");
|
||||
|
||||
nodelay = 1;
|
||||
ret = pico_socket_setoption(sk_tcp, PICO_TCP_NODELAY, &nodelay);
|
||||
fail_if(ret < 0, "socket> socket_setoption: supported PICO_TCP_NODELAY failed\n");
|
||||
ret = pico_socket_getoption(sk_tcp, PICO_TCP_NODELAY, &getnodelay);
|
||||
fail_if(ret < 0, "socket> socket_getoption: supported PICO_TCP_NODELAY failed\n");
|
||||
fail_if(getnodelay == 0, "socket> socket_setoption: PICO_TCP_NODELAY is off (expected: on!)\n");
|
||||
|
||||
nodelay = 0;
|
||||
ret = pico_socket_setoption(sk_tcp, PICO_TCP_NODELAY, &nodelay);
|
||||
fail_if(ret < 0, "socket> socket_setoption: supported PICO_TCP_NODELAY failed\n");
|
||||
ret = pico_socket_getoption(sk_tcp, PICO_TCP_NODELAY, &getnodelay);
|
||||
fail_if(ret < 0, "socket> socket_getoption: supported PICO_TCP_NODELAY failed\n");
|
||||
fail_if(getnodelay != 0, "socket> socket_setoption: PICO_TCP_NODELAY is on (expected: off!)\n");
|
||||
|
||||
|
||||
/* Set/get recv buffer (TCP) */
|
||||
ret = pico_socket_getoption(sk_tcp, PICO_SOCKET_OPT_RCVBUF, &getsocket_buffer);
|
||||
fail_if(ret < 0, "socket> socket_getoption: supported PICO_SOCKET_OPT_RCVBUF failed\n");
|
||||
fail_if(getsocket_buffer != PICO_DEFAULT_SOCKETQ,
|
||||
"socket> socket_setoption: default PICO_SOCKET_OPT_SNDBUF != DEFAULT\n");
|
||||
|
||||
socket_buffer = PICO_DEFAULT_SOCKETQ;
|
||||
ret = pico_socket_setoption(sk_tcp, PICO_SOCKET_OPT_RCVBUF, &socket_buffer);
|
||||
fail_if(ret < 0, "socket> socket_setoption: supported PICO_SOCKET_OPT_RCVBUF failed\n");
|
||||
ret = pico_socket_getoption(sk_tcp, PICO_SOCKET_OPT_RCVBUF, &getsocket_buffer);
|
||||
fail_if(ret < 0, "socket> socket_getoption: supported PICO_SOCKET_OPT_RCVBUF failed\n");
|
||||
fail_if(getsocket_buffer != socket_buffer, "UDP socket> socket_setoption: PICO_SOCKET_OPT_RCVBUF is != than expected\n");
|
||||
|
||||
socket_buffer = 2 * PICO_DEFAULT_SOCKETQ;
|
||||
ret = pico_socket_setoption(sk_tcp, PICO_SOCKET_OPT_RCVBUF, &socket_buffer);
|
||||
fail_if(ret < 0, "socket> socket_setoption: supported PICO_SOCKET_OPT_RCVBUF failed\n");
|
||||
ret = pico_socket_getoption(sk_tcp, PICO_SOCKET_OPT_RCVBUF, &getsocket_buffer);
|
||||
fail_if(ret < 0, "socket> socket_getoption: supported PICO_SOCKET_OPT_RCVBUF failed\n");
|
||||
fail_if(getsocket_buffer != socket_buffer, "UDP socket> socket_setoption: PICO_SOCKET_OPT_RCVBUF is != than expected\n");
|
||||
|
||||
/* Set/get send buffer (TCP) */
|
||||
ret = pico_socket_getoption(sk_tcp, PICO_SOCKET_OPT_SNDBUF, &getsocket_buffer);
|
||||
fail_if(ret < 0, "socket> socket_getoption: supported PICO_SOCKET_OPT_SNDBUF failed\n");
|
||||
fail_if(getsocket_buffer != PICO_DEFAULT_SOCKETQ,
|
||||
"socket> socket_setoption: default PICO_SOCKET_OPT_SNDBUF != DEFAULT got: %d exp: %d\n", getsocket_buffer, PICO_DEFAULT_SOCKETQ);
|
||||
|
||||
socket_buffer = PICO_DEFAULT_SOCKETQ;
|
||||
ret = pico_socket_setoption(sk_tcp, PICO_SOCKET_OPT_SNDBUF, &socket_buffer);
|
||||
fail_if(ret < 0, "socket> socket_setoption: supported PICO_SOCKET_OPT_SNDBUF failed\n");
|
||||
ret = pico_socket_getoption(sk_tcp, PICO_SOCKET_OPT_SNDBUF, &getsocket_buffer);
|
||||
fail_if(ret < 0, "socket> socket_getoption: supported PICO_SOCKET_OPT_SNDBUF failed\n");
|
||||
fail_if(getsocket_buffer != socket_buffer, "UDP socket> socket_setoption: PICO_SOCKET_OPT_SNDBUF is != than expected\n");
|
||||
|
||||
socket_buffer = 2 * PICO_DEFAULT_SOCKETQ;
|
||||
ret = pico_socket_setoption(sk_tcp, PICO_SOCKET_OPT_SNDBUF, &socket_buffer);
|
||||
fail_if(ret < 0, "socket> socket_setoption: supported PICO_SOCKET_OPT_SNDBUF failed\n");
|
||||
ret = pico_socket_getoption(sk_tcp, PICO_SOCKET_OPT_SNDBUF, &getsocket_buffer);
|
||||
fail_if(ret < 0, "socket> socket_getoption: supported PICO_SOCKET_OPT_SNDBUF failed\n");
|
||||
fail_if(getsocket_buffer != socket_buffer, "UDP socket> socket_setoption: PICO_SOCKET_OPT_SNDBUF is != than expected\n");
|
||||
|
||||
/* Set/get recv buffer (UDP) */
|
||||
ret = pico_socket_getoption(sk_udp, PICO_SOCKET_OPT_RCVBUF, &getsocket_buffer);
|
||||
fail_if(ret < 0, "socket> socket_getoption: supported PICO_SOCKET_OPT_RCVBUF failed\n");
|
||||
fail_if(getsocket_buffer != PICO_DEFAULT_SOCKETQ,
|
||||
"socket> socket_setoption: default PICO_SOCKET_OPT_SNDBUF != DEFAULT\n");
|
||||
|
||||
socket_buffer = PICO_DEFAULT_SOCKETQ;
|
||||
ret = pico_socket_setoption(sk_udp, PICO_SOCKET_OPT_RCVBUF, &socket_buffer);
|
||||
fail_if(ret < 0, "socket> socket_setoption: supported PICO_SOCKET_OPT_RCVBUF failed\n");
|
||||
ret = pico_socket_getoption(sk_udp, PICO_SOCKET_OPT_RCVBUF, &getsocket_buffer);
|
||||
fail_if(ret < 0, "socket> socket_getoption: supported PICO_SOCKET_OPT_RCVBUF failed\n");
|
||||
fail_if(getsocket_buffer != socket_buffer, "UDP socket> socket_setoption: PICO_SOCKET_OPT_RCVBUF is != than expected\n");
|
||||
|
||||
socket_buffer = 2 * PICO_DEFAULT_SOCKETQ;
|
||||
ret = pico_socket_setoption(sk_udp, PICO_SOCKET_OPT_RCVBUF, &socket_buffer);
|
||||
fail_if(ret < 0, "socket> socket_setoption: supported PICO_SOCKET_OPT_RCVBUF failed\n");
|
||||
ret = pico_socket_getoption(sk_udp, PICO_SOCKET_OPT_RCVBUF, &getsocket_buffer);
|
||||
fail_if(ret < 0, "socket> socket_getoption: supported PICO_SOCKET_OPT_RCVBUF failed\n");
|
||||
fail_if(getsocket_buffer != socket_buffer, "UDP socket> socket_setoption: PICO_SOCKET_OPT_RCVBUF is != than expected\n");
|
||||
|
||||
/* Set/get send buffer (UDP) */
|
||||
ret = pico_socket_getoption(sk_udp, PICO_SOCKET_OPT_SNDBUF, &getsocket_buffer);
|
||||
fail_if(ret < 0, "socket> socket_getoption: supported PICO_SOCKET_OPT_SNDBUF failed\n");
|
||||
fail_if(getsocket_buffer != PICO_DEFAULT_SOCKETQ,
|
||||
"socket> socket_setoption: default PICO_SOCKET_OPT_SNDBUF != DEFAULT\n");
|
||||
|
||||
socket_buffer = PICO_DEFAULT_SOCKETQ;
|
||||
ret = pico_socket_setoption(sk_udp, PICO_SOCKET_OPT_SNDBUF, &socket_buffer);
|
||||
fail_if(ret < 0, "socket> socket_setoption: supported PICO_SOCKET_OPT_SNDBUF failed\n");
|
||||
ret = pico_socket_getoption(sk_udp, PICO_SOCKET_OPT_SNDBUF, &getsocket_buffer);
|
||||
fail_if(ret < 0, "socket> socket_getoption: supported PICO_SOCKET_OPT_SNDBUF failed\n");
|
||||
fail_if(getsocket_buffer != socket_buffer, "UDP socket> socket_setoption: PICO_SOCKET_OPT_SNDBUF is != than expected\n");
|
||||
|
||||
socket_buffer = 2 * PICO_DEFAULT_SOCKETQ;
|
||||
ret = pico_socket_setoption(sk_udp, PICO_SOCKET_OPT_SNDBUF, &socket_buffer);
|
||||
fail_if(ret < 0, "socket> socket_setoption: supported PICO_SOCKET_OPT_SNDBUF failed\n");
|
||||
ret = pico_socket_getoption(sk_udp, PICO_SOCKET_OPT_SNDBUF, &getsocket_buffer);
|
||||
fail_if(ret < 0, "socket> socket_getoption: supported PICO_SOCKET_OPT_SNDBUF failed\n");
|
||||
fail_if(getsocket_buffer != socket_buffer, "UDP socket> socket_setoption: PICO_SOCKET_OPT_SNDBUF is != than expected\n");
|
||||
|
||||
/* Close sockets, eventually. */
|
||||
ret = pico_socket_close(sk_tcp);
|
||||
fail_if(ret < 0, "socket> tcp socket close failed: %s\n", strerror(pico_err));
|
||||
ret = pico_socket_close(sk_udp);
|
||||
fail_if(ret < 0, "socket> udp socket close failed: %s\n", strerror(pico_err));
|
||||
}
|
||||
END_TEST
|
||||
|
||||
#ifdef PICO_SUPPORT_CRC_FAULTY_UNIT_TEST
|
||||
START_TEST (test_crc_check)
|
||||
{
|
||||
uint8_t buffer[64] = {
|
||||
0x45, 0x00, 0x00, 0x40, /* start of IP hdr */
|
||||
0x91, 0xc3, 0x40, 0x00,
|
||||
0x40, 0x11, 0x24, 0xcf, /* last 2 bytes are CRC */
|
||||
0xc0, 0xa8, 0x01, 0x66,
|
||||
0xc0, 0xa8, 0x01, 0x64, /* end of IP hdr */
|
||||
0x15, 0xb3, 0x1F, 0x90, /* start of UDP/TCP hdr */
|
||||
0x00, 0x2c, 0x27, 0x22, /* end of UDP hdr */
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x0b, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, /* end of TCP hdr */
|
||||
0x01, 0x23, 0x45, 0x67, /* start of data */
|
||||
0x89, 0xab, 0xcd, 0xef,
|
||||
0xc0, 0xca, 0xc0, 0x1a
|
||||
};
|
||||
struct pico_frame *f = NULL;
|
||||
struct pico_ipv4_hdr *hdr = (struct pico_ipv4_hdr *) buffer;
|
||||
struct pico_udp_hdr *udp_hdr = NULL;
|
||||
struct pico_tcp_hdr *tcp_hdr = NULL;
|
||||
uint32_t *f_usage_count = NULL;
|
||||
uint8_t *f_buffer = NULL;
|
||||
int ret = -1;
|
||||
|
||||
printf("START CRC TEST\n");
|
||||
pico_stack_init();
|
||||
|
||||
/* IPv4 CRC unit tests */
|
||||
/* Allocated memory will not be freed when pico_ipv4_crc_check fails */
|
||||
f = calloc(1, sizeof(struct pico_frame));
|
||||
f_usage_count = calloc(1, sizeof(uint32_t));
|
||||
f_buffer = calloc(1, sizeof(uint8_t));
|
||||
f->net_hdr = buffer;
|
||||
f->net_len = PICO_SIZE_IP4HDR;
|
||||
f->transport_hdr = buffer + PICO_SIZE_IP4HDR;
|
||||
f->transport_len = sizeof(buffer) - PICO_SIZE_IP4HDR;
|
||||
f->usage_count = f_usage_count;
|
||||
f->buffer = f_buffer;
|
||||
*(f->usage_count) = 512;
|
||||
|
||||
hdr->crc = 0;
|
||||
printf(">>>>>>>>>>>>>>>>>>>>> CRC VALUE = %X\n", pico_checksum(hdr, PICO_SIZE_IP4HDR));
|
||||
hdr->crc = short_be(0x24CF); /* Make check pass */
|
||||
ret = pico_ipv4_crc_check(f);
|
||||
fail_if(ret == 0, "correct IPv4 checksum got rejected\n");
|
||||
hdr->crc = short_be(0x8899); /* Make check fail */
|
||||
ret = pico_ipv4_crc_check(f);
|
||||
fail_if(ret == 1, "incorrect IPv4 checksum got accepted\n");
|
||||
|
||||
/* UDP CRC unit tests */
|
||||
/* Allocated memory will be freed when pico_transport_crc_check fails */
|
||||
f = calloc(1, sizeof(struct pico_frame));
|
||||
f_usage_count = calloc(1, sizeof(uint32_t));
|
||||
f_buffer = calloc(1, sizeof(uint8_t));
|
||||
f->net_hdr = buffer;
|
||||
f->transport_hdr = buffer + PICO_SIZE_IP4HDR;
|
||||
f->transport_len = sizeof(buffer) - PICO_SIZE_IP4HDR;
|
||||
f->usage_count = f_usage_count;
|
||||
f->buffer = f_buffer;
|
||||
*(f->usage_count) = 1;
|
||||
hdr->proto = 0x11; /* UDP */
|
||||
hdr->crc = short_be(0x24cf); /* Set IPv4 CRC correct */
|
||||
udp_hdr = (struct pico_udp_hdr *) f->transport_hdr;
|
||||
|
||||
/* udp_hdr->crc = 0; */
|
||||
/* printf(">>>>>>>>>>>>>>>>>>>>> UDP CRC VALUE = %X\n", pico_udp_checksum_ipv4(f)); */
|
||||
ret = pico_transport_crc_check(f);
|
||||
fail_if(ret == 0, "correct UDP checksum got rejected\n");
|
||||
udp_hdr->crc = 0;
|
||||
ret = pico_transport_crc_check(f);
|
||||
fail_if(ret == 0, "UDP checksum of 0 did not get ignored\n");
|
||||
udp_hdr->crc = short_be(0x8899); /* Make check fail */
|
||||
ret = pico_transport_crc_check(f);
|
||||
fail_if(ret == 1, "incorrect UDP checksum got accepted\n");
|
||||
|
||||
/* TCP CRC unit tests */
|
||||
/* Allocated memory will be freed when pico_transport_crc_check fails */
|
||||
f = calloc(1, sizeof(struct pico_frame));
|
||||
f_usage_count = calloc(1, sizeof(uint32_t));
|
||||
f_buffer = calloc(1, sizeof(uint8_t));
|
||||
f->net_hdr = buffer;
|
||||
f->transport_hdr = buffer + PICO_SIZE_IP4HDR;
|
||||
f->transport_len = sizeof(buffer) - PICO_SIZE_IP4HDR;
|
||||
f->usage_count = f_usage_count;
|
||||
f->buffer = f_buffer;
|
||||
*(f->usage_count) = 1;
|
||||
hdr->proto = 0x06; /* TCP */
|
||||
hdr->crc = short_be(0x24cf); /* Set IPv4 CRC correct */
|
||||
tcp_hdr = (struct pico_tcp_hdr *) f->transport_hdr;
|
||||
tcp_hdr->seq = long_be(0x002c2722); /* Set sequence number correct */
|
||||
|
||||
/* tcp_hdr = 0; */
|
||||
/* printf(">>>>>>>>>>>>>>>>>>>>> TCP CRC VALUE = %X\n", pico_tcp_checksum_ipv4(f)); */
|
||||
tcp_hdr->crc = short_be(0x0016); /* Set correct TCP CRC */
|
||||
ret = pico_transport_crc_check(f);
|
||||
fail_if(ret == 0, "correct TCP checksum got rejected\n");
|
||||
tcp_hdr->crc = short_be(0x8899); /* Make check fail */
|
||||
ret = pico_transport_crc_check(f);
|
||||
fail_if(ret == 1, "incorrect TCP checksum got accepted\n");
|
||||
}
|
||||
END_TEST
|
||||
#endif
|
||||
40
kernel/picotcp/test/unit/unit_timer.c
Normal file
40
kernel/picotcp/test/unit/unit_timer.c
Normal file
@@ -0,0 +1,40 @@
|
||||
#define EXISTING_TIMERS 7
|
||||
|
||||
|
||||
START_TEST (test_timers)
|
||||
{
|
||||
uint32_t T[128];
|
||||
int i;
|
||||
struct pico_timer_ref *tref;
|
||||
pico_stack_init();
|
||||
for (i = 0; i < 128; i++) {
|
||||
pico_time expire = (pico_time)(999999 + i);
|
||||
void (*timer)(pico_time, void *) =(void (*)(pico_time, void *))0xff00 + i;
|
||||
void *arg = ((void*)0xaa00 + i);
|
||||
|
||||
T[i] = pico_timer_add(expire, timer, arg);
|
||||
printf("New timer %u\n", T[i]);
|
||||
}
|
||||
for (i = 0; i < 128; i++) {
|
||||
void (*timer)(pico_time, void *) =(void (*)(pico_time, void *))0xff00 + i;
|
||||
void *arg = ((void*)0xaa00 + i);
|
||||
|
||||
fail_if((uint32_t)(i + 1) > Timers->n);
|
||||
tref = heap_get_element(Timers, (uint32_t)i + EXISTING_TIMERS);
|
||||
fail_unless(tref->id == T[i]);
|
||||
fail_unless(tref->tmr->timer == timer);
|
||||
fail_unless(tref->tmr->arg == arg);
|
||||
}
|
||||
for (i = 127; i >= 0; i--) {
|
||||
printf("Deleting timer %d \n", i );
|
||||
pico_timer_cancel(T[i]);
|
||||
printf("Deleted timer %d \n", i );
|
||||
tref = heap_get_element(Timers, (uint32_t)i + EXISTING_TIMERS);
|
||||
fail_unless(tref->tmr == NULL);
|
||||
}
|
||||
pico_stack_tick();
|
||||
pico_stack_tick();
|
||||
pico_stack_tick();
|
||||
pico_stack_tick();
|
||||
}
|
||||
END_TEST
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user