【得捷电子Follow me第4期】基础任务一-以太网ip设置ping与抓包
[复制链接]
4.1 准备
参考
下载代码
git clone --recurse-submodules
Pico-Vscode打开文件夹
D:\BOARD\followme4\RP2040-HAT-C
会自动clone和应用patch,构建
修改RP2040-HAT-C/CMakeLists.txt里
# Set ethernet chip
set(WIZNET_CHIP W5100S)
为
# Set ethernet chip
set(WIZNET_CHIP W5500)
从以下地址下载picotool.exe、pioasm.exe、elf2uf2.exe放到
SDK安装路径我这里是D:\Program Files\Raspberry Pi\Pico SDK v1.5.1\picotool。
https://sourceforge.net/projects/rpi-pico-utils/files/v1.3.0/
修改D:\BOARD\followme4\RP2040-HAT-C\CMakeLists.txt
在pico_sdk_init()前添加
# Avoid building 'pioasm'
add_executable(Pioasm IMPORTED)
set_property(TARGET Pioasm PROPERTY IMPORTED_LOCATION
"pioasm.exe")
set(Pioasm_FOUND 1)
# Avoid building 'elf2uf2'
add_executable(ELF2UF2 IMPORTED)
set_property(TARGET ELF2UF2 PROPERTY IMPORTED_LOCATION
"elf2uf2.exe")
set(ELF2UF2_FOUND 1)
添加系统环境变量path
D:\Program Files\Raspberry Pi\Pico SDK v1.5.1\pico-sdk-tools
编译
点击build,弹出选择工具链,选择arm-none-eabi-gcc
编译后程序位于D:\BOARD\followme4\RP2040-HAT-C\build\examples
下载运行\RP2040-HAT-C\build\examples\loopback\w5x00_loopback.uf2
4.2 W5500初始化(静态IP配置)
修改g_net_info
配置和局域网同一网段
static wiz_NetInfo g_net_info =
{
.mac = {0x00, 0x08, 0xDC, 0x12, 0x34, 0x56}, // MAC address
.ip = {192, 168, 31, 111}, // IP address
.sn = {255, 255, 255, 0}, // Subnet Mask
.gw = {192, 168, 31, 1}, // Gateway
.dns = {8, 8, 8, 8}, // DNS server
.dhcp = NETINFO_STATIC // DHCP enable/disable
};
接上网口,可以看到打印IP地址等信息
4.3 电脑ping开发板与抓包
Wireshark抓包如下
网络调试助手tcp连接开发板IP端口5000,开发板收到数据原样返回
4.4 开发板ping外网
参考https://docs.wiznet.io/img/products/w5500/w5500_ap_ipraw_v110e.pdf
https://docs.wiznet.io/img/products/w5500/w5500_apc_ipraw_v110.zip
ping.c
#include <stdio.h>
#include <stdint.h>
#include "socket.h"
#include "wizchip_conf.h"
#include "ping.h"
#include "port_common.h"
#include "wizchip_conf.h"
#include "socket.h"
#include "w5x00_spi.h"
#include "time.h"
#include "pico/stdlib.h"
PINGMSGR PingRequest; // Variable for Ping Request
PINGMSGR PingReply; // Variable for Ping Reply
static uint16_t RandomID = 0x1234;
static uint16_t RandomSeqNum = 0x4321;
uint8_t ping_reply_received = 0;
uint8_t req=0;
uint8_t rep=0;
#define Sn_PROTO(ch) (0x001408 + (ch << 5))
uint8_t ping_auto(uint8_t s, uint8_t *addr)
{
uint8_t i;
int32_t len = 0;
uint8_t cnt=0;
for(i = 0; i<=3;i++){
switch(getSn_SR(s))
{
case SOCK_CLOSED:
close(s);
IINCHIP_WRITE(Sn_PROTO(s), IPPROTO_ICMP); // set ICMP Protocol
if(socket(s,Sn_MR_IPRAW,3000,0)!=0){ // open the SOCKET with IPRAW mode, if fail then Error
printf( "\r\n socket %d fail r\n", (0)) ;
#ifdef PING_DEBUG
return SOCKET_ERROR;
#endif
}
/* Check socket register */
while(getSn_SR(s)!=SOCK_IPRAW);
sleep_ms(1000); // wait 1000ms
sleep_ms(1000); // wait 1000ms
break;
case SOCK_IPRAW:
ping_request(s, addr);
req++;
while(1){
if ( (len = getSn_RX_RSR(s) ) > 0)
{
ping_reply(s, addr, len);
rep++;
break;
}
else if(cnt > 100)
{
printf( "Request Time out. \r\n");
cnt = 0;
break;
}
else
{
cnt++;
sleep_ms(50); // wait 50ms
}
// wait_time for 2 seconds, Break on fail
}
break;
default:
break;
}
#ifdef PING_DEBUG
if(req>=3)
{
printf("Ping Request = %d, PING_Reply = %d\r\n",req,rep);
if(rep == req)
return SUCCESS;
else
return REPLY_ERROR;
}
#endif
}
}
uint8_t ping_count(uint8_t s, uint16_t pCount, uint8_t *addr){
uint16_t rlen, cnt,i;
cnt = 0;
for(i=0; i<pCount+1;i++){
if(i!=0){
/* Output count number */
printf( "\r\nNo.%d\r\n", (i-1));
}
switch(getSn_SR(s))
{
case SOCK_CLOSED:
close(s);
// close the SOCKET
/* Create Socket */
IINCHIP_WRITE(Sn_PROTO(s), IPPROTO_ICMP); // set ICMP Protocol
if(socket(s,Sn_MR_IPRAW,3000,0)!=s){ // open the SOCKET with IPRAW mode, if fail then Error
printf( "\r\n socket %d fail r\n", (s)) ;
#ifdef PING_DEBUG
return SOCKET_ERROR;
#endif
}
/* Check socket register */
while(getSn_SR(s)!=SOCK_IPRAW);
sleep_ms(1000); // wait 1000ms
sleep_ms(1000); // wait 1000ms
break;
case SOCK_IPRAW:
ping_request(s, addr);
req++;
while(1){
if ( (rlen = getSn_RX_RSR(s) ) > 0){
ping_reply(s, addr, rlen);
rep++;
if (ping_reply_received) break;
}
/* wait_time for 2 seconds, Break on fail*/
if ( (cnt > 100) ) {
printf( "\r\nRequest Time out. \r\n") ;
cnt = 0;
break;
}else {
cnt++;
sleep_ms(50); // wait 50ms
}
}
break;
default:
break;
}
#ifdef PING_DEBUG
if(req>=pCount)
{
printf("Ping Request = %d, PING_Reply = %d\r\n",req,rep);
if(rep == req)
return SUCCESS;
else
return REPLY_ERROR;
}
#endif
}
}
uint8_t ping_request(uint8_t s, uint8_t *addr){
uint16_t i;
//Initailize flag for ping reply
ping_reply_received = 0;
/* make header of the ping-request */
PingRequest.Type = PING_REQUEST; // Ping-Request
PingRequest.Code = CODE_ZERO; // Always '0'
PingRequest.ID = htons(RandomID++); // set ping-request's ID to random integer value
PingRequest.SeqNum =htons(RandomSeqNum++);// set ping-request's sequence number to ramdom integer value
//size = 32; // set Data size
/* Fill in Data[] as size of BIF_LEN (Default = 32)*/
for(i = 0 ; i < BUF_LEN; i++){
PingRequest.Data[i] = (i) % 8; //'0'~'8' number into ping-request's data
}
/* Do checksum of Ping Request */
PingRequest.CheckSum = 0; // value of checksum before calucating checksum of ping-request packet
PingRequest.CheckSum = htons(checksum((uint8_t*)&PingRequest,sizeof(PingRequest))); // Calculate checksum
/* sendto ping_request to destination */
if(sendto(s,(uint8_t *)&PingRequest,sizeof(PingRequest),addr,3000)==0){ // Send Ping-Request to the specified peer.
printf( "\r\n Fail to send ping-reply packet r\n") ;
}else{
printf( "Send Ping Request to Destination (") ;
printf( "%d.%d.%d.%d )", (addr[0]), (addr[1]), (addr[2]), (addr[3])) ;
printf( " ID:%x SeqNum:%x CheckSum:%x\r\n", htons(PingRequest.ID), htons(PingRequest.SeqNum), htons(PingRequest.CheckSum)) ;
}
return 0;
} // ping request
uint8_t ping_reply(uint8_t s, uint8_t *addr, uint16_t rlen){
uint16_t tmp_checksum;
uint16_t len;
uint16_t i;
uint8_t data_buf[128];
uint16_t port = 3000;
PINGMSGR PingReply;
/* receive data from a destination */
len = recvfrom(s, (uint8_t *)data_buf,rlen,addr,&port);
if(data_buf[0] == PING_REPLY) {
PingReply.Type = data_buf[0];
PingReply.Code = data_buf[1];
PingReply.CheckSum = (data_buf[3]<<8) + data_buf[2];
PingReply.ID = (data_buf[5]<<8) + data_buf[4];
PingReply.SeqNum = (data_buf[7]<<8) + data_buf[6];
for(i=0; i<len-8 ; i++)
{
PingReply.Data[i] = data_buf[8+i];
}
/* check Checksum of Ping Reply */
tmp_checksum = ~checksum(data_buf,len);
if(tmp_checksum != 0xffff)
printf("tmp_checksum = %x\r\n",tmp_checksum);
else{
/* Output the Destination IP and the size of the Ping Reply Message*/
printf("Reply from %d.%d.%d.%d ID:%x SeqNum:%x :data size %d bytes\r\n",
(addr[0]), (addr[1]), (addr[2]), (addr[3]), htons(PingReply.ID), htons(PingReply.SeqNum), (rlen+6) );
printf("\r\n");
/* SET ping_reply_receiver to '1' and go out the while_loop (waitting for ping reply)*/
ping_reply_received =1;
}
}
else if(data_buf[0] == PING_REQUEST){
PingReply.Code = data_buf[1];
PingReply.Type = data_buf[2];
PingReply.CheckSum = (data_buf[3]<<8) + data_buf[2];
PingReply.ID = (data_buf[5]<<8) + data_buf[4];
PingReply.SeqNum = (data_buf[7]<<8) + data_buf[6];
for(i=0; i<len-8 ; i++)
{
PingReply.Data[i] = data_buf[8+i];
}
/* check Checksum of Ping Reply */
tmp_checksum = PingReply.CheckSum;
PingReply.CheckSum = 0;
PingReply.CheckSum = htons(checksum((uint8_t*)(&PingReply),len));
if(tmp_checksum != PingReply.CheckSum){
printf( " \n CheckSum is in correct %x shold be %x \n", (tmp_checksum), htons(PingReply.CheckSum)) ;
}else{
//printf( "\r\n Checksum is correct \r\n") ;
}
/* Output the Destination IP and the size of the Ping Reply Message*/
printf("Request from %d.%d.%d.%d ID:%x SeqNum:%x :data size %d bytes\r\n",
(addr[0]), (addr[1]), (addr[2]), (addr[3]), (PingReply.ID), (PingReply.SeqNum), (rlen+6) );
/* SET ping_reply_receiver to '1' and go out the while_loop (waitting for ping reply)*/
ping_reply_received =1;
}
else{
printf(" Unkonwn msg. \n");
}
return 0;
}// ping_reply
uint16_t checksum(uint8_t * data_buf, uint16_t len)
{
uint16_t sum, tsum, i, j;
uint32_t lsum;
j = len >> 1;
lsum = 0;
tsum = 0;
for (i = 0; i < j; i++)
{
tsum = data_buf[i * 2];
tsum = tsum << 8;
tsum += data_buf[i * 2 + 1];
lsum += tsum;
}
if (len % 2)
{
tsum = data_buf[i * 2];
lsum += (tsum << 8);
}
sum = (uint16_t)lsum;
sum = ~(sum + (lsum >> 16));
return sum;
}
uint16_t htons( uint16_t hostshort)
{
#if 1
//#ifdef LITTLE_ENDIAN
uint16_t netshort=0;
netshort = (hostshort & 0xFF) << 8;
netshort |= ((hostshort >> 8)& 0xFF);
return netshort;
#else
return hostshort;
#endif
}
#if 0
/*****************************************************************************************
Function name: wait_1us
Input : cnt; Delay duration = cnt * 1u seconds
Output : non
Description
: A delay function for waiting cnt*1u second.
*****************************************************************************************/
void wait_1us(unsigned int cnt)
{
unsigned int i;
for(i = 0; i<cnt; i++) {
}
}
/*****************************************************************************************
Function name: sleep_ms
Input : cnt; Delay duration = cnt * 1m seconds
Output : non
Description
: A delay function for waiting cnt*1m second. This function use wait_1us but the wait_1us
has some error (not accurate). So if you want exact time delay, please use the Timer.
*****************************************************************************************/
void sleep_ms(unsigned int cnt)
{
unsigned int i;
for (i = 0; i < cnt; i++) wait_1us(1000);
}
#endif
/*****************************************************************************************
Function name: wait_10ms
Input : cnt; Delay duration = cnt * 10m seconds
Output : non
Description
: A delay function for waiting cnt*10m second. This function use sleep_ms but the sleep_ms
has some error (not accurate more than wait_1us). So if you want exact time delay,
please use the Timer.
*****************************************************************************************/
void wait_10ms(unsigned int cnt)
{
unsigned int i;
for (i = 0; i < cnt; i++) sleep_ms(10);
}
Ping.h
#include "wizchip_conf.h"
#define BUF_LEN 32
#define PING_REQUEST 8
#define PING_REPLY 0
#define CODE_ZERO 0
#define SOCKET_ERROR 1
#define TIMEOUT_ERROR 2
#define SUCCESS 3
#define REPLY_ERROR 4
#define PING_DEBUG
typedef struct pingmsg
{
uint8_t Type; // 0 - Ping Reply, 8 - Ping Request
uint8_t Code; // Always 0
int16_t CheckSum; // Check sum
int16_t ID; // Identification
int16_t SeqNum; // Sequence Number
int8_t Data[BUF_LEN];// Ping Data : 1452 = IP RAW MTU - sizeof(Type+Code+CheckSum+ID+SeqNum)
} PINGMSGR;
uint8_t ping_auto(uint8_t s, uint8_t *addr);
uint8_t ping_count(uint8_t s, uint16_t pCount, uint8_t *addr);
uint8_t ping_request(uint8_t s, uint8_t *addr);
uint8_t ping_reply(uint8_t s, uint8_t *addr, uint16_t rlen);
uint16_t checksum(uint8_t * data_buf, uint16_t len);
uint16_t htons( uint16_t hostshort); /* htons function converts a unsigned short from host to TCP/IP network byte order (which is big-endian).*/
测试代码如下
uint8_t pDestaddr[4] = {120,232,145,144};
uint8_t tmp=0;
tmp = ping_auto(0,pDestaddr);
if(tmp == SUCCESS)
printf("-----------PING TEST OK----------\r\n");
else
printf("----------ERROR = %d----------\r\n",tmp);
sleep_ms(50);
|