Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
okll00
rt-thread
提交
16b54610
R
rt-thread
项目概览
okll00
/
rt-thread
与 Fork 源项目一致
Fork自
RT-Thread / rt-thread
通知
5
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
rt-thread
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
16b54610
编写于
8月 10, 2017
作者:
B
Bernard Xiong
提交者:
GitHub
8月 10, 2017
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #798 from armink/add_apps_to_lwip202
[lwIP] Add apps to lwip202
上级
4626b19e
640fd7d8
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
596 addition
and
0 deletion
+596
-0
components/net/lwip-2.0.2/SConscript
components/net/lwip-2.0.2/SConscript
+4
-0
components/net/lwip-2.0.2/apps/ping.c
components/net/lwip-2.0.2/apps/ping.c
+201
-0
components/net/lwip-2.0.2/apps/telnet.c
components/net/lwip-2.0.2/apps/telnet.c
+391
-0
未找到文件。
components/net/lwip-2.0.2/SConscript
浏览文件 @
16b54610
...
...
@@ -75,6 +75,10 @@ if GetDepend(['RT_LWIP_SNMP']):
if
GetDepend
([
'RT_LWIP_PPP'
]):
src
+=
ppp_src
path
+=
[
GetCurrentDir
()
+
'/src/netif/ppp'
]
# For testing apps
if
GetDepend
([
'RT_USING_NETUTILS'
]):
src
+=
Glob
(
'./apps/*.c'
)
group
=
DefineGroup
(
'lwIP'
,
src
,
depend
=
[
'RT_USING_LWIP'
,
'RT_USING_LWIP202'
],
CPPPATH
=
path
)
...
...
components/net/lwip-2.0.2/apps/ping.c
0 → 100644
浏览文件 @
16b54610
/*
* netutils: ping implementation
*/
#include "lwip/opt.h"
#include "lwip/mem.h"
#include "lwip/icmp.h"
#include "lwip/netif.h"
#include "lwip/sys.h"
#include "lwip/sockets.h"
#include "lwip/inet.h"
#include "lwip/inet_chksum.h"
#include "lwip/ip.h"
/**
* PING_DEBUG: Enable debugging for PING.
*/
#ifndef PING_DEBUG
#define PING_DEBUG LWIP_DBG_ON
#endif
/** ping receive timeout - in milliseconds */
#define PING_RCV_TIMEO rt_tick_from_millisecond(2000)
/** ping delay - in milliseconds */
#define PING_DELAY rt_tick_from_millisecond(1000)
/** ping identifier - must fit on a u16_t */
#ifndef PING_ID
#define PING_ID 0xAFAF
#endif
/** ping additional data size to include in the packet */
#ifndef PING_DATA_SIZE
#define PING_DATA_SIZE 32
#endif
/* ping variables */
static
u16_t
ping_seq_num
;
struct
_ip_addr
{
rt_uint8_t
addr0
,
addr1
,
addr2
,
addr3
;
};
/** Prepare a echo ICMP request */
static
void
ping_prepare_echo
(
struct
icmp_echo_hdr
*
iecho
,
u16_t
len
)
{
size_t
i
;
size_t
data_len
=
len
-
sizeof
(
struct
icmp_echo_hdr
);
ICMPH_TYPE_SET
(
iecho
,
ICMP_ECHO
);
ICMPH_CODE_SET
(
iecho
,
0
);
iecho
->
chksum
=
0
;
iecho
->
id
=
PING_ID
;
iecho
->
seqno
=
htons
(
++
ping_seq_num
);
/* fill the additional data buffer with some data */
for
(
i
=
0
;
i
<
data_len
;
i
++
)
{
((
char
*
)
iecho
)[
sizeof
(
struct
icmp_echo_hdr
)
+
i
]
=
(
char
)
i
;
}
iecho
->
chksum
=
inet_chksum
(
iecho
,
len
);
}
/* Ping using the socket ip */
static
err_t
ping_send
(
int
s
,
ip_addr_t
*
addr
,
int
size
)
{
int
err
;
struct
icmp_echo_hdr
*
iecho
;
struct
sockaddr_in
to
;
size_t
ping_size
=
sizeof
(
struct
icmp_echo_hdr
)
+
size
;
LWIP_ASSERT
(
"ping_size is too big"
,
ping_size
<=
0xffff
);
iecho
=
rt_malloc
(
ping_size
);
if
(
iecho
==
RT_NULL
)
{
return
ERR_MEM
;
}
ping_prepare_echo
(
iecho
,
(
u16_t
)
ping_size
);
to
.
sin_len
=
sizeof
(
to
);
to
.
sin_family
=
AF_INET
;
to
.
sin_addr
.
s_addr
=
addr
->
addr
;
err
=
lwip_sendto
(
s
,
iecho
,
ping_size
,
0
,
(
struct
sockaddr
*
)
&
to
,
sizeof
(
to
));
rt_free
(
iecho
);
return
(
err
==
ping_size
?
ERR_OK
:
ERR_VAL
);
}
static
int
ping_recv
(
int
s
,
int
*
ttl
)
{
char
buf
[
64
];
int
fromlen
=
sizeof
(
struct
sockaddr_in
),
len
;
struct
sockaddr_in
from
;
struct
ip_hdr
*
iphdr
;
struct
icmp_echo_hdr
*
iecho
;
while
((
len
=
lwip_recvfrom
(
s
,
buf
,
sizeof
(
buf
),
0
,
(
struct
sockaddr
*
)
&
from
,
(
socklen_t
*
)
&
fromlen
))
>
0
)
{
if
(
len
>=
(
sizeof
(
struct
ip_hdr
)
+
sizeof
(
struct
icmp_echo_hdr
)))
{
iphdr
=
(
struct
ip_hdr
*
)
buf
;
iecho
=
(
struct
icmp_echo_hdr
*
)(
buf
+
(
IPH_HL
(
iphdr
)
*
4
));
if
((
iecho
->
id
==
PING_ID
)
&&
(
iecho
->
seqno
==
htons
(
ping_seq_num
)))
{
*
ttl
=
iphdr
->
_ttl
;
return
len
;
}
}
}
return
len
;
}
rt_err_t
ping
(
char
*
target
,
rt_uint32_t
times
,
rt_size_t
size
)
{
int
s
,
ttl
,
recv_len
;
struct
timeval
timeout
=
{
PING_RCV_TIMEO
/
RT_TICK_PER_SECOND
,
PING_RCV_TIMEO
%
RT_TICK_PER_SECOND
};
ip_addr_t
ping_target
;
rt_uint32_t
send_times
;
rt_tick_t
recv_start_tick
;
struct
_ip_addr
{
rt_uint8_t
addr0
,
addr1
,
addr2
,
addr3
;
}
*
addr
;
send_times
=
0
;
ping_seq_num
=
0
;
if
(
size
==
0
)
size
=
PING_DATA_SIZE
;
if
(
inet_aton
(
target
,
&
ping_target
)
==
0
)
{
rt_kprintf
(
"ping: unknown host %s
\n
"
,
target
);
return
-
RT_ERROR
;
}
addr
=
(
struct
_ip_addr
*
)
&
ping_target
;
if
((
s
=
lwip_socket
(
AF_INET
,
SOCK_RAW
,
IP_PROTO_ICMP
))
<
0
)
{
rt_kprintf
(
"ping: create socket failled
\n
"
);
return
-
RT_ERROR
;
}
lwip_setsockopt
(
s
,
SOL_SOCKET
,
SO_RCVTIMEO
,
&
timeout
,
sizeof
(
struct
timeval
));
while
(
1
)
{
if
(
ping_send
(
s
,
&
ping_target
,
size
)
==
ERR_OK
)
{
recv_start_tick
=
rt_tick_get
();
if
((
recv_len
=
ping_recv
(
s
,
&
ttl
))
>=
0
)
{
rt_kprintf
(
"%d bytes from %d.%d.%d.%d icmp_seq=%d ttl=%d time=%d ticks
\n
"
,
recv_len
,
addr
->
addr0
,
addr
->
addr1
,
addr
->
addr2
,
addr
->
addr3
,
send_times
,
ttl
,
rt_tick_get
()
-
recv_start_tick
);
}
else
{
rt_kprintf
(
"From %d.%d.%d.%d icmp_seq=%d timeout
\n
"
,
addr
->
addr0
,
addr
->
addr1
,
addr
->
addr2
,
addr
->
addr3
,
send_times
);
}
}
else
{
rt_kprintf
(
"Send %d.%d.%d.%d - error
\n
"
,
addr
->
addr0
,
addr
->
addr1
,
addr
->
addr2
,
addr
->
addr3
);
}
send_times
++
;
if
(
send_times
>=
times
)
break
;
/* send ping times reached, stop */
rt_thread_delay
(
PING_DELAY
);
/* take a delay */
}
lwip_close
(
s
);
return
RT_EOK
;
}
#ifdef RT_USING_FINSH
#include <finsh.h>
FINSH_FUNCTION_EXPORT
(
ping
,
ping
network
host
);
int
cmd_ping
(
int
argc
,
char
**
argv
)
{
if
(
argc
==
1
)
{
rt_kprintf
(
"Please input: ping <host address>
\n
"
);
}
else
{
ping
(
argv
[
1
],
4
,
0
);
}
return
0
;
}
FINSH_FUNCTION_EXPORT_ALIAS
(
cmd_ping
,
__cmd_ping
,
ping
network
host
);
#endif
components/net/lwip-2.0.2/apps/telnet.c
0 → 100644
浏览文件 @
16b54610
#include <rtthread.h>
#include <lwip/api.h>
#include <lwip/sockets.h>
#include <rtdevice.h>
#include <finsh.h>
#include <shell.h>
#define TELNET_PORT 23
#define TELNET_BACKLOG 5
#define RX_BUFFER_SIZE 256
#define TX_BUFFER_SIZE 4096
#define ISO_nl 0x0a
#define ISO_cr 0x0d
#define STATE_NORMAL 0
#define STATE_IAC 1
#define STATE_WILL 2
#define STATE_WONT 3
#define STATE_DO 4
#define STATE_DONT 5
#define STATE_CLOSE 6
#define TELNET_IAC 255
#define TELNET_WILL 251
#define TELNET_WONT 252
#define TELNET_DO 253
#define TELNET_DONT 254
struct
telnet_session
{
struct
rt_ringbuffer
rx_ringbuffer
;
struct
rt_ringbuffer
tx_ringbuffer
;
rt_mutex_t
rx_ringbuffer_lock
;
rt_mutex_t
tx_ringbuffer_lock
;
struct
rt_device
device
;
rt_int32_t
server_fd
;
rt_int32_t
client_fd
;
/* telnet protocol */
rt_uint8_t
state
;
rt_uint8_t
echo_mode
;
};
static
struct
telnet_session
*
telnet
;
/* process tx data */
static
void
send_to_client
(
struct
telnet_session
*
telnet
)
{
rt_size_t
length
;
rt_uint8_t
tx_buffer
[
32
];
while
(
1
)
{
rt_memset
(
tx_buffer
,
0
,
sizeof
(
tx_buffer
));
rt_mutex_take
(
telnet
->
tx_ringbuffer_lock
,
RT_WAITING_FOREVER
);
/* get buffer from ringbuffer */
length
=
rt_ringbuffer_get
(
&
(
telnet
->
tx_ringbuffer
),
tx_buffer
,
sizeof
(
tx_buffer
));
rt_mutex_release
(
telnet
->
tx_ringbuffer_lock
);
/* do a tx procedure */
if
(
length
>
0
)
{
send
(
telnet
->
client_fd
,
tx_buffer
,
length
,
0
);
}
else
break
;
}
}
/* send telnet option to remote */
static
void
send_option_to_client
(
struct
telnet_session
*
telnet
,
rt_uint8_t
option
,
rt_uint8_t
value
)
{
rt_uint8_t
optbuf
[
4
];
optbuf
[
0
]
=
TELNET_IAC
;
optbuf
[
1
]
=
option
;
optbuf
[
2
]
=
value
;
optbuf
[
3
]
=
0
;
rt_mutex_take
(
telnet
->
tx_ringbuffer_lock
,
RT_WAITING_FOREVER
);
rt_ringbuffer_put
(
&
telnet
->
tx_ringbuffer
,
optbuf
,
3
);
rt_mutex_release
(
telnet
->
tx_ringbuffer_lock
);
send_to_client
(
telnet
);
}
/* process rx data */
static
void
process_rx
(
struct
telnet_session
*
telnet
,
rt_uint8_t
*
data
,
rt_size_t
length
)
{
rt_size_t
rx_length
,
index
;
for
(
index
=
0
;
index
<
length
;
index
++
)
{
switch
(
telnet
->
state
)
{
case
STATE_IAC
:
if
(
*
data
==
TELNET_IAC
)
{
rt_mutex_take
(
telnet
->
rx_ringbuffer_lock
,
RT_WAITING_FOREVER
);
/* put buffer to ringbuffer */
rt_ringbuffer_putchar
(
&
(
telnet
->
rx_ringbuffer
),
*
data
);
rt_mutex_release
(
telnet
->
rx_ringbuffer_lock
);
telnet
->
state
=
STATE_NORMAL
;
}
else
{
/* set telnet state according to received package */
switch
(
*
data
)
{
case
TELNET_WILL
:
telnet
->
state
=
STATE_WILL
;
break
;
case
TELNET_WONT
:
telnet
->
state
=
STATE_WONT
;
break
;
case
TELNET_DO
:
telnet
->
state
=
STATE_DO
;
break
;
case
TELNET_DONT
:
telnet
->
state
=
STATE_DONT
;
break
;
default:
telnet
->
state
=
STATE_NORMAL
;
break
;
}
}
break
;
/* don't option */
case
STATE_WILL
:
case
STATE_WONT
:
send_option_to_client
(
telnet
,
TELNET_DONT
,
*
data
);
telnet
->
state
=
STATE_NORMAL
;
break
;
/* won't option */
case
STATE_DO
:
case
STATE_DONT
:
send_option_to_client
(
telnet
,
TELNET_WONT
,
*
data
);
telnet
->
state
=
STATE_NORMAL
;
break
;
case
STATE_NORMAL
:
if
(
*
data
==
TELNET_IAC
)
telnet
->
state
=
STATE_IAC
;
else
if
(
*
data
!=
'\r'
)
/* ignore '\r' */
{
rt_mutex_take
(
telnet
->
rx_ringbuffer_lock
,
RT_WAITING_FOREVER
);
/* put buffer to ringbuffer */
rt_ringbuffer_putchar
(
&
(
telnet
->
rx_ringbuffer
),
*
data
);
rt_mutex_release
(
telnet
->
rx_ringbuffer_lock
);
}
break
;
}
data
++
;
}
rt_mutex_take
(
telnet
->
rx_ringbuffer_lock
,
RT_WAITING_FOREVER
);
/* get total size */
rx_length
=
rt_ringbuffer_data_len
(
&
telnet
->
rx_ringbuffer
);
rt_mutex_release
(
telnet
->
rx_ringbuffer_lock
);
/* indicate there are reception data */
if
((
rx_length
>
0
)
&&
(
telnet
->
device
.
rx_indicate
!=
RT_NULL
))
telnet
->
device
.
rx_indicate
(
&
telnet
->
device
,
rx_length
);
return
;
}
/* client close */
static
void
client_close
(
struct
telnet_session
*
telnet
)
{
/* set console */
rt_console_set_device
(
RT_CONSOLE_DEVICE_NAME
);
/* set finsh device */
finsh_set_device
(
RT_CONSOLE_DEVICE_NAME
);
/* close connection */
closesocket
(
telnet
->
client_fd
);
/* restore shell option */
finsh_set_echo
(
telnet
->
echo_mode
);
rt_kprintf
(
"resume console to %s
\n
"
,
RT_CONSOLE_DEVICE_NAME
);
}
/* RT-Thread Device Driver Interface */
static
rt_err_t
telnet_init
(
rt_device_t
dev
)
{
return
RT_EOK
;
}
static
rt_err_t
telnet_open
(
rt_device_t
dev
,
rt_uint16_t
oflag
)
{
return
RT_EOK
;
}
static
rt_err_t
telnet_close
(
rt_device_t
dev
)
{
return
RT_EOK
;
}
static
rt_size_t
telnet_read
(
rt_device_t
dev
,
rt_off_t
pos
,
void
*
buffer
,
rt_size_t
size
)
{
rt_size_t
result
;
/* read from rx ring buffer */
rt_mutex_take
(
telnet
->
rx_ringbuffer_lock
,
RT_WAITING_FOREVER
);
result
=
rt_ringbuffer_get
(
&
(
telnet
->
rx_ringbuffer
),
buffer
,
size
);
rt_mutex_release
(
telnet
->
rx_ringbuffer_lock
);
return
result
;
}
static
rt_size_t
telnet_write
(
rt_device_t
dev
,
rt_off_t
pos
,
const
void
*
buffer
,
rt_size_t
size
)
{
const
rt_uint8_t
*
ptr
;
ptr
=
(
rt_uint8_t
*
)
buffer
;
rt_mutex_take
(
telnet
->
tx_ringbuffer_lock
,
RT_WAITING_FOREVER
);
while
(
size
)
{
if
(
*
ptr
==
'\n'
)
rt_ringbuffer_putchar
(
&
telnet
->
tx_ringbuffer
,
'\r'
);
if
(
rt_ringbuffer_putchar
(
&
telnet
->
tx_ringbuffer
,
*
ptr
)
==
0
)
/* overflow */
break
;
ptr
++
;
size
--
;
}
rt_mutex_release
(
telnet
->
tx_ringbuffer_lock
);
/* send data to telnet client */
send_to_client
(
telnet
);
return
(
rt_uint32_t
)
ptr
-
(
rt_uint32_t
)
buffer
;
}
static
rt_err_t
telnet_control
(
rt_device_t
dev
,
rt_uint8_t
cmd
,
void
*
args
)
{
return
RT_EOK
;
}
/* telnet server thread entry */
static
void
telnet_thread
(
void
*
parameter
)
{
#define RECV_BUF_LEN 64
struct
sockaddr_in
addr
;
socklen_t
addr_size
;
rt_uint8_t
recv_buf
[
RECV_BUF_LEN
];
rt_int32_t
recv_len
=
0
;
if
((
telnet
->
server_fd
=
socket
(
AF_INET
,
SOCK_STREAM
,
0
))
==
-
1
)
{
rt_kprintf
(
"telnet: create socket failed
\n
"
);
return
;
}
addr
.
sin_family
=
AF_INET
;
addr
.
sin_port
=
htons
(
TELNET_PORT
);
addr
.
sin_addr
.
s_addr
=
INADDR_ANY
;
rt_memset
(
&
(
addr
.
sin_zero
),
0
,
sizeof
(
addr
.
sin_zero
));
if
(
bind
(
telnet
->
server_fd
,
(
struct
sockaddr
*
)
&
addr
,
sizeof
(
struct
sockaddr
))
==
-
1
)
{
rt_kprintf
(
"telnet: bind socket failed
\n
"
);
return
;
}
if
(
listen
(
telnet
->
server_fd
,
TELNET_BACKLOG
)
==
-
1
)
{
rt_kprintf
(
"telnet: listen socket failed
\n
"
);
return
;
}
/* register telnet device */
telnet
->
device
.
type
=
RT_Device_Class_Char
;
telnet
->
device
.
init
=
telnet_init
;
telnet
->
device
.
open
=
telnet_open
;
telnet
->
device
.
close
=
telnet_close
;
telnet
->
device
.
read
=
telnet_read
;
telnet
->
device
.
write
=
telnet_write
;
telnet
->
device
.
control
=
telnet_control
;
/* no private */
telnet
->
device
.
user_data
=
RT_NULL
;
/* register telnet device */
rt_device_register
(
&
telnet
->
device
,
"telnet"
,
RT_DEVICE_FLAG_RDWR
|
RT_DEVICE_FLAG_STREAM
);
while
(
1
)
{
rt_kprintf
(
"telnet server waiting for connection
\n
"
);
/* grab new connection */
if
((
telnet
->
client_fd
=
accept
(
telnet
->
server_fd
,
(
struct
sockaddr
*
)
&
addr
,
&
addr_size
))
==
-
1
)
{
continue
;
}
rt_kprintf
(
"new telnet client(%s:%d) connection, switch console to telnet...
\n
"
,
inet_ntoa
(
addr
.
sin_addr
),
addr
.
sin_port
);
/* process the new connection */
/* set console */
rt_console_set_device
(
"telnet"
);
/* set finsh device */
finsh_set_device
(
"telnet"
);
/* set init state */
telnet
->
state
=
STATE_NORMAL
;
telnet
->
echo_mode
=
finsh_get_echo
();
/* disable echo mode */
finsh_set_echo
(
0
);
while
(
1
)
{
/* try to send all data in tx ringbuffer */
send_to_client
(
telnet
);
/* do a rx procedure */
if
((
recv_len
=
recv
(
telnet
->
client_fd
,
recv_buf
,
RECV_BUF_LEN
,
0
))
>
0
)
{
process_rx
(
telnet
,
recv_buf
,
recv_len
);
}
else
{
/* close connection */
client_close
(
telnet
);
break
;
}
}
}
}
/* telnet server */
void
telnet_srv
(
void
)
{
rt_thread_t
tid
;
if
(
telnet
==
RT_NULL
)
{
rt_uint8_t
*
ptr
;
telnet
=
rt_malloc
(
sizeof
(
struct
telnet_session
));
if
(
telnet
==
RT_NULL
)
{
rt_kprintf
(
"telnet: no memory
\n
"
);
return
;
}
/* init ringbuffer */
ptr
=
rt_malloc
(
RX_BUFFER_SIZE
);
if
(
ptr
)
{
rt_ringbuffer_init
(
&
telnet
->
rx_ringbuffer
,
ptr
,
RX_BUFFER_SIZE
);
}
else
{
rt_kprintf
(
"telnet: no memory
\n
"
);
return
;
}
ptr
=
rt_malloc
(
TX_BUFFER_SIZE
);
if
(
ptr
)
{
rt_ringbuffer_init
(
&
telnet
->
tx_ringbuffer
,
ptr
,
TX_BUFFER_SIZE
);
}
else
{
rt_kprintf
(
"telnet: no memory
\n
"
);
return
;
}
/* create tx ringbuffer lock */
telnet
->
tx_ringbuffer_lock
=
rt_mutex_create
(
"telnet_tx"
,
RT_IPC_FLAG_FIFO
);
/* create rx ringbuffer lock */
telnet
->
rx_ringbuffer_lock
=
rt_mutex_create
(
"telnet_rx"
,
RT_IPC_FLAG_FIFO
);
tid
=
rt_thread_create
(
"telnet"
,
telnet_thread
,
RT_NULL
,
2048
,
25
,
5
);
if
(
tid
!=
RT_NULL
)
rt_thread_startup
(
tid
);
}
else
{
rt_kprintf
(
"telnet: already running
\n
"
);
}
}
#ifdef RT_USING_FINSH
#include <finsh.h>
FINSH_FUNCTION_EXPORT
(
telnet_srv
,
startup
telnet
server
);
#ifdef FINSH_USING_MSH
MSH_CMD_EXPORT
(
telnet_srv
,
startup
telnet
server
)
#endif
/* FINSH_USING_MSH */
#endif
/* RT_USING_FINSH */
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录