Pokusím se rozchodit Pico s ethernetovou kartou od firmy WIZnet W6100-EBV-Pico. TCP/IP stack je řešen hardwarově v čipu W6100, měl by umět TCP, UDP, IPv6, IPv4, ICMPv6, ICMPv4, IGMP, MLDv1, ARP, PPPoE. Dokumentace k modulu je zde, příklady pro bare-metal programování na githubu: RP2040 & W6x00 Ethernet Examples a příklady k integraci s FreeRTOS na githubu: RP2040 & W6x00 FreeRTOS Examples Ethernet umí 10Mbit/s a 100Mbit/s, což na spoustu aplikací bohatě stačí. Zařízení lze používat jako obyčejné Pico s tím, že můžeme navíc dělat síťařinu, což je vždycky poměrně dobrá zábava.
Zapojení pinů
Nebudeme moci používat piny GP16 až GP21 protože je na ně připojena ethernetová karta.

Zařízení musí být napájeno 5V.

Je vidět, že většina síťových věcí je hardwarově "zadrátována" přímo v čipu W6100. To má jednu výhodu a jednu nevýhodu. Výhoda je v tom, že se sítařinou na nejnižší úrovni nemusí zabývat hlavní procesor RP2040 a nevýhoda je v tom, že to nelze moc dobře aktualizovat. Například čipy WIZnet starší řady W5xxx neumí IPv6 protokol. Jsme závislí na výrobci, zda udělá nový firmware. V případě nalezení chyby je také velmi nesnadné to spravit a při závažné chybě se třeba bude muset celé zařízení prostě vyhodit.
Knihovna io6Library
K zařízení je dodávána C knihovna io6Library, pomocí které můžeme celkem snadno (pokud se tu knihovnu dostatečně naučíme) programovat síťové aplikace.
Poměrně rozsáhlou a podrobnou dokumentaci najdete zde: Dokumentace v html generovaná Doxygenem, to samé v v PDF. Dokumentaci jsem musel vygenerovat znova doxygenem a pdflatexem, protože dodávaná dokumentace je jenom ve formátu chm.
Program autokonfigurace IP adres — dodávaný příklad
Program w6x00_AAC se skládá ze souborů w6x00_AAC.c, AddressAutoConfig.c a AddressAutoConfig.h a
je příkladem síťové konfigurace zařízení a jednoduchých echo nebo loopback serverů a klientů pro různé protokoly (IPv4, IPv6, TCP a UDP).
Stažení programového vybavení provedeme obvyklým způsobem
$ cd ~/pico
$ git clone --recurse-submodules https://github.com/Wiznet/RP2040-v6-HAT-C.git
$ cd RP2040-v6-HAT-C
$ mkdir build && cd build (1)
$ cmake ..
$ make -j4 (2)
| 1 | Vytvořím si adresář build a v něm budu dělat veškerý překlad, abych to nematlal mezi zdrojové kódy. |
| 2 | Je tam drobná chyba. Překladač nemůže najít při překladu souboru RP2040-v6-HAT-C/libraries/io6Library/Internet/DHCP6/dhcpv6.h hlavičkový soubor W6100.h.
Opraven překlep: #include "W6100.h" opraveno na #include "w6100.h" a už to funguje. |
Nahrání programu provedeme takto:
-
stiskneme a podržíme tlačítka BOOTSEL (tlačítko je blíže USB konektoru)
-
připojíme mini USB kabel
-
zařízení se nám přihlásí podobně jako normální Pico

