Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
宁楠萍
rt-thread
提交
a1252f67
R
rt-thread
项目概览
宁楠萍
/
rt-thread
与 Fork 源项目一致
Fork自
RT-Thread / rt-thread
通知
2
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,发现更多精彩内容 >>
提交
a1252f67
编写于
1月 31, 2015
作者:
B
Bernard Xiong
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
[lwIP] Add DHCP server implementation
上级
068e2f95
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
426 addition
and
0 deletion
+426
-0
components/net/lwip_dhcpd/SConscript
components/net/lwip_dhcpd/SConscript
+10
-0
components/net/lwip_dhcpd/dhcp_server.c
components/net/lwip_dhcpd/dhcp_server.c
+380
-0
components/net/lwip_dhcpd/dhcp_server.h
components/net/lwip_dhcpd/dhcp_server.h
+36
-0
未找到文件。
components/net/lwip_dhcpd/SConscript
0 → 100644
浏览文件 @
a1252f67
from
building
import
*
cwd
=
GetCurrentDir
()
src
=
Glob
(
'*.c'
)
CPPPATH
=
[
cwd
]
group
=
DefineGroup
(
'LwIP'
,
src
,
depend
=
[
'RT_USING_LWIP'
,
'LWIP_USING_DHCPD'
],
CPPPATH
=
CPPPATH
)
Return
(
'group'
)
components/net/lwip_dhcpd/dhcp_server.c
0 → 100644
浏览文件 @
a1252f67
/*
* File : dhcp_server.c
* A simple DHCP server implementation
*
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2013-2015, Shanghai Real-Thread Technology Co., Ltd
* http://www.rt-thread.com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Change Logs:
* Date Author Notes
* 2013-01-30 aozima the first version
* 2013-08-08 aozima support different network segments.
* 2015-01-30 bernard release to RT-Thread RTOS.
*/
#include <stdio.h>
#include <stdint.h>
#include <rtthread.h>
#include <lwip/opt.h>
#include <lwip/sockets.h>
#include <lwip/inet_chksum.h>
#include <netif/etharp.h>
#include <netif/ethernetif.h>
#include <lwip/ip.h>
/* DHCP server option */
/* allocated client ip range */
#ifndef DHCPD_CLIENT_IP_MIN
#define DHCPD_CLIENT_IP_MIN 2
#endif
#ifndef DHCPD_CLIENT_IP_MAX
#define DHCPD_CLIENT_IP_MAX 254
#endif
/* the DHCP server address */
#ifndef DHCPD_SERVER_IPADDR0
#define DHCPD_SERVER_IPADDR0 192UL
#define DHCPD_SERVER_IPADDR1 168UL
#define DHCPD_SERVER_IPADDR2 169UL
#define DHCPD_SERVER_IPADDR3 1UL
#endif
//#define DHCP_DEBUG_PRINTF
#ifdef DHCP_DEBUG_PRINTF
#define DEBUG_PRINTF rt_kprintf("[DHCP] "); rt_kprintf
#else
#define DEBUG_PRINTF(...)
#endif
/* DHCP_DEBUG_PRINTF */
/* we need some routines in the DHCP of lwIP */
#undef LWIP_DHCP
#define LWIP_DHCP 1
#include <lwip/dhcp.h>
/* buffer size for receive DHCP packet */
#define BUFSZ 1024
static
uint8_t
next_client_ip
=
DHCPD_CLIENT_IP_MIN
;
static
rt_err_t
_low_level_dhcp_send
(
struct
netif
*
netif
,
const
void
*
buffer
,
rt_size_t
size
)
{
struct
pbuf
*
p
;
struct
eth_hdr
*
ethhdr
;
struct
ip_hdr
*
iphdr
;
struct
udp_hdr
*
udphdr
;
p
=
pbuf_alloc
(
PBUF_LINK
,
SIZEOF_ETH_HDR
+
sizeof
(
struct
ip_hdr
)
+
sizeof
(
struct
udp_hdr
)
+
size
,
PBUF_RAM
);
if
(
p
==
RT_NULL
)
return
-
RT_ENOMEM
;
ethhdr
=
(
struct
eth_hdr
*
)
p
->
payload
;
iphdr
=
(
struct
ip_hdr
*
)((
char
*
)
ethhdr
+
SIZEOF_ETH_HDR
);
udphdr
=
(
struct
udp_hdr
*
)((
char
*
)
iphdr
+
sizeof
(
struct
ip_hdr
));
ETHADDR32_COPY
(
&
ethhdr
->
dest
,
(
struct
eth_addr
*
)
&
ethbroadcast
);
ETHADDR16_COPY
(
&
ethhdr
->
src
,
netif
->
hwaddr
);
ethhdr
->
type
=
PP_HTONS
(
ETHTYPE_IP
);
iphdr
->
src
.
addr
=
0x00000000
;
/* src: 0.0.0.0 */
iphdr
->
dest
.
addr
=
0xFFFFFFFF
;
/* src: 255.255.255.255 */
IPH_VHL_SET
(
iphdr
,
4
,
IP_HLEN
/
4
);
IPH_TOS_SET
(
iphdr
,
0x00
);
IPH_LEN_SET
(
iphdr
,
htons
(
IP_HLEN
+
sizeof
(
struct
udp_hdr
)
+
size
));
IPH_ID_SET
(
iphdr
,
htons
(
2
));
IPH_OFFSET_SET
(
iphdr
,
0
);
IPH_TTL_SET
(
iphdr
,
255
);
IPH_PROTO_SET
(
iphdr
,
IP_PROTO_UDP
);
IPH_CHKSUM_SET
(
iphdr
,
0
);
IPH_CHKSUM_SET
(
iphdr
,
inet_chksum
(
iphdr
,
IP_HLEN
));
udphdr
->
src
=
htons
(
DHCP_SERVER_PORT
);
udphdr
->
dest
=
htons
(
DHCP_CLIENT_PORT
);
udphdr
->
len
=
htons
(
sizeof
(
struct
udp_hdr
)
+
size
);
udphdr
->
chksum
=
0
;
memcpy
((
char
*
)
udphdr
+
sizeof
(
struct
udp_hdr
),
buffer
,
size
);
return
netif
->
linkoutput
(
netif
,
p
);
}
static
void
dhcpd_thread_entry
(
void
*
parameter
)
{
struct
netif
*
netif
=
RT_NULL
;
int
sock
;
int
bytes_read
;
char
*
recv_data
;
rt_uint32_t
addr_len
;
struct
sockaddr_in
server_addr
,
client_addr
;
struct
dhcp_msg
*
msg
;
int
optval
=
1
;
/* get ethernet interface. */
netif
=
(
struct
netif
*
)
parameter
;
RT_ASSERT
(
netif
!=
RT_NULL
);
/* our DHCP server information */
DEBUG_PRINTF
(
"DHCP server IP: %d.%d.%d.%d client IP: %d.%d.%d.%d-%d
\n
"
,
DHCPD_SERVER_IPADDR0
,
DHCPD_SERVER_IPADDR1
,
DHCPD_SERVER_IPADDR2
,
DHCPD_SERVER_IPADDR3
,
DHCPD_SERVER_IPADDR0
,
DHCPD_SERVER_IPADDR1
,
DHCPD_SERVER_IPADDR2
,
DHCPD_CLIENT_IP_MIN
,
DHCPD_CLIENT_IP_MAX
);
/* allocate buffer for receive */
recv_data
=
rt_malloc
(
BUFSZ
);
if
(
recv_data
==
RT_NULL
)
{
/* No memory */
DEBUG_PRINTF
(
"Out of memory
\n
"
);
return
;
}
/* create a socket with UDP */
if
((
sock
=
socket
(
AF_INET
,
SOCK_DGRAM
,
0
))
==
-
1
)
{
DEBUG_PRINTF
(
"create socket failed, errno = %d
\n
"
,
errno
);
rt_free
(
recv_data
);
return
;
}
/* set to receive broadcast packet */
setsockopt
(
sock
,
SOL_SOCKET
,
SO_BROADCAST
,
&
optval
,
sizeof
(
optval
));
/* initialize server address */
server_addr
.
sin_family
=
AF_INET
;
server_addr
.
sin_port
=
htons
(
DHCP_SERVER_PORT
);
server_addr
.
sin_addr
.
s_addr
=
INADDR_ANY
;
rt_memset
(
&
(
server_addr
.
sin_zero
),
0
,
sizeof
(
server_addr
.
sin_zero
));
/* bind socket to the server address */
if
(
bind
(
sock
,
(
struct
sockaddr
*
)
&
server_addr
,
sizeof
(
struct
sockaddr
))
==
-
1
)
{
/* bind failed. */
DEBUG_PRINTF
(
"bind server address failed, errno=%d
\n
"
,
errno
);
rt_free
(
recv_data
);
return
;
}
addr_len
=
sizeof
(
struct
sockaddr
);
DEBUG_PRINTF
(
"DHCP server listen on port %d...
\n
"
,
DHCP_SERVER_PORT
);
while
(
1
)
{
bytes_read
=
recvfrom
(
sock
,
recv_data
,
BUFSZ
-
1
,
0
,
(
struct
sockaddr
*
)
&
client_addr
,
&
addr_len
);
if
(
bytes_read
<
DHCP_MSG_LEN
)
{
DEBUG_PRINTF
(
"packet too short, wait for next!
\n
"
);
continue
;
}
msg
=
(
struct
dhcp_msg
*
)
recv_data
;
/* check message type to make sure we can handle it */
if
((
msg
->
op
!=
DHCP_BOOTREQUEST
)
||
(
msg
->
cookie
!=
PP_HTONL
(
DHCP_MAGIC_COOKIE
)))
{
continue
;
}
/* handler. */
{
uint8_t
*
dhcp_opt
;
uint8_t
option
;
uint8_t
length
;
uint8_t
message_type
=
0
;
uint8_t
finished
=
0
;
uint32_t
request_ip
=
0
;
dhcp_opt
=
(
uint8_t
*
)
msg
+
DHCP_OPTIONS_OFS
;
while
(
finished
==
0
)
{
option
=
*
dhcp_opt
;
length
=
*
(
dhcp_opt
+
1
);
switch
(
option
)
{
case
DHCP_OPTION_REQUESTED_IP
:
request_ip
=
*
(
dhcp_opt
+
2
)
<<
24
|
*
(
dhcp_opt
+
3
)
<<
16
|
*
(
dhcp_opt
+
4
)
<<
8
|
*
(
dhcp_opt
+
5
);
break
;
case
DHCP_OPTION_END
:
finished
=
1
;
break
;
case
DHCP_OPTION_MESSAGE_TYPE
:
message_type
=
*
(
dhcp_opt
+
2
);
break
;
default:
break
;
}
/* switch(option) */
dhcp_opt
+=
(
2
+
length
);
}
/* reply. */
dhcp_opt
=
(
uint8_t
*
)
msg
+
DHCP_OPTIONS_OFS
;
/* check. */
if
(
request_ip
)
{
uint32_t
client_ip
=
DHCPD_SERVER_IPADDR0
<<
24
|
DHCPD_SERVER_IPADDR1
<<
16
|
DHCPD_SERVER_IPADDR2
<<
8
|
(
next_client_ip
);
if
(
request_ip
!=
client_ip
)
{
*
dhcp_opt
++
=
DHCP_OPTION_MESSAGE_TYPE
;
*
dhcp_opt
++
=
DHCP_OPTION_MESSAGE_TYPE_LEN
;
*
dhcp_opt
++
=
DHCP_NAK
;
*
dhcp_opt
++
=
DHCP_OPTION_END
;
DEBUG_PRINTF
(
"requested IP invalid, reply DHCP_NAK
\n
"
);
if
(
netif
!=
RT_NULL
)
{
int
send_byte
=
(
dhcp_opt
-
(
uint8_t
*
)
msg
);
_low_level_dhcp_send
(
netif
,
msg
,
send_byte
);
DEBUG_PRINTF
(
"DHCP server send %d byte
\n
"
,
send_byte
);
}
next_client_ip
++
;
if
(
next_client_ip
>
DHCPD_CLIENT_IP_MAX
)
next_client_ip
=
DHCPD_CLIENT_IP_MIN
;
continue
;
}
}
if
(
message_type
==
DHCP_DISCOVER
)
{
DEBUG_PRINTF
(
"request DHCP_DISCOVER
\n
"
);
DEBUG_PRINTF
(
"reply DHCP_OFFER
\n
"
);
// DHCP_OPTION_MESSAGE_TYPE
*
dhcp_opt
++
=
DHCP_OPTION_MESSAGE_TYPE
;
*
dhcp_opt
++
=
DHCP_OPTION_MESSAGE_TYPE_LEN
;
*
dhcp_opt
++
=
DHCP_OFFER
;
// DHCP_OPTION_SERVER_ID
*
dhcp_opt
++
=
DHCP_OPTION_SERVER_ID
;
*
dhcp_opt
++
=
4
;
*
dhcp_opt
++
=
DHCPD_SERVER_IPADDR0
;
*
dhcp_opt
++
=
DHCPD_SERVER_IPADDR1
;
*
dhcp_opt
++
=
DHCPD_SERVER_IPADDR2
;
*
dhcp_opt
++
=
DHCPD_SERVER_IPADDR3
;
// DHCP_OPTION_LEASE_TIME
*
dhcp_opt
++
=
DHCP_OPTION_LEASE_TIME
;
*
dhcp_opt
++
=
4
;
*
dhcp_opt
++
=
0x00
;
*
dhcp_opt
++
=
0x01
;
*
dhcp_opt
++
=
0x51
;
*
dhcp_opt
++
=
0x80
;
}
else
if
(
message_type
==
DHCP_REQUEST
)
{
DEBUG_PRINTF
(
"request DHCP_REQUEST
\n
"
);
DEBUG_PRINTF
(
"reply DHCP_ACK
\n
"
);
// DHCP_OPTION_MESSAGE_TYPE
*
dhcp_opt
++
=
DHCP_OPTION_MESSAGE_TYPE
;
*
dhcp_opt
++
=
DHCP_OPTION_MESSAGE_TYPE_LEN
;
*
dhcp_opt
++
=
DHCP_ACK
;
// DHCP_OPTION_SERVER_ID
*
dhcp_opt
++
=
DHCP_OPTION_SERVER_ID
;
*
dhcp_opt
++
=
4
;
*
dhcp_opt
++
=
DHCPD_SERVER_IPADDR0
;
*
dhcp_opt
++
=
DHCPD_SERVER_IPADDR1
;
*
dhcp_opt
++
=
DHCPD_SERVER_IPADDR2
;
*
dhcp_opt
++
=
DHCPD_SERVER_IPADDR3
;
// DHCP_OPTION_SUBNET_MASK
*
dhcp_opt
++
=
DHCP_OPTION_SUBNET_MASK
;
*
dhcp_opt
++
=
4
;
*
dhcp_opt
++
=
0xFF
;
*
dhcp_opt
++
=
0xFF
;
*
dhcp_opt
++
=
0xFF
;
*
dhcp_opt
++
=
0x00
;
// DHCP_OPTION_LEASE_TIME
*
dhcp_opt
++
=
DHCP_OPTION_LEASE_TIME
;
*
dhcp_opt
++
=
4
;
*
dhcp_opt
++
=
0x00
;
*
dhcp_opt
++
=
0x01
;
*
dhcp_opt
++
=
0x51
;
*
dhcp_opt
++
=
0x80
;
}
else
{
DEBUG_PRINTF
(
"un handle message:%d
\n
"
,
message_type
);
}
// append DHCP_OPTION_END
*
dhcp_opt
++
=
DHCP_OPTION_END
;
/* send reply. */
if
((
message_type
==
DHCP_DISCOVER
)
||
(
message_type
==
DHCP_REQUEST
))
{
msg
->
op
=
DHCP_BOOTREPLY
;
IP4_ADDR
(
&
msg
->
yiaddr
,
DHCPD_SERVER_IPADDR0
,
DHCPD_SERVER_IPADDR1
,
DHCPD_SERVER_IPADDR2
,
next_client_ip
);
client_addr
.
sin_addr
.
s_addr
=
INADDR_BROADCAST
;
if
(
netif
!=
RT_NULL
)
{
int
send_byte
=
(
dhcp_opt
-
(
uint8_t
*
)
msg
);
_low_level_dhcp_send
(
netif
,
msg
,
send_byte
);
DEBUG_PRINTF
(
"DHCP server send %d byte
\n
"
,
send_byte
);
}
}
}
/* handler. */
}
}
void
dhcpd_start
(
char
*
netif_name
)
{
rt_thread_t
thread
;
struct
netif
*
netif
=
RT_NULL
;
/* find ethernet interface. */
netif
=
netif_find
(
netif_name
);
if
(
netif
==
RT_NULL
)
{
DEBUG_PRINTF
(
"Not found network interface:%s
\n
"
,
netif_name
);
}
thread
=
rt_thread_create
(
"dhcpd"
,
dhcpd_thread_entry
,
netif
,
1024
,
RT_THREAD_PRIORITY_MAX
-
3
,
2
);
if
(
thread
!=
RT_NULL
)
{
rt_thread_startup
(
thread
);
}
}
components/net/lwip_dhcpd/dhcp_server.h
0 → 100644
浏览文件 @
a1252f67
/*
* File : dhcp_server.h
* A simple DHCP server implementation
*
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2013-2015, Shanghai Real-Thread Technology Co., Ltd
* http://www.rt-thread.com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Change Logs:
* Date Author Notes
* 2013-01-30 aozima the first version
* 2013-08-08 aozima support different network segments.
* 2015-01-30 bernard release to RT-Thread RTOS.
*/
#ifndef DHCPV4_SERVER_H__
#define DHCPV4_SERVER_H__
void
dhcpd_start
(
char
*
netif_name
);
#endif
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录