$ cd examples/AddressAutoConfiguration/
$ ls -l
celkem 2132
drwxrwxr-x 3 jirka jirka 4096 bře 5 20:30 CMakeFiles
-rw-rw-r-- 1 jirka jirka 1023 bře 5 20:30 cmake_install.cmake
-rw-rw-r-- 1 jirka jirka 163577 bře 5 20:30 Makefile
-rwxrwxr-x 1 jirka jirka 68016 bře 5 20:35 w6x00_AAC.bin
-rw-rw-r-- 1 jirka jirka 1162877 bře 5 20:35 w6x00_AAC.dis
-rwxrwxr-x 1 jirka jirka 137316 bře 5 20:35 w6x00_AAC.elf
-rw-rw-r-- 1 jirka jirka 306384 bře 5 20:35 w6x00_AAC.elf.map
-rw-rw-r-- 1 jirka jirka 191376 bře 5 20:35 w6x00_AAC.hex
-rw-rw-r-- 1 jirka jirka 136192 bře 5 20:35 w6x00_AAC.uf2 (1)
$ cp w6x00_AAC.uf2 /media/jirka/RPI-PI2 (2)
| 1 | Tohle je přeložený program. |
| 2 | Ještě mi vedle běží jiné Pico s testem RNG generátoru, proto se zařízení jmenuje RPI-PI2. |
Překládaný program je poměrně dlouhý, ale zkusím ho okomentovat.
/**
* Copyright (c) 2021 WIZnet Co.,Ltd
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/**
* ----------------------------------------------------------------------------------------------------
* Includes
* ----------------------------------------------------------------------------------------------------
*/
#include <stdio.h>
#include "port_common.h"
#include "wizchip_conf.h"
#include "w6x00_spi.h"
#include "loopback.h"
#include "AddressAutoConfig.h"
#include "dhcpv4.h"
#include "timer.h"
#include "dns.h"
/**
* ----------------------------------------------------------------------------------------------------
* Macros
* ----------------------------------------------------------------------------------------------------
*/
/* Clock */
#define PLL_SYS_KHZ (133 * 1000) // na tohle nebudeme evidentně šahat
/* Buffer */
#define ETHERNET_BUF_MAX_SIZE (1024 * 2)
/* Socket */
#define SOCKET_TCP_SERVER 0
#define SOCKET_TCP_CLIENT 1
#define SOCKET_UDP 2
#define SOCKET_TCP_SERVER6 3
#define SOCKET_TCP_CLIENT6 4
#define SOCKET_UDP6 5
#define SOCKET_DHCP 6
#define SOCKET_DNS 7
/* Port */
#define PORT_TCP_SERVER 5000
#define PORT_TCP_CLIENT 5001
#define PORT_TCP_CLIENT_DEST 5002
#define PORT_UDP 5003
#define PORT_TCP_SERVER6 5004
#define PORT_TCP_CLIENT6 5005
#define PORT_TCP_CLIENT6_DEST 5006
#define PORT_UDP6 5007
#define IPV4 // pokud chceme používat IP verze 4
#define IPV6 // pokud chceme používat IP verze 6
#ifdef IPV4
#define TCP_SERVER
#define TCP_CLIENT
#define UDP
#define DHCP_RETRY_COUNT 5
#define DHCP4
#define DNS
#endif
#ifdef IPV6
#define TCP_SERVER6
#define TCP_CLIENT6
#define UDP6
#define ADDRS_AUTO_CONFIG
#endif
#define DNS_RETRY_COUNT 5
/**
* ----------------------------------------------------------------------------------------------------
* Variables
* ----------------------------------------------------------------------------------------------------
*/
/* Network */ // konfigurace síťové karty a protokolů
static wiz_NetInfo g_net_info =
{
.mac = {0x00, 0x08, 0xDC, 0x12, 0x34, 0x56}, // MAC address
.ip = {192, 168, 11, 2}, // IP address
.sn = {255, 255, 255, 0}, // Subnet Mask
.gw = {192, 168, 11, 1}, // Gateway
.dns = {8, 8, 8, 8}, // DNS server
.lla = {0xfe, 0x80, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x02, 0x08, 0xdc, 0xff,
0xfe, 0x57, 0x57, 0x25}, // Link Local Address
.gua = {0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00}, // Global Unicast Address
.sn6 = {0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00}, // IPv6 Prefix
.gw6 = {0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00}, // Gateway IPv6 Address
.dns6 = {0x20, 0x01, 0x48, 0x60,
0x48, 0x60, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x88, 0x88}, // DNS6 server
.ipmode = 0
};
uint8_t tcp_client_destip[] = {
192, 168, 50, 103
};
uint8_t tcp_client_destip6[] = {
0x20, 0x01, 0x02, 0xb8,
0x00, 0x10, 0xff, 0xff,
0x71, 0x48, 0xcb, 0x27,
0x36, 0xb9, 0x99, 0x2e
};
uint16_t tcp_client_destport = PORT_TCP_CLIENT_DEST;
uint16_t tcp_client_destport6 = PORT_TCP_CLIENT6_DEST;
static uint8_t g_ethernet_buf[ETHERNET_BUF_MAX_SIZE] = {
0,
}; // common buffer
/* Loopback */
static uint8_t g_tcp_server_buf[ETHERNET_BUF_MAX_SIZE] = {
0,
};
static uint8_t g_tcp_client_buf[ETHERNET_BUF_MAX_SIZE] = {
0,
};
static uint8_t g_udp_buf[ETHERNET_BUF_MAX_SIZE] = {
0,
};
static uint8_t g_tcp_server6_buf[ETHERNET_BUF_MAX_SIZE] = {
0,
};
static uint8_t g_tcp_client6_buf[ETHERNET_BUF_MAX_SIZE] = {
0,
};
static uint8_t g_udp6_buf[ETHERNET_BUF_MAX_SIZE] = {
0,
};
/* DHCP */
static uint8_t g_dhcp_get_ip_flag = 0;
/* DNS */
static uint8_t g_dns_target_domain[] = "www.wiznet.io";
static uint8_t g_dns_target_ip[4] = {
0,
};
static uint8_t g_dns6_target_domain[] = "www.google.com";
static uint8_t g_dns6_target_ip[16] = {
0,
};
static uint8_t g_dns_get_ip_flag = 0;
uint8_t IP_TYPE;
/* Timer */
static volatile uint16_t g_msec_cnt = 0;
/**
* ----------------------------------------------------------------------------------------------------
* Functions
* ----------------------------------------------------------------------------------------------------
*/
/* Clock */
static void set_clock_khz(void);
/* DHCP */
static void wizchip_dhcp4_init(void);
static void wizchip_dhcp4_assign(void);
static void wizchip_dhcp4_conflict(void);
/* Timer */
static void repeating_timer_callback(void);
/**
* ----------------------------------------------------------------------------------------------------
* Main
* ----------------------------------------------------------------------------------------------------
*/
int main()
{
/* Initialize */
int retval = 0;
uint8_t dhcp_retry = 0;
uint8_t dns_retry = 0;
set_clock_khz();
stdio_init_all();
sleep_ms(1000 * 3);
printf("==========================================================\n");
printf("Compiled @ %s, %s\n", __DATE__, __TIME__);
printf("==========================================================\n");
wizchip_spi_initialize();
wizchip_cris_initialize();
wizchip_reset();
wizchip_initialize();
wizchip_check();
#ifdef DHCP4
g_net_info.ipmode = NETINFO_DHCP_V4;
#else
g_net_info.ipmode = NETINFO_STATIC_V4;
#endif
#ifdef IPV6
#ifdef ADDRS_AUTO_CONFIG
g_net_info.ipmode |= NETINFO_SLAAC_V6;
#else
g_net_info.ipmode |= NETINFO_STATIC_V6;
#endif
#endif
network_initialize(g_net_info);
/* Get network information */
print_network_information(g_net_info);
#ifdef ADDRS_AUTO_CONFIG
if(g_net_info.ipmode & NETINFO_SLAAC_V6)
{
if(1 != AddressAutoConfig_Init(&g_net_info))
{
printf("Address Auto Config failed\n");
}
}
#endif
#ifdef DHCP4
if (g_net_info.ipmode & NETINFO_DHCP_V4) // DHCP
{
wizchip_dhcp4_init();
}
#else
g_dhcp_get_ip_flag = 1;
#endif
#ifdef DNS
DNS_init(g_ethernet_buf);
#endif
/* Infinite loop */
while (1)
{
#ifdef DHCP4
/* Assigned IP through DHCP */
if (g_net_info.ipmode & NETINFO_DHCP_V4)
{
retval = DHCPv4_run();
if (retval == DHCP_IP_LEASED)
{
if (g_dhcp_get_ip_flag == 0)
{
printf(" DHCP success\n");
g_dhcp_get_ip_flag = 1;
}
}
else if (retval == DHCP_FAILED)
{
g_dhcp_get_ip_flag = 0;
dhcp_retry++;
if (dhcp_retry <= DHCP_RETRY_COUNT)
{
printf(" DHCP timeout occurred and retry %d\n", dhcp_retry);
}
}
if (dhcp_retry > DHCP_RETRY_COUNT)
{
printf(" DHCP failed\n");
DHCPv4_stop();
while (1)
;
}
if(g_dhcp_get_ip_flag == 0)
{
wizchip_delay_ms(1000); // wait for 1 second
}
}
#endif
if(g_dhcp_get_ip_flag == 1)
{
#ifdef TCP_SERVER
/* TCP server loopback test */
if ((retval = loopback_tcps(SOCKET_TCP_SERVER, g_tcp_server_buf, PORT_TCP_SERVER, AS_IPV4)) < 0)
{
printf(" loopback_tcps error : %d\n", retval);
while (1)
;
}
#endif
#ifdef TCP_CLIENT
/* TCP client loopback test */
if ((retval = loopback_tcpc(SOCKET_TCP_CLIENT, g_tcp_client_buf, tcp_client_destip, tcp_client_destport, AS_IPV4)) < 0)
{
printf(" loopback_tcpc error : %d\n", retval);
while (1)
;
}
#endif
#ifdef UDP
/* UDP loopback test */
if ((retval = loopback_udps(SOCKET_UDP, g_udp_buf, PORT_UDP, AS_IPV4)) < 0)
{
printf(" loopback_udps error : %d\n", retval);
while (1)
;
}
#endif
#ifdef TCP_SERVER6
/* TCP server loopback test */
if ((retval = loopback_tcps(SOCKET_TCP_SERVER6, g_tcp_server6_buf, PORT_TCP_SERVER6, AS_IPV6)) < 0)
{
printf(" loopback_tcps IPv6 error : %d\n", retval);
while (1)
;
}
#endif
#ifdef TCP_CLIENT6
/* TCP client loopback test */
if ((retval = loopback_tcpc(SOCKET_TCP_CLIENT6, g_tcp_client6_buf, tcp_client_destip6, tcp_client_destport6, AS_IPV6)) < 0)
{
printf(" loopback_tcpc IPv6 error : %d\n", retval);
while (1)
;
}
#endif
#ifdef UDP6
/* UDP loopback test */
if ((retval = loopback_udps(SOCKET_UDP6, g_udp6_buf, PORT_UDP6, AS_IPV6)) < 0)
{
printf(" loopback_udps IPv6 error : %d\n", retval);
while (1)
;
}
#endif
#ifdef DNS
/* Get IP through DNS */
if (g_dns_get_ip_flag == 0)
{
IP_TYPE = 0x1;
if (DNS_run(SOCKET_DNS, g_net_info.dns, g_dns_target_domain, g_dns_target_ip, AS_IPV4) > 0)
{
printf(" DNS success\n");
printf(" Target domain : %s\n", g_dns_target_domain);
printf(" IP of target domain : %d.%d.%d.%d\n", g_dns_target_ip[0], g_dns_target_ip[1], g_dns_target_ip[2], g_dns_target_ip[3]);
IP_TYPE = 0x1c;
if (DNS_run(SOCKET_DNS, g_net_info.dns, g_dns6_target_domain, g_dns6_target_ip, AS_IPV4) > 0)
{
printf(" DNS success\n");
printf(" Target domain : %s\n", g_dns6_target_domain);
printf(" IP of target domain : %.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x\n"
, g_dns6_target_ip[0], g_dns6_target_ip[1], g_dns6_target_ip[2], g_dns6_target_ip[3]
, g_dns6_target_ip[4], g_dns6_target_ip[5], g_dns6_target_ip[6], g_dns6_target_ip[7]
, g_dns6_target_ip[8], g_dns6_target_ip[9], g_dns6_target_ip[10], g_dns6_target_ip[11]
, g_dns6_target_ip[12], g_dns6_target_ip[13], g_dns6_target_ip[14], g_dns6_target_ip[15]
);
printf(" DNS Done\n");
g_dns_get_ip_flag = 1;
}
// If you have an available network through IPv6.
//#ifdef IPV6
#if 0
g_dns_get_ip_flag = 0;
IP_TYPE = 0x1;
if (DNS_run(SOCKET_DNS, g_net_info.dns6, g_dns6_target_domain, g_dns_target_ip, AS_IPV6) > 0)
{
printf(" DNS6 success\n");
printf(" Target domain : %s\n", g_dns6_target_domain);
printf(" IP of target domain : %d.%d.%d.%d\n", g_dns_target_ip[0], g_dns_target_ip[1], g_dns_target_ip[2], g_dns_target_ip[3]);
IP_TYPE = 0x1c;
if (DNS_run(SOCKET_DNS, g_net_info.dns6, g_dns6_target_domain, g_dns6_target_ip, AS_IPV6) > 0)
{
printf(" DNS6 success\n");
printf(" Target domain : %s\n", g_dns6_target_domain);
printf(" IP of target domain : %.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x\n"
, g_dns6_target_ip[0], g_dns6_target_ip[1], g_dns6_target_ip[2], g_dns6_target_ip[3]
, g_dns6_target_ip[4], g_dns6_target_ip[5], g_dns6_target_ip[6], g_dns6_target_ip[7]
, g_dns6_target_ip[8], g_dns6_target_ip[9], g_dns6_target_ip[10], g_dns6_target_ip[11]
, g_dns6_target_ip[12], g_dns6_target_ip[13], g_dns6_target_ip[14], g_dns6_target_ip[15]
);
g_dns_get_ip_flag = 1;
}
}
#endif
}
else
{
dns_retry++;
if (dns_retry <= DNS_RETRY_COUNT)
{
printf(" DNS timeout occurred and retry %d\n", dns_retry);
}
}
if (dns_retry > DNS_RETRY_COUNT)
{
printf(" DNS failed\n");
while (1)
;
}
if(g_dns_get_ip_flag == 0)
{
wizchip_delay_ms(1000); // wait for 1 second
}
}
#endif
}
}
}
/**
* ----------------------------------------------------------------------------------------------------
* Functions
* ----------------------------------------------------------------------------------------------------
*/
/* Clock */
static void set_clock_khz(void)
{
// set a system clock frequency in khz
set_sys_clock_khz(PLL_SYS_KHZ, true);
// configure the specified clock
clock_configure(
clk_peri,
0, // No glitchless mux
CLOCKS_CLK_PERI_CTRL_AUXSRC_VALUE_CLKSRC_PLL_SYS, // System PLL on AUX mux
PLL_SYS_KHZ * 1000, // Input frequency
PLL_SYS_KHZ * 1000 // Output (must be same as no divider)
);
}
/* DHCP */
static void wizchip_dhcp4_init(void)
{
printf(" DHCP client running\n");
DHCPv4_init(SOCKET_DHCP, g_ethernet_buf);
reg_dhcpv4_cbfunc(wizchip_dhcp4_assign, wizchip_dhcp4_assign, wizchip_dhcp4_conflict);
}
static void wizchip_dhcp4_assign(void)
{
getIPfromDHCPv4(g_net_info.ip);
getGWfromDHCPv4(g_net_info.gw);
getSNfromDHCPv4(g_net_info.sn);
getDNSfromDHCPv4(g_net_info.dns);
/* Network initialize */
network_initialize(g_net_info); // apply from DHCP
print_network_information(g_net_info);
printf(" DHCP leased time : %ld seconds\n", getDHCPv4Leasetime());
}
static void wizchip_dhcp4_conflict(void)
{
printf(" Conflict IP from DHCP\n");
// halt or reset or any...
while (1)
; // this example is halt.
}
/* Timer */
static void repeating_timer_callback(void)
{
g_msec_cnt++;
if (g_msec_cnt >= 1000 - 1)
{
g_msec_cnt = 0;
DHCPv4_time_handler();
DNS_time_handler();
}
}
$ minicom -b 115200 -o -D /dev/ttyACM1
Vítejte v programu minicom 2.7.1
VOLBY: I18n
Datum překladu programu: Dec 23 2019, 02:06:26.
Port /dev/ttyACM1, 21:12:48
Stiskněte CTRL-A Z pro nápovědu o klávesách se zvláštním významem
==========================================================
Compiled @ Mar 5 2024, 20:35:11
==========================================================
==========================================================
W6100 network configuration
MAC : 00:08:DC:12:34:56
IP : 192.168.11.2
Subnet Mask : 255.255.255.0
Gateway : 192.168.11.1
DNS : 8.8.8.8
GW6 : 0000:0000:0000:0000:0000:0000:0000:0000
LLA : FE80:0000:0000:0000:0208:DCFF:FE57:5725
GUA : 0000:0000:0000:0000:0000:0000:0000:0000
SUB6 : FFFF:FFFF:FFFF:FFFF:0000:0000:0000:0000
DNS6 : 2001:4860:4860:0000:0000:0000:0000:8888
==========================================================
Duplicate_Address_Detection
Wait RQIR.....
Timeout !!! DAD SUCCESSED
flags = 0x80
==========================================================
W6100 network configuration
MAC : 00:08:DC:12:34:56
IP : 192.168.11.2
Subnet Mask : 255.255.255.0
Gateway : 192.168.11.1
DNS : 8.8.8.8
GW6 : 0000:0000:0000:0000:0000:0000:0000:0000
LLA : FE80:0000:0000:0000:0208:DCFF:FE12:3456
GUA : 0000:0000:0000:0000:0000:0000:0000:0000
SUB6 : FFFF:FFFF:FFFF:FFFF:0000:0000:0000:0000
DNS6 : 2001:4860:4860:0000:0000:0000:0000:8888
==========================================================
Address_Auto_Configuration Start
getICMP6BLKR() = 0x4
getSn_PROTOR(7) = 0x3a
Sn_SR : 33
getSLRTR() = 0xfa0
getSLRCR() = 0x0
getSLCR() = 0x0
getSLIR() = 0x0
Wait SLIR.....
getSLIR() = 0x0
getSn_RX_RSR(7) = 0x72
size : 4
recvfrom IP : fe80:00:00:00:76d4:35ff:fe84:e5e3
RA
type : 86
code : 0
RA_flag : 0
Router_lifetime : 1800 s
Reachable_time : 0 ms
Retrans_time : 0 ms
Option Type : 3 (Prefix information)
Option length : 32
Prefix Length : 64
Prefix Information Flag : c0
valid lifetime : 5400
preferred lifetime : 2700
prefix : 2a0e:5340:0004:0001::
Option Type : 25 (Recursive DNS Server)
Option length : 24
DNS lifetime : 900
DNS IP : 2a0e:5340:0004:0001:0000:0000:0000:001
default
o_type : 31
o_len : 24
RA : 0
MO : 0
==========================================================
W6100 network configuration
MAC : 00:08:DC:12:34:56
IP : 192.168.11.2
Subnet Mask : 255.255.255.0
Gateway : 192.168.11.1
DNS : 8.8.8.8
GW6 : FE80:0000:0000:0000:76D4:35FF:FE84:E5E3
LLA : FE80:0000:0000:0000:0208:DCFF:FE12:3456
GUA : 2A0E:5340:0004:0001:0208:DCFF:FE12:3456
SUB6 : 2A0E:5340:0004:0001:0000:0000:0000:0000
DNS6 : 2001:4860:4860:0000:0000:0000:0000:8888
==========================================================
Address_Auto_Configuration Succeed
DHCP client running
==========================================================
W6100 network configuration
MAC : 00:08:DC:12:34:56
IP : 192.168.120.186
Subnet Mask : 255.255.255.0
Gateway : 192.168.120.1
DNS : 192.168.120.1
GW6 : FE80:0000:0000:0000:76D4:35FF:FE84:E5E3
LLA : FE80:0000:0000:0000:0208:DCFF:FE12:3456
GUA : 2A0E:5340:0004:0001:0208:DCFF:FE12:3456
SUB6 : 2A0E:5340:0004:0001:0000:0000:0000:0000
DNS6 : 2001:4860:4860:0000:0000:0000:0000:8888
==========================================================
DHCP leased time : 3600 seconds
DHCP success
1:Socket opened[19]
2:Opened, UDP loopback, port [5003] as IPv4 mode
4:Socket opened[19]
5:Opened, UDP loopback, port [5007] as IPv6 mode
DNS success
Target domain : www.wiznet.io
IP of target domain : 183.111.174.49
DNS success
Target domain : www.google.com
IP of target domain : 2a00:1450:4014:080a:0000:0000:0000:2004
DNS Done
0:Listen, TCP server loopback, port [5000] as IPv4 mode
SOCK Status: 0
3:Listen, TCP server loopback, port [5004] as IPv6 mode
SOCK Status: 0
SOCK Status: 0
jirka@jirka-Precision-T3610:~/vyuka_sspvc$ ping 192.168.120.186
PINK 192.168.120.186 (192.168.120.186) 56(84) bytes of data.
64 bajtů od 192.168.120.186: pořadí=1 TTL=128 čas=0,363 ms
64 bajtů od 192.168.120.186: pořadí=2 TTL=128 čas=0,182 ms
64 bajtů od 192.168.120.186: pořadí=3 TTL=128 čas=0,200 ms
64 bajtů od 192.168.120.186: pořadí=4 TTL=128 čas=0,179 ms
^C
--- Statistika pinků na 192.168.120.186 ---
4 paketů odesláno, 4 přijato, 0% ztráta paketů, čas 3064 ms
RTT min/prům/max/s.odch = 0,179/0,231/0,363/0,076 ms
jirka@jirka-Precision-T3610:~/vyuka_sspvc$ ping 2a0e:5340:4:1:208:dcff:fe12:3456
PINK 2a0e:5340:4:1:208:dcff:fe12:3456 (2a0e:5340:4:1:208:dcff:fe12:3456) 56 data bytes
64 bajtů od 2a0e:5340:4:1:208:dcff:fe12:3456: pořadí=1 TTL=128 čas=0,322 ms
64 bajtů od 2a0e:5340:4:1:208:dcff:fe12:3456: pořadí=2 TTL=128 čas=0,308 ms
64 bajtů od 2a0e:5340:4:1:208:dcff:fe12:3456: pořadí=3 TTL=128 čas=0,300 ms
64 bajtů od 2a0e:5340:4:1:208:dcff:fe12:3456: pořadí=4 TTL=128 čas=0,295 ms
^C
--- Statistika pinků na 2a0e:5340:4:1:208:dcff:fe12:3456 ---
4 paketů odesláno, 4 přijato, 0% ztráta paketů, čas 3066 ms
RTT min/prům/max/s.odch = 0,295/0,306/0,322/0,010 ms
jirka@jirka-Precision-T3610:~/vyuka_sspvc$
Zařízení je plně dual stack, IPv4 adresu 192.168.120.186 dostalo od DHCP serveru a IPv6 adresu 2a0e:5340:4:1:208:dcff:fe12:3456 si vyjednalo pomocí RAD protokolu. Protokolem IPv6 je dostupné i ze školy, přestože je u mně v kanceláři na stole.
jirka@jirka-Precision-T3610:~/pico/RP2040-v6-HAT-C/build/examples/AddressAutoConfiguration$ ssh root@piskoviste.jr.lixis.cz
Last login: Mon Feb 19 07:55:05 2024 from 10.17.19.13
OpenBSD 7.4 (GENERIC.MP) #2: Fri Dec 8 15:39:04 MST 2023
Welcome to OpenBSD: The proactively secure Unix-like operating system.
Please use the sendbug(1) utility to report bugs in the system.
Before reporting a bug, please try to reproduce it with the latest
version of the code. With bug reports, please try to ensure that
enough information to reproduce the problem is enclosed, and if a
known fix for it exists, include that as well.
piskoviste# ping6 2a0e:5340:4:1:208:dcff:fe12:3456
PING 2a0e:5340:4:1:208:dcff:fe12:3456 (2a0e:5340:4:1:208:dcff:fe12:3456): 56 data bytes
64 bytes from 2a0e:5340:4:1:208:dcff:fe12:3456: icmp_seq=0 hlim=116 time=9.059 ms
64 bytes from 2a0e:5340:4:1:208:dcff:fe12:3456: icmp_seq=1 hlim=116 time=8.858 ms
64 bytes from 2a0e:5340:4:1:208:dcff:fe12:3456: icmp_seq=2 hlim=116 time=8.760 ms
^C
--- 2a0e:5340:4:1:208:dcff:fe12:3456 ping statistics ---
3 packets transmitted, 3 packets received, 0.0% packet loss
round-trip min/avg/max/std-dev = 8.760/8.893/9.059/0.125 ms
piskoviste#
Na stroječku je jednoduchý "loopback server", který nedělá nic jiného, než že poslouchá na TCP portu a dělá ozvěnu. Po uspěšném připojení opakuje text, který mu pošleme. Pro IPv6 protokol server poslouchá na TCP portu 5004. Pro otestování loopback serveru použiju program telnet, který je snad na každém Linuxu. Program telnet nepoužívá žádné šifrování, takže komunikaci po síti může kdokoliv na trase odposlechnout.
jirka-Precision-T3610:~$ telnet 2a0e:5340:4:1:208:dcff:fe12:3456 5004 (1)
Trying 2a0e:5340:4:1:208:dcff:fe12:3456...
Connected to 2a0e:5340:4:1:208:dcff:fe12:3456.
Escape character is '^]'.
Ahoj (2)
Ahoj (3)
Ping (2)
Ping (3)
Funguje to. (2)
Funguje to. (3)
^] (4)
telnet> quit
Connection closed.
| 1 | Připojení telnet <ip adresa našeho zařízení> <port>. |
| 2 | Toto jsem napsal na klávesnici, |
| 3 | a toto se vrátilo. |
| 4 | Abych ukončil spojení a program telnet, musím zmáčknou Ctrl+AltGr+g což vygeneruje escape znak '^]' a potom klávesu q nebo napsat quit, tak ukončím spojení se serverem. |
Synchronní ukázka práce programu
$ telnet 2a0e:5340:4:1:208:dcff:fe12:3456 5004
Trying 2a0e:5340:4:1:208:dcff:fe12:3456...
Connected to 2a0e:5340:4:1:208:dcff:fe12:3456.
Escape character is '^]'.
Kolik je hodin? (1)
Kolik je hodin? (2)
Nemusis me posilat vetu "Kolik je hodin?", ale rekni mi, kolik je skutecne hodin. (3)
Nemusis me posilat vetu "Kolik je hodin?", ale rekni mi, kolik je skutecne hodin. (4)
Ty nejsi moc inteligentní? (5)
Ty nejsi moc inteligentní? (6)
Tak urcite nejsi AI. (7)
Tak urcite nejsi AI. (8)
Koncim, s blbem se rec nevede. (9)
Koncim, s blbem se rec nevede. (10)
^]
telnet> quit
Connection closed. (11)
| 1 | Já na klávesnici. |
| 2 | Odpověď serveru. |
| 3 | Já na klávesnici. |
| 4 | Odpověď serveru. |
| 5 | Já na klávesnici. |
| 6 | Odpověď serveru. |
| 7 | Já na klávesnici. Vypadá to, že na druhém konci opravdu nesedí umělá inteligence, přestává mě to bavit. |
| 8 | Odpověď serveru. |
| 9 | Já na klávesnici. |
| 10 | Odpověď serveru. |
| 11 | Už mám plné zuby toho papouškování, končím spojení. |
3:Listen, TCP server loopback, port [5004] as IPv6 mode
Dostal jsem 17 bytu: Kolik je h ... (1)
Dostal jsem 83 bytu: Nemusis me ... (3)
Dostal jsem 29 bytu: Ty nejsi m ... (5)
Dostal jsem 22 bytu: Tak urcite ... (7)
Dostal jsem 32 bytu: Koncim, s ... (9)
3:Listen, TCP server loopback, port [5004] as IPv6 mode (11)
| 1 | Viz 1 z telnetu. |
| 2 | Viz 3 z telnetu. |
| 3 | Viz 5 z telnetu. |
| 4 | Viz 7 z telnetu. |
| 5 | Viz 9 z telnetu. |
| 6 | Klient (to jsem já :-) ukončil spojení, startuje nový server a čeká na další spojení. |