Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lzh_me
Kernel Liteos A
提交
4f55f678
K
Kernel Liteos A
项目概览
lzh_me
/
Kernel Liteos A
与 Fork 源项目一致
Fork自
OpenHarmony / Kernel Liteos A
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
Kernel Liteos A
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
4f55f678
编写于
9月 22, 2020
作者:
C
c00546070
提交者:
caoruihong 00546070
9月 22, 2020
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Description: add dhcps and tftpc
Reviewed-by: jianghan
上级
9b25a48d
变更
18
隐藏空白更改
内联
并排
Showing
18 changed file
with
3218 addition
and
398 deletion
+3218
-398
net/lwip-2.1/Makefile
net/lwip-2.1/Makefile
+1
-1
net/lwip-2.1/enhancement/include/dhcps_fix.h
net/lwip-2.1/enhancement/include/dhcps_fix.h
+0
-102
net/lwip-2.1/enhancement/include/lwip/api_shell.h
net/lwip-2.1/enhancement/include/lwip/api_shell.h
+3
-5
net/lwip-2.1/enhancement/include/lwip/dhcps.h
net/lwip-2.1/enhancement/include/lwip/dhcps.h
+0
-10
net/lwip-2.1/enhancement/include/lwip/fixme.h
net/lwip-2.1/enhancement/include/lwip/fixme.h
+44
-83
net/lwip-2.1/enhancement/include/lwip/tftpc.h
net/lwip-2.1/enhancement/include/lwip/tftpc.h
+310
-0
net/lwip-2.1/enhancement/src/api_shell.c
net/lwip-2.1/enhancement/src/api_shell.c
+6
-3
net/lwip-2.1/enhancement/src/dhcps.c
net/lwip-2.1/enhancement/src/dhcps.c
+983
-0
net/lwip-2.1/enhancement/src/fixme.c
net/lwip-2.1/enhancement/src/fixme.c
+60
-75
net/lwip-2.1/enhancement/src/tftpc.c
net/lwip-2.1/enhancement/src/tftpc.c
+1726
-0
net/lwip-2.1/porting/include/lwip/dhcp.h
net/lwip-2.1/porting/include/lwip/dhcp.h
+19
-0
net/lwip-2.1/porting/include/lwip/lwipopts.h
net/lwip-2.1/porting/include/lwip/lwipopts.h
+4
-0
net/lwip-2.1/porting/include/lwip/netif.h
net/lwip-2.1/porting/include/lwip/netif.h
+10
-5
net/lwip-2.1/porting/include/lwip/netifapi.h
net/lwip-2.1/porting/include/lwip/netifapi.h
+1
-0
net/lwip-2.1/porting/src/driverif.c
net/lwip-2.1/porting/src/driverif.c
+28
-52
net/lwip-2.1/porting/src/fixme.c
net/lwip-2.1/porting/src/fixme.c
+0
-46
net/lwip-2.1/porting/src/sockets.c
net/lwip-2.1/porting/src/sockets.c
+6
-8
net/lwip-2.1/porting/src/sys_arch.c
net/lwip-2.1/porting/src/sys_arch.c
+17
-8
未找到文件。
net/lwip-2.1/Makefile
浏览文件 @
4f55f678
...
@@ -44,7 +44,7 @@ LOCAL_FLAGS += $(LOCAL_INCLUDE)
...
@@ -44,7 +44,7 @@ LOCAL_FLAGS += $(LOCAL_INCLUDE)
LOCAL_SRCS
:=
$(
wildcard
porting/src/
*
.c
$(LWIPNOAPPSFILES)
)
LOCAL_SRCS
:=
$(
wildcard
porting/src/
*
.c
$(LWIPNOAPPSFILES)
)
LOCAL_SRCS
+=
$(
wildcard
enhancement/src/
*
.c
)
LOCAL_SRCS
+=
$(
wildcard
enhancement/src/
*
.c
)
LOCAL_SRCS
+=
$(
wildcard
$(LWIPDIR)
/core/ipv4/dhcps.c
)
LOCAL_SRCS
:=
$(
filter-out
$(LWIPDIR)
/core/ipv4/dhcp.c,
$(LOCAL_SRCS)
)
LOCAL_SRCS
:=
$(
filter-out
$(LWIPDIR)
/core/ipv4/etharp.c,
$(LOCAL_SRCS)
)
LOCAL_SRCS
:=
$(
filter-out
$(LWIPDIR)
/core/ipv4/etharp.c,
$(LOCAL_SRCS)
)
LOCAL_SRCS
:=
$(
filter-out
$(LWIPDIR)
/api/sockets.c,
$(LOCAL_SRCS)
)
LOCAL_SRCS
:=
$(
filter-out
$(LWIPDIR)
/api/sockets.c,
$(LOCAL_SRCS)
)
...
...
net/lwip-2.1/enhancement/include/dhcps_fix.h
已删除
100755 → 0
浏览文件 @
9b25a48d
/*
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef LITEOS_A_DHCPS_FIXME_H
#define LITEOS_A_DHCPS_FIXME_H
#include "lwip/opt.h"
#if (LWIP_DHCP) && (LWIP_DHCPS)
#define LWIP_STATIC static
/* Option handling: options are parsed in dhcp_parse_reply
* and saved in an array where other functions can load them from.
* This might be moved into the struct dhcp (not necessarily since
* lwIP is single-threaded and the array is only used while in recv
* callback). */
enum
dhcp_option_idx
{
DHCP_OPTION_IDX_OVERLOAD
=
0
,
DHCP_OPTION_IDX_MSG_TYPE
,
DHCP_OPTION_IDX_SERVER_ID
,
DHCP_OPTION_IDX_LEASE_TIME
,
DHCP_OPTION_IDX_T1
,
DHCP_OPTION_IDX_T2
,
DHCP_OPTION_IDX_SUBNET_MASK
,
DHCP_OPTION_IDX_ROUTER
,
#if LWIP_DHCP_PROVIDE_DNS_SERVERS
DHCP_OPTION_IDX_DNS_SERVER
,
DHCP_OPTION_IDX_DNS_SERVER_LAST
=
DHCP_OPTION_IDX_DNS_SERVER
+
LWIP_DHCP_PROVIDE_DNS_SERVERS
-
1
,
#endif
/* LWIP_DHCP_PROVIDE_DNS_SERVERS */
#if LWIP_DHCP_GET_NTP_SRV
DHCP_OPTION_IDX_NTP_SERVER
,
DHCP_OPTION_IDX_NTP_SERVER_LAST
=
DHCP_OPTION_IDX_NTP_SERVER
+
LWIP_DHCP_MAX_NTP_SERVERS
-
1
,
#endif
/* LWIP_DHCP_GET_NTP_SRV */
DHCP_OPTION_IDX_REQUESTED_IP
,
DHCP_OPTION_IDX_MAX
};
#define DHCP_OPTION_ROUTER_SIZE 4
#define DHCP_OPTION_SUBNET_MASK_SIZE 4
#define DHCP_OPTION_LEASE_TIME_SIZE 4
#define DHCP_OPTION_SERVER_ID_LEN 4
#define DHCP_OPTION_T1_LEN 4
#define DHCP_OPTION_T2_LEN 4
#define DHCP_CLIENT_PORT 68
#define DHCP_SERVER_PORT 67
#define DHCP_BROADCAST_FLAG 0x8000
#define DHCP_MAX_MSG_LEN_MIN_REQUIRED 576
struct
dyn_lease_addr
{
u8_t
cli_hwaddr
[
DHCP_CHADDR_LEN
];
u32_t
flags
;
u32_t
leasetime
;
u32_t
proposed_leasetime
;
ip4_addr_t
cli_addr
;
};
struct
dhcps
{
struct
udp_pcb
*
pcb
;
struct
dyn_lease_addr
leasearr
[
LWIP_DHCPS_MAX_LEASE
];
u8_t
pcb_allocated
;
u8_t
lease_num
;
struct
netif
*
netif
;
ip4_addr_t
start_addr
;
ip4_addr_t
end_addr
;
};
#endif // (LWIP_DHCP) && (LWIP_DHCPS)
#endif // LITEOS_A_DHCPS_FIXME_H
net/lwip-2.1/enhancement/include/api_shell.h
→
net/lwip-2.1/enhancement/include/
lwip/
api_shell.h
浏览文件 @
4f55f678
...
@@ -29,8 +29,8 @@
...
@@ -29,8 +29,8 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
*/
#ifndef LWIP_API_SHELL_H
#ifndef LWIP_
HDR_
API_SHELL_H
#define LWIP_API_SHELL_H
#define LWIP_
HDR_
API_SHELL_H
#include "arch/cc.h"
#include "arch/cc.h"
#include "lwip/opt.h"
#include "lwip/opt.h"
...
@@ -58,6 +58,4 @@ void netstat_internal(void *ctx);
...
@@ -58,6 +58,4 @@ void netstat_internal(void *ctx);
}
}
#endif
#endif
#endif
/* LWIP_HDR_API_SHELL_H */
#endif
net/lwip-2.1/enhancement/include/dhcps.h
→
net/lwip-2.1/enhancement/include/
lwip/
dhcps.h
浏览文件 @
4f55f678
...
@@ -63,16 +63,6 @@ extern "C" {
...
@@ -63,16 +63,6 @@ extern "C" {
err_t
dhcps_start
(
struct
netif
*
netif
,
const
char
*
start_ip
,
u16_t
ip_num
);
err_t
dhcps_start
(
struct
netif
*
netif
,
const
char
*
start_ip
,
u16_t
ip_num
);
void
dhcps_stop
(
struct
netif
*
netif
);
void
dhcps_stop
(
struct
netif
*
netif
);
void
dhcp_common_option
(
struct
dhcp_msg
*
msg_out
,
u8_t
option_type
,
u8_t
option_len
,
u16_t
*
options_out_len
);
void
dhcp_common_option_byte
(
struct
dhcp_msg
*
msg_out
,
u8_t
value
,
u16_t
*
options_out_len
);
void
dhcp_common_option_short
(
struct
dhcp_msg
*
msg_out
,
u16_t
value
,
u16_t
*
options_out_len
);
void
dhcp_common_option_long
(
struct
dhcp_msg
*
msg_out
,
u32_t
value
,
u16_t
*
options_out_len
);
void
dhcp_common_option_trailer
(
struct
dhcp_msg
*
msg_out
,
u16_t
*
options_out_len
);
#if LWIP_DHCP_BOOTP_FILE
err_t
dhcps_parse_options
(
struct
pbuf
*
p
,
char
*
boot_file_name
);
#else
err_t
dhcps_parse_options
(
struct
pbuf
*
p
);
#endif
#if defined (__cplusplus) && __cplusplus
#if defined (__cplusplus) && __cplusplus
}
}
...
...
net/lwip-2.1/enhancement/include/
api_shell_fix
.h
→
net/lwip-2.1/enhancement/include/
lwip/fixme
.h
浏览文件 @
4f55f678
...
@@ -29,17 +29,12 @@
...
@@ -29,17 +29,12 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
*/
#ifndef LITEOS_A_FIXME_H
#ifndef LWIP_HDR_FIXME_H
#define LITEOS_A_FIXME_H
#define LWIP_HDR_FIXME_H
#define LWIP_ENABLE_LOS_SHELL_CMD 1
#define LWIP_ENABLE_IP_CONFLICT_SIGNAL 0
#define PF_PKT_SUPPORT 1
#define NETCONN_PKT_RAW 0x80
#include "lwip/opt.h"
#include "lwip/opt.h"
#include "netif/etharp.h"
#i
f LWIP_ENABLE_LOS_SHELL_CMD
#i
nclude "lwip/netif.h"
#define link_rx_drop cachehit
#define link_rx_drop cachehit
#define link_tx_drop cachehit
#define link_tx_drop cachehit
...
@@ -51,61 +46,56 @@
...
@@ -51,61 +46,56 @@
#define ip_rx_bytes cachehit
#define ip_rx_bytes cachehit
#define ip_tx_bytes cachehit
#define ip_tx_bytes cachehit
#define LWIP_STATIC static
#define DUP_ARP_DETECT_TIME 2000
/* 2 seconds period */
#define SYS_ARCH_ERROR SYS_ARCH_TIMEOUT
#define SOF_BINDNONUNICAST 0x0800U
/* socket has bind to a non unicast */
#define NETCONN_PKT_RAW 0x80
#include "netif/etharp.h"
#define SYS_ARCH_ERROR SYS_ARCH_TIMEOUT
#include "lwip/netif.h"
#define LWIP_SHELL_CMD_PING_RETRY_TIMES 4
#define LWIP_ENABLE_LOS_SHELL_CMD LOSCFG_SHELL
#define LWIP_SHELL_CMD_PING_RETRY_TIMES 4
#define LWIP_SHELL_CMD_PING_TIMEOUT 2000
#define LWIP_SHELL_CMD_PING_TIMEOUT 2000
#define LWIP_MAX_UDP_RAW_SEND_SIZE 65332
#define LWIP_EXT_POLL_SUPPORT LWIP_SOCKET_POLL
#define TRANSFER_MODE_BINARY 1
#define ip_addr_set_val(dest, src) do { \
IP_SET_TYPE_VAL(*dest, IP_GET_TYPE(src)); \
u32_t
lwip_tftp_get_file_by_filename
(
u32_t
ulHostAddr
,
if(IP_IS_V6_VAL(*(src))) { \
u16_t
usTftpServPort
,
ip6_addr_set(ip_2_ip6(dest), ip_2_ip6(src)); \
u8_t
ucTftpTransMode
,
} else { \
s8_t
*
szSrcFileName
,
ip4_addr_set(ip_2_ip4(dest), ip_2_ip4(src)); \
s8_t
*
szDestDirPath
);
} \
} while (0)
u32_t
lwip_tftp_put_file_by_filename
(
u32_t
ulHostAddr
,
u16_t
usTftpServPort
,
u8_t
cTftpTransMode
,
s8_t
*
szSrcFileName
,
s8_t
*
szDestDirPath
);
#define ip_addr_set_val(dest, src) do { IP_SET_TYPE_VAL(*dest, IP_GET_TYPE(src)); if(IP_IS_V6_VAL(*(src))) { \
ip6_addr_set(ip_2_ip6(dest), ip_2_ip6(src)); } else { \
ip4_addr_set(ip_2_ip4(dest), ip_2_ip4(src)); }} while (0)
#define ip_addr_ismulticast_val(ipaddr) ((IP_IS_V6_VAL(*ipaddr)) ? \
#define ip_addr_ismulticast_val(ipaddr) ((IP_IS_V6_VAL(*ipaddr)) ? \
ip6_addr_ismulticast(ip_2_ip6(ipaddr)) : \
ip6_addr_ismulticast(ip_2_ip6(ipaddr)) : \
ip4_addr_ismulticast(ip_2_ip4(ipaddr)))
ip4_addr_ismulticast(ip_2_ip4(ipaddr)))
#define ip_addr_isbroadcast_val(ipaddr, netif) ((IP_IS_V6_VAL(*ipaddr)) ? \
#define ip_addr_isbroadcast_val(ipaddr, netif) ((IP_IS_V6_VAL(*ipaddr)) ? \
0 : \
0 : \
ip4_addr_isbroadcast(ip_2_ip4(ipaddr), netif))
ip4_addr_isbroadcast(ip_2_ip4(ipaddr), netif))
#define ip_addr_netcmp_val(addr1, addr2, mask) ((IP_IS_V6_VAL(*(addr1)) && IP_IS_V6_VAL(*(addr2))) ? \
#define ip_addr_netcmp_val(addr1, addr2, mask) ((IP_IS_V6_VAL(*(addr1)) && IP_IS_V6_VAL(*(addr2))) ? \
0 : \
0 : \
ip4_addr_netcmp(ip_2_ip4(addr1), ip_2_ip4(addr2), mask))
ip4_addr_netcmp(ip_2_ip4(addr1), ip_2_ip4(addr2), mask))
#if LWIP_DHCP
#define ip6_addr_isnone_val(ip6addr) (((ip6addr).addr[0] == 0xffffffffUL) && \
((ip6addr).addr[1] == 0xffffffffUL) && \
((ip6addr).addr[2] == 0xffffffffUL) && \
((ip6addr).addr[3] == 0xffffffffUL))
/*
#define ip6_addr_isnone(ip6addr) (((ip6addr) == NULL) || ip6_addr_isnone_val(*(ip6addr)))
* Close DHCP and set static network.
*
#define ipaddr_ntoa_unsafe(addr) ((IP_IS_V6_VAL(*addr)) ? ip6addr_ntoa(ip_2_ip6(addr)) : ip4addr_ntoa(ip_2_ip4(addr)))
* @param netif a pre-allocated netif structure
*
* @return ERR_OK, or ERR_VAL if failed.
*/
err_t
netif_dhcp_off
(
struct
netif
*
netif
);
#endif
/* LWIP_DHCP */
#ifdef ip6_addr_cmp
#undef ip6_addr_cmp
#define ip6_addr_cmp(addr1, addr2) (((addr1)->addr[0] == (addr2)->addr[0]) && \
((addr1)->addr[1] == (addr2)->addr[1]) && \
((addr1)->addr[2] == (addr2)->addr[2]) && \
((addr1)->addr[3] == (addr2)->addr[3]))
#endif
#include "lwip/prot/dhcp.h"
err_t
netif_dhcp_off
(
struct
netif
*
netif
);
err_t
netif_do_rmv_ipv6_addr
(
struct
netif
*
netif
,
void
*
arguments
);
err_t
netif_do_rmv_ipv6_addr
(
struct
netif
*
netif
,
void
*
arguments
);
...
@@ -113,49 +103,20 @@ err_t netif_set_mtu(struct netif *netif, u16_t netif_mtu);
...
@@ -113,49 +103,20 @@ err_t netif_set_mtu(struct netif *netif, u16_t netif_mtu);
err_t
netif_set_hwaddr
(
struct
netif
*
netif
,
const
unsigned
char
*
hw_addr
,
int
hw_len
);
err_t
netif_set_hwaddr
(
struct
netif
*
netif
,
const
unsigned
char
*
hw_addr
,
int
hw_len
);
struct
netif
*
netifapi_netif_find_by_name
(
const
char
*
name
);
/* 2 seconds period */
#define DUP_ARP_DETECT_TIME 2000
err_t
etharp_update_arp_entry
(
struct
netif
*
netif
,
const
ip4_addr_t
*
ipaddr
,
struct
eth_addr
*
ethaddr
,
u8_t
flags
);
err_t
etharp_update_arp_entry
(
struct
netif
*
netif
,
const
ip4_addr_t
*
ipaddr
,
struct
eth_addr
*
ethaddr
,
u8_t
flags
);
err_t
etharp_delete_arp_entry
(
struct
netif
*
netif
,
ip4_addr_t
*
ipaddr
);
err_t
etharp_delete_arp_entry
(
struct
netif
*
netif
,
ip4_addr_t
*
ipaddr
);
#define LWIP_MAX_UDP_RAW_SEND_SIZE 65332
#define ip6_addr_isnone_val(ip6addr) (((ip6addr).addr[0] == 0xffffffffUL) && \
((ip6addr).addr[1] == 0xffffffffUL) && \
((ip6addr).addr[2] == 0xffffffffUL) && \
((ip6addr).addr[3] == 0xffffffffUL))
#define ip6_addr_isnone(ip6addr) (((ip6addr) == NULL) || ip6_addr_isnone_val(*(ip6addr)))
err_t
lwip_dns_setserver
(
u8_t
numdns
,
ip_addr_t
*
dnsserver
);
err_t
lwip_dns_setserver
(
u8_t
numdns
,
ip_addr_t
*
dnsserver
);
err_t
lwip_dns_getserver
(
u8_t
numdns
,
ip_addr_t
*
dnsserver
);
err_t
lwip_dns_getserver
(
u8_t
numdns
,
ip_addr_t
*
dnsserver
);
#define ipaddr_ntoa_unsafe(addr) ((IP_IS_V6_VAL(*addr)) ? ip6addr_ntoa(ip_2_ip6(addr)) : ip4addr_ntoa(ip_2_ip4(addr)))
#define SOF_BINDNONUNICAST 0x0800U
/* socket has bind to a non unicast */
#if PF_PKT_SUPPORT
#if PF_PKT_SUPPORT
extern
struct
raw_pcb
*
pkt_raw_pcbs
;
extern
struct
raw_pcb
*
pkt_raw_pcbs
;
#endif
#endif
#if LWIP_RAW
extern
struct
raw_pcb
*
raw_pcbs
;
extern
struct
raw_pcb
*
raw_pcbs
;
#endif
#ifdef ip6_addr_cmp
#endif
/* LWIP_HDR_FIXME_H */
#undef ip6_addr_cmp
#define ip6_addr_cmp(addr1, addr2) (((addr1)->addr[0] == (addr2)->addr[0]) && \
((addr1)->addr[1] == (addr2)->addr[1]) && \
((addr1)->addr[2] == (addr2)->addr[2]) && \
((addr1)->addr[3] == (addr2)->addr[3]))
#endif //ip6_addr_cmp
#define LWIP_EXT_POLL_SUPPORT LWIP_SOCKET_POLL
#endif //LWIP_ENABLE_LOS_SHELL_CMD
#endif //LITEOS_A_FIXME_H
net/lwip-2.1/enhancement/include/lwip/tftpc.h
0 → 100644
浏览文件 @
4f55f678
/*
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef LWIP_HDR_TFTPC_H
#define LWIP_HDR_TFTPC_H
#include "lwip/opt.h"
#include "lwip/sockets.h"
#if LWIP_TFTP
/* don't build if not configured for use in lwipopts.h */
#if defined (__cplusplus) && __cplusplus
extern
"C"
{
#endif
#define TFTP_NULL_UINT32 ((u32_t)0xffffffffUL)
#define TFTP_NULL_INT32 -1
/** @cond liteos
* @defgroup TFTP_Interfaces
* @ingroup Enums
* * This section contains the TFTP enums.
*/
/**
*
* This Enum is used to specify the transfer mode of the file to be handled by TFTP client.
*/
typedef
enum
tagTFTPC_TransferMode
{
TRANSFER_MODE_ASCII
=
0
,
/**< Indicates that the mode of transfer is ASCII. */
TRANSFER_MODE_BINARY
,
/**< Indicates that the mode of transfer is Binary */
TRANSFER_MODE_BUTT
/**< Indicates invalid transfer mode.*/
}
TFTPC_TRANSFER_MODE_E
;
/**
* This Enum is used to specify the transfer mode to be handled by TFTP client
* This Enum indicates the TFTP client transfer mode of the file
*/
typedef
enum
tagTFTPC_ErrCode
{
TFTPC_SOCKET_FAILURE
=
1
,
/**< Error while creating UDP socket. */
TFTPC_BIND_FAILURE
=
2
,
/**< Error while binding to the UDP socket. */
TFTPC_SELECT_ERROR
=
3
,
/**< Error returned by select() system call. */
TFTPC_RECVFROM_ERROR
=
4
,
/**< Error while receiving data from the peer. */
TFTPC_SENDTO_ERROR
=
5
,
/**< Error while sending data to the peer. */
TFTPC_FILE_NOT_FOUND
=
6
,
/**< Requested file is not found. */
/**< This is the error sent by the server when host name cannot be resolved. */
TFTPC_CANNOT_RESOLVE_HOSTNAME
=
7
,
TFTPC_INVALID_PARAVALUE
=
8
,
/**< Input parameters passed to TFTP interfaces are invalid. */
/**< Error detected in TFTP packet or the error received from the TFTP server. */
TFTPC_PROTO_ERROR
=
9
,
/**< Error during packet synchronization while sending or unexpected packet is received. */
TFTPC_SYNC_FAILURE
=
10
,
/**< File size limit crossed, Max block can be 0xFFFF, each block containing 512 bytes. */
TFTPC_FILE_TOO_BIG
=
11
,
TFTPC_SRC_FILENAME_LENGTH_ERROR
=
12
,
/**< File name length greater than 256. */
TFTPC_IP_NOT_WITHIN_RANGE
=
13
,
/**< Host name IP is not valid. */
TFTPC_ACCESS_ERROR
=
14
,
/**< TFTP server returned file access error. */
/**< TFTP server returned error signifying that the DISK is full to write. */
TFTPC_DISK_FULL
=
15
,
TFTPC_FILE_EXISTS
=
16
,
/**< TFTP server returned error signifying that the file exists. */
/**< tftp_put_file_by_filename returned error signifying that the source file name do not exist. */
TFTPC_FILE_NOT_EXIST
=
17
,
TFTPC_MEMALLOC_ERROR
=
18
,
/**< Memory allocation failed in TFTP client. */
TFTPC_FILEOPEN_ERROR
=
19
,
/**< File open failed. */
TFTPC_FILEREAD_ERROR
=
20
,
/**< File read error. */
TFTPC_FILECREATE_ERROR
=
21
,
/**< File create error. */
TFTPC_FILEWRITE_ERROR
=
22
,
/**< File write error. */
TFTPC_TIMEOUT_ERROR
=
23
,
/**< Max time expired while waiting for file to be received. */
/**< Error when the received packet is less than 4 bytes (error length) or greater than 512 bytes. */
TFTPC_PKT_SIZE_ERROR
=
24
,
TFTPC_ERROR_NOT_DEFINED
=
25
,
/**< Returned by TFTP server for protocol user error. */
TFTPC_DEST_PATH_LENGTH_ERROR
=
26
,
/**< If the destination file path length is greater than 256. */
TFTPC_UNKNOWN_TRANSFER_ID
=
27
,
/**< Returned by TFTP server for undefined transfer ID. */
/**< IOCTL function failed at TFTP client while setting the socket to non-block. */
TFTPC_IOCTLSOCKET_FAILURE
=
28
,
TFTPC_MEMCPY_FAILURE
=
29
/**< TFTP memcpy failure. */
}
TFTPC_ERR_CODE_E
;
typedef
enum
tagTFTPC_OpCode
{
TFTPC_OP_RRQ
=
1
,
/* read request */
TFTPC_OP_WRQ
,
/* write request */
TFTPC_OP_DATA
,
/* data packet */
TFTPC_OP_ACK
,
/* acknowledgement */
TFTPC_OP_ERROR
,
/* error code */
TFTPC_OP_OPT
/* option code */
}
TFTPC_OPCODE_E
;
typedef
enum
tagTFTPC_PROTOCOL_ErrCode
{
TFTPC_PROTOCOL_USER_DEFINED
=
0
,
TFTPC_PROTOCOL_FILE_NOT_FOUND
,
TFTPC_PROTOCOL_ACCESS_ERROR
,
TFTPC_PROTOCOL_DISK_FULL
,
TFTPC_PROTOCOL_PROTO_ERROR
,
TFTPC_PROTOCOL_UNKNOWN_TRANSFER_ID
,
TFTPC_PROTOCOL_FILE_EXISTS
,
TFTPC_PROTOCOL_CANNOT_RESOLVE_HOSTNAME
}
TFTPC_PROT_ERRCODE_E
;
#ifndef TFTPC_MAX_SEND_REQ_ATTEMPTS
#define TFTPC_MAX_SEND_REQ_ATTEMPTS 5
/* tftp max attempts */
#endif
#ifndef TFTPC_TIMEOUT_PERIOD
#define TFTPC_TIMEOUT_PERIOD 5
/* tftp timeout period,unit :s */
#endif
#define TFTPC_SERVER_PORT 69
/* tftp server well known port no. */
/* MAX file size in TFTP is 32 MB.
Reason for keeping 75 here , is ((75*512=38400bytes)/1024) = 37MB. So the recv/Send Loop can
receive the complete MAX message from the network
*/
#define TFTPC_MAX_WAIT_IN_LOOP 75
#define TFTP_BLKSIZE 512
/* data block size (IEN-133) */
#define TFTP_HDRSIZE 4
/* TFTP header size */
#define TFTP_PKTSIZE (TFTP_BLKSIZE + TFTP_HDRSIZE)
/* Packet size */
#define TFTP_MAX_MODE_SIZE 9
/* max size of mode string */
#define TFTP_MAXERRSTRSIZE 100
/* max size of error message string */
#define TFTP_MAX_PATH_LENGTH 256
/* Max path or filename length */
#define TFTP_MAX_BLK_NUM (0xFFFFL)
/* MAximum block number */
/* IP address not including reserved IPs(0 and 127) and multicast addresses(Class D) */
#define TFTPC_IP_ADDR_MIN 0x01000000
#define TFTPC_IP_ADDR_EX_RESV 0x7effffff
#define TFTPC_IP_ADDR_CLASS_B 0x80000000
#define TFTPC_IP_ADDR_EX_CLASS_DE 0xdfffffff
#define TFTPC_FOUR 4
/* minimum packet size */
/****************************************************************************/
/* Structure definitions */
/****************************************************************************/
/* Tftp data packet */
typedef
struct
tagTFTPC_DATA
{
u16_t
usBlknum
;
/* block number */
u8_t
ucDataBuf
[
TFTP_BLKSIZE
];
/* Actual data */
}
TFTPC_DATA_S
;
/* TFTP error packet */
typedef
struct
tagTFTPC_ERROR
{
u16_t
usErrNum
;
/* error number */
u8_t
ucErrMesg
[
TFTP_MAXERRSTRSIZE
];
/* error message */
}
TFTPC_ERROR_S
;
/* TFTP packet format */
typedef
struct
tagTFTPC_PACKET
{
u16_t
usOpcode
;
/* Opcode value */
union
{
/* it contains mode and filename */
s8_t
ucName_Mode
[
TFTP_MAX_PATH_LENGTH
+
TFTP_MAX_MODE_SIZE
];
u16_t
usBlknum
;
/* Block Number */
TFTPC_DATA_S
stTFTP_Data
;
/* Data Packet */
TFTPC_ERROR_S
stTFTP_Err
;
/* Error Packet */
}
u
;
}
TFTPC_PACKET_S
;
/** @defgroup TFTP_Interfaces
* This section contains the TFTP Interfaces
*/
/*
Func Name: lwip_tftp_get_file_by_filename
*/
/**
* @ingroup TFTP_Interfaces
* @brief
* This API gets the source file from the server. It then stores the received file in the destination path
* on the client system.
*
* @param[in] ulHostAddr IP address of Host. This is the TFTP server IP. [NA]
* @param[in] usTftpServPort TFTP server port. If the value is passed as 0 then the default TFTP
* PORT 69 is used. [NA]
* @param[in] ucTftpTransMode File transfer mode, either TRANSFER_MODE_BINARY or TRANSFER_MODE_ASCII. [NA]
* @param[in] szSrcFileName Source file in the tftp server. [NA]
* @param[in] szDestDirPath Destination file path in the in the client. [NA]
* @param[out] [N/A]
*
* @return
* ERR_OK: On success \n
* TFTPC_ERR_CODE_E: On failure
*
* @note
* \n
* The behavior of this API is such that if the destination file already exists, it will be overwritten.
*/
u32_t
lwip_tftp_get_file_by_filename
(
u32_t
ulHostAddr
,
u16_t
usTftpServPort
,
u8_t
ucTftpTransMode
,
s8_t
*
szSrcFileName
,
s8_t
*
szDestDirPath
);
/* @defgroup TFTP_Interfaces
* This section contains the TFTP Interfaces
*/
/*
Func Name: lwip_tftp_put_file_by_filename
*/
/**
* @ingroup TFTP_Interfaces
* @brief
* This API reads the contents of the source file on the client system and sends it to the server and
* server then receives the data and stores it in the specified destination path.
*
* @param[in] ulHostAddr Indicates the IP address of Host. This is the TFTP server IP.
* @param[in] usTftpServPort Indicates the TFTP server port. If the value is passed as 0 then the default TFTP
* PORT 69 is used.
* @param[in] ucTftpTransMode Indicates the file transfer mode, either TRANSFER_MODE_BINARY or TRANSFER_MODE_ASCII.
* @param[in] szSrcFileName Indicates the source file in the client.
* @param[in] szDestDirPath Indicates the destination file path on the tftp server.
*
* @return
* ERR_OK: On success \n
* TFTPC_ERR_CODE_E: On failure
*
*/
u32_t
lwip_tftp_put_file_by_filename
(
u32_t
ulHostAddr
,
u16_t
usTftpServPort
,
u8_t
cTftpTransMode
,
s8_t
*
szSrcFileName
,
s8_t
*
szDestDirPath
);
#ifdef TFTP_TO_RAWMEM
/* @defgroup TFTP_Interfaces
* This section contains the TFTP Interfaces
*/
/*
Func Name: lwip_tftp_get_file_by_filename_to_rawmem
*/
/**
* @ingroup TFTP_Interfaces
* @brief
* This API gets the source file from the server. It then stores the received file in the target memory
* on the client system.
*
* @param[in] ulHostAddr Indicates the IP address of the Host. This is the TFTP server IP.
* @param[in] usTftpServPort Indicates the TFTP server port. If the value is passed as 0 then the default TFTP
* PORT 69 is used.
* @param[in] ucTftpTransMode Indicates the File transfer mode, either TRANSFER_MODE_BINARY or TRANSFER_MODE_ASCII.
* @param[in] szSrcFileName Indicates the Source file in the TFTP server.
* @param[in] szDestMemAddr Indicates the target memory address in the client.
* @param[in/out] ulFileLength Indicates the target memory address can cache the size of the content,
and The real size of the Source file.
*
* @return
* ERR_OK: On success \n
* TFTPC_ERR_CODE_E: On failure
* @note
* 1.You must define TFTP_TO_RAWMEM when using this API. \n
* 2.The behavior of this API is such that if the destination file already exists, it will be overwritten.
* @endcond
*/
u32_t
lwip_tftp_get_file_by_filename_to_rawmem
(
u32_t
ulHostAddr
,
u16_t
usTftpServPort
,
u8_t
ucTftpTransMode
,
s8_t
*
szSrcFileName
,
s8_t
*
szDestMemAddr
,
u32_t
*
ulFileLength
);
#endif
#if defined (__cplusplus) && __cplusplus
}
#endif
#endif
/* LWIP_TFTP */
#endif
/* LWIP_HDR_TFTPC_H */
net/lwip-2.1/enhancement/src/api_shell.c
浏览文件 @
4f55f678
...
@@ -33,7 +33,7 @@
...
@@ -33,7 +33,7 @@
#define icmp6_hdr netinet_icmp6_hdr
#define icmp6_hdr netinet_icmp6_hdr
#include <netinet/icmp6.h>
#include <netinet/icmp6.h>
#undef icmp6_hdr
#undef icmp6_hdr
#include "
api_shell_fix
.h"
#include "
lwip/fixme
.h"
#include "lwip/opt.h"
#include "lwip/opt.h"
#if LWIP_ENABLE_LOS_SHELL_CMD
#if LWIP_ENABLE_LOS_SHELL_CMD
...
@@ -62,7 +62,8 @@
...
@@ -62,7 +62,8 @@
#include <ctype.h>
#include <ctype.h>
#include <poll.h>
#include <poll.h>
#include "api_shell.h"
#include "lwip/api_shell.h"
#include "lwip/tftpc.h"
#include "lwip/dns.h"
#include "lwip/dns.h"
#include "lwip/netdb.h"
#include "lwip/netdb.h"
...
@@ -78,7 +79,7 @@
...
@@ -78,7 +79,7 @@
#include "shell.h"
#include "shell.h"
#endif
#endif
#define
netif_find netifapi_netif_find_by_name
#define
LWIP_STATIC static
#if LWIP_ARP
#if LWIP_ARP
extern
sys_sem_t
ip_conflict_detect
;
extern
sys_sem_t
ip_conflict_detect
;
...
@@ -3163,8 +3164,10 @@ void netstat_internal(void *ctx)
...
@@ -3163,8 +3164,10 @@ void netstat_internal(void *ctx)
int
recvQlen
=
0
;
int
recvQlen
=
0
;
int
sendQlen
=
0
;
int
sendQlen
=
0
;
u_int
proto
;
u_int
proto
;
#if PF_PKT_SUPPORT
u8_t
netif_name
[
IFNAMSIZ
];
u8_t
netif_name
[
IFNAMSIZ
];
struct
netif
*
netif
=
NULL
;
struct
netif
*
netif
=
NULL
;
#endif
if
(
ndata
==
NULL
)
{
if
(
ndata
==
NULL
)
{
return
;
return
;
...
...
net/lwip-2.1/enhancement/src/dhcps.c
0 → 100644
浏览文件 @
4f55f678
/*
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* Dynamic Host Configuration Protocol Server
*
*/
#include "../core/ipv4/dhcp.c"
/* for enum dhcp_option_idx/dhcp_option_xx/dhcp_parse_reply etc. */
#include "lwip/opt.h"
#if (LWIP_DHCP) && (LWIP_DHCPS)
/* don't build if not configured for use in lwipopts.h */
#include <string.h>
#include "lwip/stats.h"
#include "lwip/mem.h"
#include "lwip/udp.h"
#include "lwip/ip_addr.h"
#include "lwip/netif.h"
#include "lwip/def.h"
#include "lwip/prot/dhcp.h"
#include "lwip/dhcp.h"
#include "lwip/dhcps.h"
#include "lwip/sys.h"
#include "netif/etharp.h"
#define DHCPS_ADDRESS_FREE 0x0
#define DHCPS_ADDRESS_OFFERRED 0x1
#define DHCPS_ADDRESS_BOUND 0x2
#define DHCPS_ADDRESS_DECLINED 0x3
#define LWIP_STATIC static
#define DHCP_OPTION_ROUTER_SIZE 4
#define DHCP_OPTION_SUBNET_MASK_SIZE 4
#define DHCP_OPTION_LEASE_TIME_SIZE 4
#define DHCP_OPTION_SERVER_ID_LEN 4
#define DHCP_OPTION_T1_LEN 4
#define DHCP_OPTION_T2_LEN 4
#define DHCP_CLIENT_PORT 68
#define DHCP_SERVER_PORT 67
#define DHCP_BROADCAST_FLAG 0x8000
struct
dyn_lease_addr
{
u8_t
cli_hwaddr
[
DHCP_CHADDR_LEN
];
u32_t
flags
;
u32_t
leasetime
;
u32_t
proposed_leasetime
;
ip4_addr_t
cli_addr
;
};
struct
dhcps
{
struct
dhcp
dhcp
;
struct
udp_pcb
*
pcb
;
struct
dyn_lease_addr
leasearr
[
LWIP_DHCPS_MAX_LEASE
];
u8_t
pcb_allocated
;
u8_t
lease_num
;
struct
netif
*
netif
;
ip4_addr_t
start_addr
;
ip4_addr_t
end_addr
;
};
#define dhcps_option_given(dhcps, idx) dhcp_option_given(&(dhcps)->dhcp, idx)
#define dhcps_got_option(dhcps, idx) dhcp_got_option(&(dhcps)->dhcp, idx)
#define dhcps_clear_option(dhcps, idx) dhcp_clear_option(&(dhcps)->dhcp, idx)
#define dhcps_clear_all_options(dhcps) dhcp_clear_all_options(&(dhcps)->dhcp)
#define dhcps_get_option_value(dhcps, idx) dhcp_get_option_value(&(dhcps)->dhcp, idx)
#define dhcps_set_option_value(dhcps, idx, val) dhcp_set_option_value(&(dhcps)->dhcp, idx, val)
#define netif_get_dhcps(netif) ((struct dhcps*)netif_get_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_DHCPS))
#define netif_set_dhcps(netif, dhcps) netif_set_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_DHCPS, dhcps)
LWIP_STATIC
void
dhcp_common_option
(
struct
dhcp_msg
*
msg_out
,
u8_t
option_type
,
u8_t
option_len
,
u16_t
*
options_out_len
);
LWIP_STATIC
void
dhcp_common_option_byte
(
struct
dhcp_msg
*
msg_out
,
u8_t
value
,
u16_t
*
options_out_len
);
LWIP_STATIC
void
dhcp_common_option_long
(
struct
dhcp_msg
*
msg_out
,
u32_t
value
,
u16_t
*
options_out_len
);
LWIP_STATIC
void
dhcp_common_option_trailer
(
struct
dhcp_msg
*
msg_out
,
u16_t
options_out_len
,
struct
pbuf
*
p_out
);
LWIP_STATIC
err_t
dhcps_parse_options
(
struct
pbuf
*
p
,
struct
dhcps
*
dhcps
);
LWIP_STATIC
struct
pbuf
*
dhcps_create_base_msg
(
struct
dhcp_msg
*
client_msg
);
LWIP_STATIC
void
remove_stale_entries
(
struct
dhcps
*
dhcps
);
LWIP_STATIC
void
add_client_entry
(
struct
dhcps
*
dhcps
,
unsigned
int
idx
,
struct
dhcp_msg
*
client_msg
);
LWIP_STATIC
int
find_free_slot
(
struct
dhcps
*
dhcps
);
LWIP_STATIC
struct
dyn_lease_addr
*
find_client_lease
(
struct
dhcps
*
dhcps
,
struct
dhcp_msg
*
client_msg
);
LWIP_STATIC
ip4_addr_t
validate_discover
(
struct
dhcps
*
dhcps
,
struct
dhcp_msg
*
client_msg
,
struct
dyn_lease_addr
**
client_lease
);
LWIP_STATIC
void
handle_discover
(
struct
netif
*
netif
,
struct
dhcps
*
dhcps
,
struct
dhcp_msg
*
client_msg
,
struct
dyn_lease_addr
*
client_lease
);
LWIP_STATIC
ip4_addr_t
validate_request_message
(
struct
netif
*
netif
,
struct
dhcp_msg
*
client_msg
,
struct
dyn_lease_addr
*
client_lease
,
ip4_addr_t
serverid
);
LWIP_STATIC
void
handle_request
(
struct
netif
*
netif
,
struct
dhcps
*
dhcps
,
struct
dhcp_msg
*
client_msg
,
struct
dyn_lease_addr
*
client_lease
,
ip4_addr_t
serverid
);
LWIP_STATIC
void
handle_decline
(
struct
netif
*
netif
,
struct
dhcps
*
dhcps
,
struct
dhcp_msg
*
client_msg
,
struct
dyn_lease_addr
*
client_lease
);
LWIP_STATIC
void
handle_inform
(
struct
netif
*
netif
,
struct
dhcps
*
dhcps
,
struct
dhcp_msg
*
client_msg
);
LWIP_STATIC
void
handle_client_messages
(
struct
netif
*
netif
,
struct
dhcps
*
dhcps
,
struct
dhcp_msg
*
client_msg
,
ip4_addr_t
serverid
,
u8_t
msg_type
);
LWIP_STATIC
void
dhcps_recv
(
void
*
arg
,
struct
udp_pcb
*
pcb
,
struct
pbuf
*
p
,
const
ip_addr_t
*
ip_addr
,
u16_t
port
);
LWIP_STATIC
struct
pbuf
*
dhcps_create_base_msg
(
struct
dhcp_msg
*
client_msg
)
{
struct
pbuf
*
srvr_msg_pbuf
=
NULL
;
struct
dhcp_msg
*
srvr_msg
=
NULL
;
srvr_msg_pbuf
=
pbuf_alloc
(
PBUF_TRANSPORT
,
sizeof
(
struct
dhcp_msg
),
PBUF_RAM
);
if
(
srvr_msg_pbuf
==
NULL
)
{
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
|
LWIP_DBG_LEVEL_SERIOUS
,
(
"dhcps_create_base_msg(): could not allocate pbuf
\n
"
));
return
NULL
;
}
LWIP_ASSERT
(
"dhcps_create_base_msg: check that first pbuf can hold struct dhcp_msg"
,
(
srvr_msg_pbuf
->
len
>=
sizeof
(
struct
dhcp_msg
)));
#if DRIVER_STATUS_CHECK
srvr_msg_pbuf
->
flags
|=
PBUF_FLAG_DHCP_BUF
;
#endif
srvr_msg
=
(
struct
dhcp_msg
*
)
srvr_msg_pbuf
->
payload
;
srvr_msg
->
op
=
DHCP_BOOTREPLY
;
srvr_msg
->
htype
=
client_msg
->
htype
;
srvr_msg
->
hlen
=
client_msg
->
hlen
;
srvr_msg
->
hops
=
0
;
srvr_msg
->
xid
=
client_msg
->
xid
;
srvr_msg
->
secs
=
0
;
srvr_msg
->
flags
=
client_msg
->
flags
;
ip4_addr_set_zero
(
&
srvr_msg
->
ciaddr
);
ip4_addr_set_zero
(
&
srvr_msg
->
yiaddr
);
ip4_addr_set_zero
(
&
srvr_msg
->
siaddr
);
ip4_addr_copy
(
srvr_msg
->
giaddr
,
client_msg
->
giaddr
);
if
(
memcpy_s
(
srvr_msg
->
chaddr
,
sizeof
(
srvr_msg
->
chaddr
),
client_msg
->
chaddr
,
DHCP_CHADDR_LEN
)
!=
EOK
)
{
(
void
)
pbuf_free
(
srvr_msg_pbuf
);
return
NULL
;
}
(
void
)
memset_s
(
srvr_msg
->
sname
,
sizeof
(
srvr_msg
->
sname
),
0
,
DHCP_SNAME_LEN
);
(
void
)
memset_s
(
srvr_msg
->
file
,
sizeof
(
srvr_msg
->
file
),
0
,
DHCP_FILE_LEN
);
srvr_msg
->
cookie
=
PP_HTONL
(
DHCP_MAGIC_COOKIE
);
return
srvr_msg_pbuf
;
}
LWIP_STATIC
void
remove_stale_entries
(
struct
dhcps
*
dhcps
)
{
int
i
=
0
;
u32_t
curr_time
=
sys_now
();
for
(
i
=
0
;
i
<
dhcps
->
lease_num
;
i
++
)
{
/* Slot should not be free or have infinite lease time */
if
((
dhcps
->
leasearr
[
i
].
flags
!=
DHCPS_ADDRESS_FREE
)
&&
(
dhcps
->
leasearr
[
i
].
leasetime
!=
(
u32_t
)
~
0
))
{
if
(
dhcps
->
leasearr
[
i
].
leasetime
<
curr_time
)
{
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
,
(
"remove_stale_entries: Removing Client Entry at Index = %"
U32_F
"
\n
"
,
i
));
(
void
)
memset_s
(
&
(
dhcps
->
leasearr
[
i
]),
sizeof
(
struct
dyn_lease_addr
),
0
,
sizeof
(
struct
dyn_lease_addr
));
dhcps
->
leasearr
[
i
].
flags
=
DHCPS_ADDRESS_FREE
;
}
}
}
}
LWIP_STATIC
void
add_client_entry
(
struct
dhcps
*
dhcps
,
unsigned
int
idx
,
struct
dhcp_msg
*
client_msg
)
{
u32_t
client_lease_time
=
(
u32_t
)(
LWIP_DHCPS_LEASE_TIME
);
if
((
dhcps_option_given
(
dhcps
,
DHCP_OPTION_IDX_LEASE_TIME
))
#if (LWIP_DHCPS_LEASE_TIME != ~0)
&&
(
dhcps_get_option_value
(
dhcps
,
DHCP_OPTION_IDX_LEASE_TIME
)
<
LWIP_DHCPS_LEASE_TIME
)
#endif
)
{
client_lease_time
=
(
u32_t
)
dhcps_get_option_value
(
dhcps
,
DHCP_OPTION_IDX_LEASE_TIME
);
}
(
void
)
memset_s
(
&
(
dhcps
->
leasearr
[
idx
]),
sizeof
(
struct
dyn_lease_addr
),
0
,
sizeof
(
struct
dyn_lease_addr
));
if
(
memcpy_s
(
dhcps
->
leasearr
[
idx
].
cli_hwaddr
,
DHCP_CHADDR_LEN
,
client_msg
->
chaddr
,
sizeof
(
client_msg
->
chaddr
))
!=
EOK
)
{
return
;
}
/* This is called only during offer message, so adding offer time.
This is later updated to lease time when request message is handled */
dhcps
->
leasearr
[
idx
].
leasetime
=
sys_now
()
+
(
LWIP_DHCPS_OFFER_TIME
*
1000
);
dhcps
->
leasearr
[
idx
].
cli_addr
.
addr
=
dhcps
->
start_addr
.
addr
+
idx
;
dhcps
->
leasearr
[
idx
].
flags
=
DHCPS_ADDRESS_OFFERRED
;
dhcps
->
leasearr
[
idx
].
proposed_leasetime
=
client_lease_time
;
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
,
(
"add_client_entry: Adding Client Entry at Index = %"
U32_F
"
\n
"
,
idx
));
}
LWIP_STATIC
int
find_free_slot
(
struct
dhcps
*
dhcps
)
{
int
i
;
for
(
i
=
0
;
i
<
dhcps
->
lease_num
;
i
++
)
{
if
((
dhcps
->
leasearr
[
i
].
flags
==
DHCPS_ADDRESS_FREE
)
&&
(
htonl
(
dhcps
->
start_addr
.
addr
+
(
u32_t
)
i
)
!=
ip_2_ip4
(
&
dhcps
->
netif
->
ip_addr
)
->
addr
))
{
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
,
(
"find_free_slot: Found Free Slot at Index = %"
U32_F
"
\n
"
,
i
));
return
i
;
}
}
return
-
1
;
}
LWIP_STATIC
struct
dyn_lease_addr
*
find_client_lease
(
struct
dhcps
*
dhcps
,
struct
dhcp_msg
*
client_msg
)
{
int
i
;
for
(
i
=
0
;
i
<
dhcps
->
lease_num
;
i
++
)
{
if
(
dhcps
->
leasearr
[
i
].
flags
!=
DHCPS_ADDRESS_FREE
)
{
if
(
memcmp
(
dhcps
->
leasearr
[
i
].
cli_hwaddr
,
client_msg
->
chaddr
,
client_msg
->
hlen
)
==
0
)
{
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
,
(
"find_client_lease: Found Client Lease at Index = %"
U32_F
"
\n
"
,
i
));
return
&
(
dhcps
->
leasearr
[
i
]);
}
}
}
return
NULL
;
}
LWIP_STATIC
ip4_addr_t
validate_discover
(
struct
dhcps
*
dhcps
,
struct
dhcp_msg
*
client_msg
,
struct
dyn_lease_addr
**
client_lease
)
{
ip4_addr_t
client_ip
;
int
idx
=
-
1
;
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
,
(
"validate_discover: Validating Discover Message
\n
"
));
client_ip
.
addr
=
0
;
if
(
*
client_lease
==
NULL
)
{
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
,
(
"validate_discover: Existing Client Lease not Found
\n
"
));
if
(
dhcps_option_given
(
dhcps
,
DHCP_OPTION_IDX_REQUESTED_IP
))
{
client_ip
.
addr
=
(
u32_t
)
dhcps_get_option_value
(
dhcps
,
DHCP_OPTION_IDX_REQUESTED_IP
);
#ifdef LWIP_DEV_DEBUG
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
,
(
"validate_discover function: Requested IP from client = %"
U32_F
"
\n
"
,
client_ip
.
addr
));
#endif
if
((
client_ip
.
addr
>=
dhcps
->
start_addr
.
addr
)
&&
(
client_ip
.
addr
<=
dhcps
->
end_addr
.
addr
))
{
idx
=
(
int
)(
client_ip
.
addr
-
dhcps
->
start_addr
.
addr
);
if
((
dhcps
->
leasearr
[
idx
].
flags
!=
DHCPS_ADDRESS_FREE
)
||
(
ntohl
(
client_ip
.
addr
)
==
ip_2_ip4
(
&
dhcps
->
netif
->
ip_addr
)
->
addr
))
{
/* Requested IP is not available */
#ifdef LWIP_DEV_DEBUG
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
,
(
"validate_discover function: Requested IP from client = %"
U32_F
" Not available
\n
"
,
client_ip
.
addr
));
#endif
idx
=
-
1
;
}
}
}
if
(
idx
==
-
1
)
{
idx
=
find_free_slot
(
dhcps
);
if
(
idx
==
-
1
)
{
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
,
(
"validate_discover function: No Free Slot available for Storing addresses
\n
"
));
client_ip
.
addr
=
0
;
return
client_ip
;
}
client_ip
.
addr
=
dhcps
->
start_addr
.
addr
+
(
u32_t
)
idx
;
#ifdef LWIP_DEV_DEBUG
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
,
(
"validate_discover function: New IP = %"
U32_F
" is being assigned
\n
"
,
client_ip
.
addr
));
#endif
}
add_client_entry
(
dhcps
,
(
unsigned
int
)
idx
,
client_msg
);
(
*
client_lease
)
=
&
(
dhcps
->
leasearr
[
idx
]);
}
else
{
client_ip
.
addr
=
(
*
client_lease
)
->
cli_addr
.
addr
;
#ifdef LWIP_DEV_DEBUG
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
,
(
"validate_discover: Existing Client Lease Found. Existing IP =%"
U32_F
"
\n
"
,
client_ip
.
addr
));
#endif
if
((
dhcps_option_given
(
dhcps
,
DHCP_OPTION_IDX_LEASE_TIME
))
#if (~0 != LWIP_DHCPS_LEASE_TIME)
&&
(
dhcps_get_option_value
(
dhcps
,
DHCP_OPTION_IDX_LEASE_TIME
)
<
LWIP_DHCPS_LEASE_TIME
)
#endif
)
{
/* Assign the newly requested time or else use the existing lease time as-is */
(
*
client_lease
)
->
proposed_leasetime
=
(
u32_t
)
dhcps_get_option_value
(
dhcps
,
DHCP_OPTION_IDX_LEASE_TIME
);
}
}
return
client_ip
;
}
void
dhcp_common_option
(
struct
dhcp_msg
*
msg_out
,
u8_t
option_type
,
u8_t
option_len
,
u16_t
*
options_out_len
)
{
*
options_out_len
=
dhcp_option
(
*
options_out_len
,
msg_out
->
options
,
option_type
,
option_len
);
}
void
dhcp_common_option_byte
(
struct
dhcp_msg
*
msg_out
,
u8_t
value
,
u16_t
*
options_out_len
)
{
*
options_out_len
=
dhcp_option_byte
(
*
options_out_len
,
msg_out
->
options
,
value
);
}
void
dhcp_common_option_long
(
struct
dhcp_msg
*
msg_out
,
u32_t
value
,
u16_t
*
options_out_len
)
{
*
options_out_len
=
dhcp_option_long
(
*
options_out_len
,
msg_out
->
options
,
value
);
}
void
dhcp_common_option_trailer
(
struct
dhcp_msg
*
msg_out
,
u16_t
options_out_len
,
struct
pbuf
*
p_out
)
{
dhcp_option_trailer
(
options_out_len
,
msg_out
->
options
,
p_out
);
}
LWIP_STATIC
void
handle_discover
(
struct
netif
*
netif
,
struct
dhcps
*
dhcps
,
struct
dhcp_msg
*
client_msg
,
struct
dyn_lease_addr
*
client_lease
)
{
#if !LWIP_DHCPS_DISCOVER_BROADCAST
ip_addr_t
client_ipaddr
;
#endif
ip4_addr_t
client_ip
;
ip_addr_t
dst_addr
;
struct
pbuf
*
out_msg
=
NULL
;
struct
dhcp_msg
*
srvr_msg
=
NULL
;
u16_t
options_len
=
0
;
#if !LWIP_DHCPS_DISCOVER_BROADCAST
#if ETHARP_SUPPORT_STATIC_ENTRIES
struct
eth_addr
ethaddr
;
#endif
#endif
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
,
(
"handle_discover: Processing Discover Message
\n
"
));
client_ip
=
validate_discover
(
dhcps
,
client_msg
,
&
client_lease
);
if
(
client_ip
.
addr
==
0
)
{
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
,
(
"handle_discover: Returning as unable to get a proper address for client
\n
"
));
return
;
}
out_msg
=
dhcps_create_base_msg
(
client_msg
);
if
(
out_msg
==
NULL
)
{
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
,
(
"handle_discover function: Memory allocation for base message failed
\n
"
));
return
;
}
srvr_msg
=
(
struct
dhcp_msg
*
)
out_msg
->
payload
;
// no need check msg pointer from payload here
srvr_msg
->
yiaddr
.
addr
=
htonl
(
client_ip
.
addr
);
dhcp_common_option
(
srvr_msg
,
DHCP_OPTION_MESSAGE_TYPE
,
DHCP_OPTION_MESSAGE_TYPE_LEN
,
&
options_len
);
dhcp_common_option_byte
(
srvr_msg
,
DHCP_OFFER
,
&
options_len
);
/* hilink need this router option */
dhcp_common_option
(
srvr_msg
,
DHCP_OPTION_ROUTER
,
DHCP_OPTION_ROUTER_SIZE
,
&
options_len
);
dhcp_common_option_long
(
srvr_msg
,
ntohl
(
ip_2_ip4
(
&
netif
->
ip_addr
)
->
addr
),
&
options_len
);
/* netif already holds the Server ID in network order. so, no need to convert it again */
dhcp_common_option
(
srvr_msg
,
DHCP_OPTION_SERVER_ID
,
DHCP_OPTION_SERVER_ID_LEN
,
&
options_len
);
dhcp_common_option_long
(
srvr_msg
,
ntohl
(
ip_2_ip4
(
&
netif
->
ip_addr
)
->
addr
),
&
options_len
);
dhcp_common_option
(
srvr_msg
,
DHCP_OPTION_LEASE_TIME
,
DHCP_OPTION_LEASE_TIME_SIZE
,
&
options_len
);
dhcp_common_option_long
(
srvr_msg
,
client_lease
->
proposed_leasetime
,
&
options_len
);
dhcp_common_option
(
srvr_msg
,
DHCP_OPTION_T1
,
DHCP_OPTION_T1_LEN
,
&
options_len
);
dhcp_common_option_long
(
srvr_msg
,
(
client_lease
->
proposed_leasetime
/
2
),
&
options_len
);
dhcp_common_option
(
srvr_msg
,
DHCP_OPTION_T2
,
DHCP_OPTION_T2_LEN
,
&
options_len
);
/* calculate safe periods for lease (proposed_leasetime * 0.875 -> 87.5%) */
dhcp_common_option_long
(
srvr_msg
,
((
client_lease
->
proposed_leasetime
*
7
)
/
8
),
&
options_len
);
/* No need to convert netmask into network order as it is already stored in network order */
dhcp_common_option
(
srvr_msg
,
DHCP_OPTION_SUBNET_MASK
,
DHCP_OPTION_SUBNET_MASK_SIZE
,
&
options_len
);
dhcp_common_option_long
(
srvr_msg
,
ntohl
(
ip4_addr_get_u32
(
ip_2_ip4
(
&
netif
->
netmask
))),
&
options_len
);
dhcp_common_option_trailer
(
srvr_msg
,
options_len
,
out_msg
);
if
(
client_msg
->
ciaddr
.
addr
!=
0
)
{
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
,
(
"handle_discover: sendto(OFFER, ciaddr, DHCP_CLIENT_PORT)
\n
"
));
ip_addr_set_ip4_u32_val
(
dst_addr
,
(
u32_t
)(
client_msg
->
ciaddr
.
addr
));
(
void
)
udp_sendto_if_src
(
dhcps
->
pcb
,
out_msg
,
&
dst_addr
,
DHCP_CLIENT_PORT
,
netif
,
&
(
netif
->
ip_addr
));
}
#if !LWIP_DHCPS_DISCOVER_BROADCAST
else
if
(
ntohs
(
client_msg
->
flags
)
&
DHCP_BROADCAST_FLAG
)
{
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
,
(
"handle_discover: sendto(OFFER, IP_ADDR_BROADCAST, DHCP_CLIENT_PORT)
\n
"
));
(
void
)
udp_sendto_if_src
(
dhcps
->
pcb
,
out_msg
,
IP_ADDR_BROADCAST
,
DHCP_CLIENT_PORT
,
netif
,
&
(
netif
->
ip_addr
));
}
else
{
client_ip
.
addr
=
htonl
(
client_ip
.
addr
);
#if ETHARP_SUPPORT_STATIC_ENTRIES
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
,
(
"handle_discover: Updating ARP Static Entry for unicast reply
\n
"
));
if
(
memcpy_s
(
ethaddr
.
addr
,
ETHARP_HWADDR_LEN
,
client_msg
->
chaddr
,
client_msg
->
hlen
)
!=
EOK
)
{
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
,
(
"memcpy_s failed
\n
"
));
(
void
)
pbuf_free
(
out_msg
);
return
;
}
if
(
etharp_add_static_entry
(
&
client_ip
,
&
ethaddr
)
!=
ERR_OK
)
{
(
void
)
pbuf_free
(
out_msg
);
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
,
(
"handle_discover: Adding static entry to arp cache failed
\n
"
));
return
;
}
#endif
/* Need to check and add an arp entry to make this pass through smoothly */
ip_addr_copy_from_ip4
(
client_ipaddr
,
client_ip
);
(
void
)
udp_sendto_if_src
(
dhcps
->
pcb
,
out_msg
,
&
client_ipaddr
,
DHCP_CLIENT_PORT
,
netif
,
&
(
netif
->
ip_addr
));
#if ETHARP_SUPPORT_STATIC_ENTRIES
/* We just added the entry above and checked for it's success too. so, the below function call cannot fail */
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
,
(
"handle_discover: Removing ARP Static Entry added for unicast reply
\n
"
));
(
void
)
etharp_remove_static_entry
(
&
client_ip
);
#endif
}
#else
else
{
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
,
(
"handle_discover: sendto(OFFER, IP_ADDR_BROADCAST, DHCP_CLIENT_PORT)
\n
"
));
(
void
)
udp_sendto_if_src
(
dhcps
->
pcb
,
out_msg
,
IP_ADDR_BROADCAST
,
DHCP_CLIENT_PORT
,
netif
,
&
(
netif
->
ip_addr
));
}
#endif
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
,
(
"handle_discover: deleting()ing
\n
"
));
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
,
(
"handle_discover: Sending Reply has been successful
\n
"
));
(
void
)
pbuf_free
(
out_msg
);
return
;
}
LWIP_STATIC
ip4_addr_t
validate_request_message
(
struct
netif
*
netif
,
struct
dhcp_msg
*
client_msg
,
struct
dyn_lease_addr
*
client_lease
,
ip4_addr_t
serverid
)
{
struct
dhcps
*
dhcps
=
netif_get_dhcps
(
netif
);
ip4_addr_t
requested_ip
;
requested_ip
.
addr
=
0
;
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
,
(
"validate_request_message: Processing Request Message
\n
"
));
if
((
client_lease
!=
NULL
)
&&
(
client_lease
->
flags
==
DHCPS_ADDRESS_OFFERRED
))
{
/* Now, we are in selecting state */
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
,
(
"validate_request_message: In Selecting State
\n
"
));
if
((
serverid
.
addr
==
0
)
||
(
client_msg
->
ciaddr
.
addr
!=
0
)
||
(
!
dhcps_option_given
(
dhcps
,
DHCP_OPTION_IDX_REQUESTED_IP
)))
{
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
,
(
"Server ID or ciaddr or requested ip option is not present
\n
"
));
return
requested_ip
;
}
if
(
serverid
.
addr
!=
ip_2_ip4
(
&
netif
->
ip_addr
)
->
addr
)
{
/* This message is not meant for us. The client intends to talk to some other server */
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
,
(
"validate_request_message: Server id doesn't match with ours. Message not for us
\n
"
));
requested_ip
.
addr
=
1
;
return
requested_ip
;
}
requested_ip
.
addr
=
(
u32_t
)
dhcps_get_option_value
(
dhcps
,
DHCP_OPTION_IDX_REQUESTED_IP
);
}
else
{
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
,
(
"validate_request_message: In Init-Reboot, Renew or Rebinding State
\n
"
));
/* Now, we can be either in Init-reboot state or renew state or rebinding state */
if
(
dhcps_option_given
(
dhcps
,
DHCP_OPTION_IDX_REQUESTED_IP
))
{
/* Requested IP option is filled in. Indicates we are mostly in Init-Reboot State */
if
(
client_lease
==
NULL
)
{
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
,
(
"validate_request_message: No Configuration found corresponding to request message
\n
"
));
requested_ip
.
addr
=
1
;
return
requested_ip
;
}
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
,
(
"validate_request_message: Requested IP Option is present. So, considering as Init-Reboot State
\n
"
));
if
(
client_msg
->
ciaddr
.
addr
!=
0
)
{
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
,
(
"validate_request_message: Error: ciaddr is filled in the Init-Reboot state.
\n
"
));
return
requested_ip
;
}
requested_ip
.
addr
=
(
u32_t
)
dhcps_get_option_value
(
dhcps
,
DHCP_OPTION_IDX_REQUESTED_IP
);
}
else
{
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
,
(
"validate_request_message: \
Requested IP Option is not present. So, considering as Renewing or Rebinding State
\n
"
));
if
(
client_msg
->
ciaddr
.
addr
==
0
)
{
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
,
(
"validate_request_message: Error: ciaddr is not filled in the Renewing or Rebinding state.
\n
"
));
return
requested_ip
;
}
requested_ip
.
addr
=
ntohl
(
client_msg
->
ciaddr
.
addr
);
}
}
/* requested_ip is in host order and DHCP Server IP is in network order,
so converting the former to network order for check */
if
(
htonl
(
requested_ip
.
addr
)
==
ip_2_ip4
(
&
netif
->
ip_addr
)
->
addr
)
{
/* This requested_ip is the dhcp server is using, it is invalid */
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
,
(
"validate_request_message: Requested IP addr is invalid
\n
"
));
requested_ip
.
addr
=
1
;
}
return
requested_ip
;
}
LWIP_STATIC
void
handle_request
(
struct
netif
*
netif
,
struct
dhcps
*
dhcps
,
struct
dhcp_msg
*
client_msg
,
struct
dyn_lease_addr
*
client_lease
,
ip4_addr_t
serverid
)
{
ip4_addr_t
requested_ip
;
struct
pbuf
*
out_msg
=
NULL
;
struct
dhcp_msg
*
srvr_msg
=
NULL
;
u16_t
options_len
=
0
;
ip_addr_t
dst_addr
;
ip_addr_t
ip_send
;
#if ETHARP_SUPPORT_STATIC_ENTRIES
struct
eth_addr
ethaddr
;
#endif
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
,
(
"handle_request: Processing Request Message
\n
"
));
requested_ip
=
validate_request_message
(
netif
,
client_msg
,
client_lease
,
serverid
);
if
(
requested_ip
.
addr
==
1
)
{
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
,
(
"handle_request: Validation of request message failed. Dropping the packet.
\n
"
));
return
;
}
out_msg
=
dhcps_create_base_msg
(
client_msg
);
if
(
out_msg
==
NULL
)
{
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
,
(
"handle_request: Creating base message failed
\n
"
));
return
;
}
srvr_msg
=
(
struct
dhcp_msg
*
)
out_msg
->
payload
;
dhcp_common_option
(
srvr_msg
,
DHCP_OPTION_SERVER_ID
,
DHCP_OPTION_SERVER_ID_LEN
,
&
options_len
);
dhcp_common_option_long
(
srvr_msg
,
ntohl
(
ip_2_ip4
(
&
netif
->
ip_addr
)
->
addr
),
&
options_len
);
/* hilink need this router option */
dhcp_common_option
(
srvr_msg
,
DHCP_OPTION_ROUTER
,
DHCP_OPTION_ROUTER_SIZE
,
&
options_len
);
dhcp_common_option_long
(
srvr_msg
,
ntohl
(
ip_2_ip4
(
&
netif
->
ip_addr
)
->
addr
),
&
options_len
);
if
((
client_lease
!=
NULL
)
&&
(
client_lease
->
cli_addr
.
addr
==
requested_ip
.
addr
))
{
if
(
client_lease
->
proposed_leasetime
!=
(
u32_t
)(
~
0
))
{
if
(
client_lease
->
flags
==
DHCPS_ADDRESS_OFFERRED
)
{
client_lease
->
leasetime
=
sys_now
()
+
(
client_lease
->
proposed_leasetime
*
1000
);
}
else
{
client_lease
->
leasetime
+=
(
client_lease
->
proposed_leasetime
*
1000
);
}
}
else
{
client_lease
->
leasetime
=
client_lease
->
proposed_leasetime
;
}
client_lease
->
flags
=
DHCPS_ADDRESS_BOUND
;
srvr_msg
->
yiaddr
.
addr
=
htonl
(
client_lease
->
cli_addr
.
addr
);
dhcp_common_option
(
srvr_msg
,
DHCP_OPTION_MESSAGE_TYPE
,
DHCP_OPTION_MESSAGE_TYPE_LEN
,
&
options_len
);
dhcp_common_option_byte
(
srvr_msg
,
DHCP_ACK
,
&
options_len
);
dhcp_common_option
(
srvr_msg
,
DHCP_OPTION_LEASE_TIME
,
DHCP_OPTION_LEASE_TIME_SIZE
,
&
options_len
);
dhcp_common_option_long
(
srvr_msg
,
client_lease
->
proposed_leasetime
,
&
options_len
);
dhcp_common_option
(
srvr_msg
,
DHCP_OPTION_T1
,
DHCP_OPTION_T1_LEN
,
&
options_len
);
dhcp_common_option_long
(
srvr_msg
,
(
client_lease
->
proposed_leasetime
/
2
),
&
options_len
);
dhcp_common_option
(
srvr_msg
,
DHCP_OPTION_T2
,
DHCP_OPTION_T2_LEN
,
&
options_len
);
/* calculate safe periods for lease (proposed_leasetime * 0.875 -> 87.5%) */
dhcp_common_option_long
(
srvr_msg
,
((
client_lease
->
proposed_leasetime
*
7
)
/
8
),
&
options_len
);
dhcp_common_option
(
srvr_msg
,
DHCP_OPTION_SUBNET_MASK
,
DHCP_OPTION_SUBNET_MASK_SIZE
,
&
options_len
);
dhcp_common_option_long
(
srvr_msg
,
ntohl
(
ip_2_ip4
(
&
netif
->
netmask
)
->
addr
),
&
options_len
);
#ifdef LWIP_DEV_DEBUG
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
,
(
"handle_request: Send ACK. to=%"
U32_F
" lease time=%"
U32_F
"
\n
"
,
requested_ip
.
addr
,
client_lease
->
proposed_leasetime
));
#endif
}
else
{
dhcp_common_option
(
srvr_msg
,
DHCP_OPTION_MESSAGE_TYPE
,
DHCP_OPTION_MESSAGE_TYPE_LEN
,
&
options_len
);
dhcp_common_option_byte
(
srvr_msg
,
DHCP_NAK
,
&
options_len
);
/* Just set this here, so that the NAK message is brcasted.
The correct flags has already been added in the respose message during base message creation */
client_msg
->
flags
|=
htons
(
DHCP_BROADCAST_FLAG
);
client_msg
->
ciaddr
.
addr
=
0
;
/* This is done so that NAK Gets brcasted */
#ifdef LWIP_DEV_DEBUG
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
,
(
"handle_request: Send NAK. Requested from=%"
U32_F
"
\n
"
,
requested_ip
.
addr
));
#endif
}
requested_ip
.
addr
=
htonl
(
requested_ip
.
addr
);
dhcp_common_option_trailer
(
srvr_msg
,
options_len
,
out_msg
);
if
(
client_msg
->
ciaddr
.
addr
!=
0
)
{
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
,
(
"handle_request: sendto(ACK, ciaddr, DHCP_CLIENT_PORT)
\n
"
));
ip_addr_set_ip4_u32_val
(
dst_addr
,
(
u32_t
)(
client_msg
->
ciaddr
.
addr
));
(
void
)
udp_sendto_if_src
(
dhcps
->
pcb
,
out_msg
,
&
dst_addr
,
DHCP_CLIENT_PORT
,
netif
,
&
(
netif
->
ip_addr
));
}
else
if
(
ntohs
(
client_msg
->
flags
)
&
DHCP_BROADCAST_FLAG
)
{
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
,
(
"handle_request: sending reply using brdcast
\n
"
));
(
void
)
udp_sendto_if_src
(
dhcps
->
pcb
,
out_msg
,
IP_ADDR_BROADCAST
,
DHCP_CLIENT_PORT
,
netif
,
&
(
netif
->
ip_addr
));
}
else
{
#if ETHARP_SUPPORT_STATIC_ENTRIES
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
,
(
"handle_request: Updating ARP Static Entry for unicast reply
\n
"
));
if
(
memcpy_s
(
ethaddr
.
addr
,
ETHARP_HWADDR_LEN
,
client_msg
->
chaddr
,
client_msg
->
hlen
)
!=
EOK
)
{
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
,
(
"handle_request: Copy chaddr failed
\n
"
));
(
void
)
pbuf_free
(
out_msg
);
return
;
}
if
(
ERR_OK
!=
etharp_add_static_entry
(
&
requested_ip
,
&
ethaddr
))
{
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
,
(
"handle_request: Adding static entry to arp cache failed
\n
"
));
(
void
)
pbuf_free
(
out_msg
);
return
;
}
#endif
/* Need to check and add an arp entry to make this pass through smoothly */
#ifdef LWIP_DEV_DEBUG
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
,
(
"handle_request: sending reply using unicast Client IP =%"
U32_F
"
\n
"
,
requested_ip
.
addr
));
#endif
ip_send
.
u_addr
.
ip4
.
addr
=
requested_ip
.
addr
;
ip_send
.
type
=
IPADDR_TYPE_V4
;
(
void
)
udp_sendto_if_src
(
dhcps
->
pcb
,
out_msg
,
&
ip_send
,
DHCP_CLIENT_PORT
,
netif
,
&
(
netif
->
ip_addr
));
#if ETHARP_SUPPORT_STATIC_ENTRIES
/* We just added the entry above and checked for it's success too. so, the below function call cannot fail */
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
,
(
"handle_request: Removing ARP Static Entry added for unicast reply
\n
"
));
(
void
)
etharp_remove_static_entry
(
&
requested_ip
);
#endif
}
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
,
(
"handle_request: deleting
\n
"
));
(
void
)
pbuf_free
(
out_msg
);
return
;
}
LWIP_STATIC
void
handle_decline
(
struct
netif
*
netif
,
struct
dhcps
*
dhcps
,
struct
dhcp_msg
*
client_msg
,
struct
dyn_lease_addr
*
client_lease
)
{
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
,
(
"handle_decline: Processing Decline Message
\n
"
));
if
((
client_lease
!=
NULL
)
&&
(
dhcps_option_given
(
dhcps
,
DHCP_OPTION_IDX_REQUESTED_IP
))
&&
(
client_msg
->
ciaddr
.
addr
==
0
))
{
if
(
client_lease
->
cli_addr
.
addr
==
(
u32_t
)
dhcps_get_option_value
(
dhcps
,
DHCP_OPTION_IDX_REQUESTED_IP
))
{
#ifdef LWIP_DEV_DEBUG
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
,
(
"handle_decline: Marking Client Entry as declined. Client IP =%"
U32_F
"
\n
"
,
client_lease
->
cli_addr
.
addr
));
#endif
(
void
)
memset_s
(
client_lease
->
cli_hwaddr
,
sizeof
(
client_lease
->
cli_hwaddr
),
0
,
DHCP_CHADDR_LEN
);
client_lease
->
proposed_leasetime
=
0
;
client_lease
->
leasetime
=
sys_now
()
+
(
LWIP_DHCPS_DECLINE_TIME
*
1000
);
client_lease
->
flags
=
DHCPS_ADDRESS_DECLINED
;
}
}
}
LWIP_STATIC
void
handle_inform
(
struct
netif
*
netif
,
struct
dhcps
*
dhcps
,
struct
dhcp_msg
*
client_msg
)
{
struct
pbuf
*
out_msg
=
NULL
;
struct
dhcp_msg
*
srvr_msg
=
NULL
;
u16_t
options_len
=
0
;
ip_addr_t
dst_addr
;
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
,
(
"handle_inform: Processing Inform Message
\n
"
));
if
(
client_msg
->
ciaddr
.
addr
==
0
)
{
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
,
(
"handle_inform: ciaddr is empty. Can't send back a response
\n
"
));
return
;
}
out_msg
=
dhcps_create_base_msg
(
client_msg
);
if
(
out_msg
==
NULL
)
{
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
,
(
"handle_inform: Creating base message failed
\n
"
));
return
;
}
srvr_msg
=
(
struct
dhcp_msg
*
)
out_msg
->
payload
;
dhcp_common_option
(
srvr_msg
,
DHCP_OPTION_MESSAGE_TYPE
,
DHCP_OPTION_MESSAGE_TYPE_LEN
,
&
options_len
);
dhcp_common_option_byte
(
srvr_msg
,
DHCP_ACK
,
&
options_len
);
dhcp_common_option_trailer
(
srvr_msg
,
options_len
,
out_msg
);
#ifdef LWIP_DEV_DEBUG
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
,
(
"handle_inform: Send ACK to Client. Client is=%"
U32_F
"
\n
"
,
client_msg
->
ciaddr
.
addr
));
#endif
ip_addr_set_ip4_u32_val
(
dst_addr
,
client_msg
->
ciaddr
.
addr
);
(
void
)
udp_sendto_if_src
(
dhcps
->
pcb
,
out_msg
,
&
dst_addr
,
DHCP_CLIENT_PORT
,
netif
,
&
(
netif
->
ip_addr
));
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
,
(
"handle_inform: deleting pbuf
\n
"
));
(
void
)
pbuf_free
(
out_msg
);
return
;
}
LWIP_STATIC
void
handle_client_messages
(
struct
netif
*
netif
,
struct
dhcps
*
dhcps
,
struct
dhcp_msg
*
client_msg
,
ip4_addr_t
serverid
,
u8_t
msg_type
)
{
struct
dyn_lease_addr
*
client_lease
=
NULL
;
client_lease
=
find_client_lease
(
dhcps
,
client_msg
);
switch
(
msg_type
)
{
case
DHCP_DISCOVER
:
handle_discover
(
netif
,
dhcps
,
client_msg
,
client_lease
);
break
;
case
DHCP_REQUEST
:
handle_request
(
netif
,
dhcps
,
client_msg
,
client_lease
,
serverid
);
break
;
case
DHCP_DECLINE
:
handle_decline
(
netif
,
dhcps
,
client_msg
,
client_lease
);
break
;
case
DHCP_RELEASE
:
if
((
client_lease
!=
NULL
)
&&
(
client_lease
->
cli_addr
.
addr
==
ntohl
(
client_msg
->
ciaddr
.
addr
)))
{
#ifdef LWIP_DEV_DEBUG
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
,
(
"DHCP Release: Client IPAdd =%"
U32_F
"
\n
"
,
client_msg
->
ciaddr
.
addr
));
#endif
(
void
)
memset_s
(
client_lease
,
sizeof
(
struct
dyn_lease_addr
),
0
,
sizeof
(
struct
dyn_lease_addr
));
client_lease
->
flags
=
DHCPS_ADDRESS_FREE
;
}
break
;
case
DHCP_INFORM
:
handle_inform
(
netif
,
dhcps
,
client_msg
);
break
;
default:
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
|
LWIP_DBG_LEVEL_WARNING
,
(
"DHCP Server. Invalid message type received %d
\n
"
,
msg_type
));
}
}
err_t
dhcps_parse_options
(
struct
pbuf
*
p
,
struct
dhcps
*
dhcps
)
{
return
dhcp_parse_reply
(
p
,
&
dhcps
->
dhcp
);
}
LWIP_STATIC
void
dhcps_recv
(
void
*
arg
,
struct
udp_pcb
*
pcb
,
struct
pbuf
*
p
,
const
ip_addr_t
*
ip_addr
,
u16_t
port
)
{
struct
netif
*
netif
=
(
struct
netif
*
)
arg
;
struct
dhcps
*
dhcps
=
netif_get_dhcps
(
netif
);
struct
dhcp_msg
*
client_msg
=
(
struct
dhcp_msg
*
)
p
->
payload
;
u8_t
msg_type
;
ip4_addr_t
serverid
;
ip4_addr_t
addr
;
if
(
client_msg
==
NULL
)
{
return
;
}
addr
.
addr
=
ip_addr
->
u_addr
.
ip4
.
addr
;
serverid
.
addr
=
0
;
#ifdef LWIP_DEV_DEBUG
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
,
(
"dhcps_recv(pbuf = %p) from DHCP Client %"
U16_F
".%"
U16_F
".%"
U16_F
".%"
U16_F
" port %"
U16_F
"
\n
"
,
(
void
*
)
p
,
ip4_addr1_16
(
&
addr
),
ip4_addr2_16
(
&
addr
),
ip4_addr3_16
(
&
addr
),
ip4_addr4_16
(
&
addr
),
port
));
#endif
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
,
(
"pbuf->len = %"
U16_F
"
\n
"
,
p
->
len
));
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
,
(
"pbuf->tot_len = %"
U16_F
"
\n
"
,
p
->
tot_len
));
/* prevent warnings about unused arguments */
LWIP_UNUSED_ARG
(
pcb
);
LWIP_UNUSED_ARG
(
addr
);
LWIP_UNUSED_ARG
(
port
);
dhcps_clear_all_options
(
dhcps
);
/* Check and remove old entries on each call to dhcp_recv. This way, we don't need to maintain timers */
remove_stale_entries
(
dhcps
);
if
(
p
->
len
<
DHCP_OPTIONS_OFS
)
{
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
|
LWIP_DBG_LEVEL_WARNING
,
(
"DHCP client message or pbuf too short. pbuf len =%"
U16_F
" DHCP MIN Reply Len = %"
U32_F
"
\n
"
,
p
->
len
,
DHCP_MIN_REPLY_LEN
));
goto
free_pbuf_and_return
;
}
if
(
client_msg
->
op
!=
DHCP_BOOTREQUEST
)
{
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
|
LWIP_DBG_LEVEL_WARNING
,
(
"Not a DHCP reply message, Type %"
U16_F
"
\n
"
,
(
u16_t
)
client_msg
->
op
));
goto
free_pbuf_and_return
;
}
if
(
client_msg
->
cookie
!=
PP_HTONL
(
DHCP_MAGIC_COOKIE
))
{
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
|
LWIP_DBG_LEVEL_WARNING
,
(
"DHCP Server. Cookie Value is incorrect. %"
U32_F
"
\n
"
,
(
u32_t
)
client_msg
->
cookie
));
goto
free_pbuf_and_return
;
}
if
(
client_msg
->
hlen
!=
ETHARP_HWADDR_LEN
)
{
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
|
LWIP_DBG_LEVEL_WARNING
,
(
"DHCP Server. Invalid hardware address length %"
U16_F
"
\n
"
,
(
u16_t
)
client_msg
->
hlen
));
goto
free_pbuf_and_return
;
}
if
(
dhcps_parse_options
(
p
,
dhcps
)
!=
ERR_OK
)
{
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
|
LWIP_DBG_LEVEL_WARNING
,
(
"Parsing of Options failed in DHCP Client Message
\n
"
));
goto
free_pbuf_and_return
;
}
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
,
(
"Searching DHCP_OPTION_MESSAGE_TYPE
\n
"
));
/* obtain pointer to DHCP message type */
if
(
!
dhcps_option_given
(
dhcps
,
DHCP_OPTION_IDX_MSG_TYPE
))
{
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
|
LWIP_DBG_LEVEL_WARNING
,
(
"DHCP_OPTION_MESSAGE_TYPE option not found
\n
"
));
goto
free_pbuf_and_return
;
}
/* read DHCP message type */
msg_type
=
(
u8_t
)
dhcps_get_option_value
(
dhcps
,
DHCP_OPTION_IDX_MSG_TYPE
);
if
(
dhcps_option_given
(
dhcps
,
DHCP_OPTION_IDX_SERVER_ID
))
{
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
|
LWIP_DBG_LEVEL_WARNING
,
(
"DHCP_OPTION_SERVER_ID option found
\n
"
));
/* Parse options would have changed it to host order. But, we have our IP stored in netif in network order */
serverid
.
addr
=
htonl
((
u32_t
)
dhcps_get_option_value
(
dhcps
,
DHCP_OPTION_IDX_SERVER_ID
));
}
if
((
serverid
.
addr
!=
0
)
&&
((
msg_type
==
DHCP_DISCOVER
)
||
(
msg_type
==
DHCP_INFORM
)))
{
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
|
LWIP_DBG_LEVEL_WARNING
,
(
"Serverid present in DHCP_DISCOVER and DHCP_INFORM messages
\n
"
));
goto
free_pbuf_and_return
;
}
if
((
!
ip4_addr_cmp
(
&
serverid
,
ip_2_ip4
(
&
netif
->
ip_addr
)))
&&
((
msg_type
==
DHCP_DECLINE
)
||
(
msg_type
==
DHCP_RELEASE
)))
{
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
|
LWIP_DBG_LEVEL_WARNING
,
(
"Serverid not present in DHCP_RELEASE and DHCP_DECLINE messages
\n
"
));
goto
free_pbuf_and_return
;
}
handle_client_messages
(
netif
,
dhcps
,
client_msg
,
serverid
,
msg_type
);
free_pbuf_and_return:
(
void
)
pbuf_free
(
p
);
}
err_t
dhcps_start
(
struct
netif
*
netif
,
const
char
*
start_ip
,
u16_t
ip_num
)
{
struct
dhcps
*
dhcps
=
NULL
;
ip4_addr_t
address_in_hton
;
int
err
;
LWIP_ERROR
(
"netif != NULL"
,
(
netif
!=
NULL
),
return
ERR_ARG
);
dhcps
=
netif_get_dhcps
(
netif
);
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
|
LWIP_DBG_STATE
,
(
"dhcps_start(netif=%p) %s
\n
"
,
(
void
*
)
netif
,
netif_get_name
(
netif
)));
if
(
netif
->
mtu
<
DHCP_MAX_MSG_LEN_MIN_REQUIRED
)
{
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
,
(
"MTU =%"
U16_F
",DHCP Msg Len Required =%"
U32_F
"
\n
"
,
netif
->
mtu
,
DHCP_MAX_MSG_LEN_MIN_REQUIRED
));
return
ERR_MEM
;
}
if
(
dhcps
!=
NULL
)
{
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
,
(
"dhcps_start(): DHCP Server is already started
\n
"
));
return
ERR_MEM
;
}
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
,
(
"dhcps_start(): starting new DHCP Server
\n
"
));
dhcps
=
(
struct
dhcps
*
)
mem_malloc
(
sizeof
(
struct
dhcps
));
if
(
dhcps
==
NULL
)
{
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
,
(
"dhcps_start(): could not allocate dhcp
\n
"
));
return
ERR_MEM
;
}
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
,
(
"dhcps_start(): allocated dhcp"
));
(
void
)
memset_s
(
dhcps
,
sizeof
(
struct
dhcps
),
0
,
sizeof
(
struct
dhcps
));
dhcps
->
pcb
=
udp_new
();
if
(
dhcps
->
pcb
==
NULL
)
{
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
,
(
"dhcp_start(): could not allocate pcb
\n
"
));
mem_free
((
void
*
)
dhcps
);
return
ERR_MEM
;
}
#if LWIP_SO_BINDTODEVICE
/* bind dhcp udp_pcb to specific netif, this could make dhcp server start on multiple netif */
dhcps
->
pcb
->
ifindex
=
netif
->
ifindex
;
#endif
if
((
start_ip
==
NULL
)
||
(
ip_num
==
0
))
{
/* use default ip lease configuration. */
dhcps
->
start_addr
.
addr
=
ntohl
(
ip_2_ip4
(
&
netif
->
ip_addr
)
->
addr
&
ip_2_ip4
(
&
netif
->
netmask
)
->
addr
)
+
1
;
dhcps
->
end_addr
.
addr
=
ntohl
(
ip_2_ip4
(
&
netif
->
ip_addr
)
->
addr
|
(
~
ip_2_ip4
(
&
netif
->
netmask
)
->
addr
))
-
1
;
dhcps
->
lease_num
=
(
u8_t
)(
dhcps
->
end_addr
.
addr
-
dhcps
->
start_addr
.
addr
+
1
);
if
(
dhcps
->
lease_num
>
LWIP_DHCPS_MAX_LEASE
)
{
dhcps
->
lease_num
=
LWIP_DHCPS_MAX_LEASE
;
dhcps
->
end_addr
.
addr
=
dhcps
->
start_addr
.
addr
+
LWIP_DHCPS_MAX_LEASE
-
1
;
}
}
else
{
dhcps
->
start_addr
.
addr
=
ntohl
(
ipaddr_addr
(
start_ip
));
dhcps
->
end_addr
.
addr
=
(
u32_t
)(
dhcps
->
start_addr
.
addr
+
(
u32_t
)(
LWIP_MIN
(
ip_num
-
1
,
LWIP_DHCPS_MAX_LEASE
-
1
)));
ip4_addr_set_hton
(
&
address_in_hton
,
&
dhcps
->
start_addr
);
if
(
!
ip4_addr_netcmp
((
&
address_in_hton
),
ip_2_ip4
(
&
netif
->
ip_addr
),
ip_2_ip4
(
&
netif
->
netmask
))
||
ip4_addr_isbroadcast
((
&
address_in_hton
),
netif
))
{
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
,
(
"dhcp_start(): %s in not a valid ip lease
\n
"
,
start_ip
));
udp_remove
(
dhcps
->
pcb
);
mem_free
((
void
*
)
dhcps
);
return
ERR_ARG
;
}
ip4_addr_set_hton
(
&
address_in_hton
,
&
dhcps
->
end_addr
);
if
(
!
ip4_addr_netcmp
((
&
address_in_hton
),
ip_2_ip4
(
&
netif
->
ip_addr
),
ip_2_ip4
(
&
netif
->
netmask
))
||
ip4_addr_isbroadcast
((
&
address_in_hton
),
netif
))
{
dhcps
->
end_addr
.
addr
=
ntohl
(
ip_2_ip4
(
&
netif
->
ip_addr
)
->
addr
|
(
~
ip_2_ip4
(
&
netif
->
netmask
)
->
addr
))
-
1
;
}
dhcps
->
lease_num
=
(
u8_t
)(
dhcps
->
end_addr
.
addr
-
dhcps
->
start_addr
.
addr
+
1
);
}
dhcps
->
netif
=
netif
;
dhcps
->
pcb
->
so_options
|=
SOF_BROADCAST
;
err
=
udp_bind
(
dhcps
->
pcb
,
IP_ADDR_ANY
,
DHCP_SERVER_PORT
);
if
(
err
!=
ERR_OK
)
{
udp_remove
(
dhcps
->
pcb
);
mem_free
((
void
*
)
dhcps
);
return
ERR_MEM
;
}
err
=
udp_connect
(
dhcps
->
pcb
,
IP_ADDR_ANY
,
DHCP_CLIENT_PORT
);
if
(
err
!=
ERR_OK
)
{
udp_remove
(
dhcps
->
pcb
);
mem_free
((
void
*
)
dhcps
);
return
ERR_MEM
;
}
udp_recv
(
dhcps
->
pcb
,
dhcps_recv
,
netif
);
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
,
(
"dhcps_start(): starting DHCPS Successfully
\n
"
));
#ifdef LWIP_DEV_DEBUG
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
,
(
"dhcps_start(): DHCPS Conf:: netif addr = %"
U32_F
" dhcps start addr%"
U32_F
" dhcp end addr%"
U32_F
"
\n
"
,
ip_2_ip4
(
&
netif
->
ip_addr
)
->
addr
,
dhcps
->
start_addr
.
addr
,
dhcps
->
end_addr
.
addr
));
#endif
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
,
(
"dhcps_start(): DHCPS Lease Conf:: Lease Time = %"
U32_F
" Offer Time = %"
U32_F
"
\n
"
,
LWIP_DHCPS_LEASE_TIME
,
LWIP_DHCPS_OFFER_TIME
));
netif_set_dhcps
(
netif
,
dhcps
);
return
ERR_OK
;
}
void
dhcps_stop
(
struct
netif
*
netif
)
{
LWIP_ERROR
(
"dhcps_stop: netif != NULL"
,
(
netif
!=
NULL
),
return
);
struct
dhcps
*
dhcps
=
netif_get_dhcps
(
netif
);
if
(
dhcps
!=
NULL
)
{
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
,
(
"dhcps_stop(): Stopping DHCP Server
\n
"
));
if
(
dhcps
->
pcb
!=
NULL
)
{
LWIP_DEBUGF
(
DHCP_DEBUG
|
LWIP_DBG_TRACE
,
(
"dhcps_stop(): Removing UDP PCB
\n
"
));
udp_remove
(
dhcps
->
pcb
);
dhcps
->
pcb
=
NULL
;
}
mem_free
(
dhcps
);
netif_set_dhcps
(
netif
,
NULL
);
}
}
#endif
net/lwip-2.1/enhancement/src/
api_shell_fix
.c
→
net/lwip-2.1/enhancement/src/
fixme
.c
浏览文件 @
4f55f678
...
@@ -29,46 +29,26 @@
...
@@ -29,46 +29,26 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
*/
#include "api_shell_fix.h"
#include "lwip/fixme.h"
#include <time.h>
#include <lwip/sys.h>
#include <lwip/sys.h>
#include <lwip/snmp.h>
#include <lwip/snmp.h>
#include <lwip/etharp.h>
#include <lwip/etharp.h>
#include <lwip/netifapi.h>
#include <lwip/netifapi.h>
#include <lwip/sockets.h>
#include <lwip/priv/api_msg.h>
#include <lwip/priv/api_msg.h>
#include "securec.h"
#define NETIFAPI_VAR_REF(name) API_VAR_REF(name)
#define NETIFAPI_VAR_REF(name) API_VAR_REF(name)
#define NETIFAPI_VAR_DECLARE(name) API_VAR_DECLARE(struct netifapi_msg, name)
#define NETIFAPI_VAR_DECLARE(name) API_VAR_DECLARE(struct netifapi_msg, name)
#define NETIFAPI_VAR_ALLOC(name) API_VAR_ALLOC(struct netifapi_msg, MEMP_NETIFAPI_MSG, name, ERR_MEM)
#define NETIFAPI_VAR_ALLOC(name) API_VAR_ALLOC(struct netifapi_msg, MEMP_NETIFAPI_MSG, name, ERR_MEM)
#define NETIFAPI_VAR_FREE(name) API_VAR_FREE(MEMP_NETIFAPI_MSG, name)
#define NETIFAPI_VAR_FREE(name) API_VAR_FREE(MEMP_NETIFAPI_MSG, name)
/**
*
*
* ################# FOR API_SHELL ONLY #################
*
*
*
*/
#if LWIP_ENABLE_LOS_SHELL_CMD
#if LWIP_DHCP
#if LWIP_DHCP
#include <lwip/dhcp.h>
#include <lwip/dhcp.h>
/*
/*
* Close DHCP and set static network.
* Close DHCP and set static network.
*
* @param netif a pre-allocated netif structure
* @param netif a pre-allocated netif structure
*
* @return ERR_OK, or ERR_VAL if failed.
* @return ERR_OK, or ERR_VAL if failed.
*/
*/
err_t
netif_dhcp_off
(
struct
netif
*
netif
)
err_t
netif_dhcp_off
(
struct
netif
*
netif
)
...
@@ -85,32 +65,48 @@ err_t netif_dhcp_off(struct netif *netif)
...
@@ -85,32 +65,48 @@ err_t netif_dhcp_off(struct netif *netif)
old_gateway
=
netif
->
gw
;
old_gateway
=
netif
->
gw
;
if
(
netif_dhcp_data
(
netif
))
{
if
(
netif_dhcp_data
(
netif
))
{
(
void
)
dhcp_release
(
netif
);
(
void
)
dhcp_release
(
netif
);
(
void
)
dhcp_stop
(
netif
);
(
void
)
dhcp_stop
(
netif
);
(
void
)
dhcp_cleanup
(
netif
);
(
void
)
dhcp_cleanup
(
netif
);
LWIP_DEBUGF
(
NETIF_DEBUG
,
(
"DHCP is close;set static IP
\n
"
));
LWIP_DEBUGF
(
NETIF_DEBUG
,
(
"DHCP is close;set static IP
\n
"
));
}
}
ip_addr_set_val
(
&
netif
->
ip_addr
,
&
old_ipaddr
);
ip_addr_set_val
(
&
netif
->
ip_addr
,
&
old_ipaddr
);
ip_addr_set_val
(
&
netif
->
netmask
,
&
old_netmask
);
ip_addr_set_val
(
&
netif
->
netmask
,
&
old_netmask
);
ip_addr_set_val
(
&
netif
->
gw
,
&
old_gateway
);
ip_addr_set_val
(
&
netif
->
gw
,
&
old_gateway
);
(
void
)
netif_set_up
(
netif
);
(
void
)
netif_set_up
(
netif
);
return
ERR_OK
;
return
ERR_OK
;
}
}
err_t
dhcp_is_bound
(
struct
netif
*
netif
)
{
struct
dhcp
*
dhcp
=
NULL
;
LWIP_ERROR
(
"netif != NULL"
,
(
netif
!=
NULL
),
return
ERR_ARG
);
dhcp
=
netif_dhcp_data
(
netif
);
LWIP_ERROR
(
"netif->dhcp != NULL"
,
(
dhcp
!=
NULL
),
return
ERR_ARG
);
if
(
dhcp
->
state
==
DHCP_STATE_BOUND
)
{
return
ERR_OK
;
}
else
{
return
ERR_INPROGRESS
;
}
}
#endif
/* LWIP_DHCP */
#endif
/* LWIP_DHCP */
#if LWIP_DHCPS
#if LWIP_DHCPS
#include "dhcps.h"
#include "
lwip/
dhcps.h"
static
err_t
netifapi_do_dhcps_start
(
struct
tcpip_api_call_data
*
m
)
static
err_t
netifapi_do_dhcps_start
(
struct
tcpip_api_call_data
*
m
)
{
{
/* cast through void* to silence alignment warnings.
/* cast through void* to silence alignment warnings.
* We know it works because the structs have been instantiated as struct netifapi_msg */
* We know it works because the structs have been instantiated as struct netifapi_msg */
err_t
ret
;
err_t
ret
;
struct
netifapi_msg
*
msg
=
(
struct
netifapi_msg
*
)(
void
*
)
m
;
struct
netifapi_msg
*
msg
=
(
struct
netifapi_msg
*
)(
void
*
)
m
;
ret
=
dhcps_start
(
msg
->
netif
,
msg
->
msg
.
dhcp_start_params
.
start_ip
,
msg
->
msg
.
dhcp_start_params
.
ip_num
);
ret
=
dhcps_start
(
msg
->
netif
,
msg
->
msg
.
dhcp_start_params
.
start_ip
,
msg
->
msg
.
dhcp_start_params
.
ip_num
);
return
ret
;
return
ret
;
}
}
...
@@ -124,8 +120,8 @@ err_t netifapi_dhcps_start(struct netif *netif, char *start_ip, u16_t ip_num)
...
@@ -124,8 +120,8 @@ err_t netifapi_dhcps_start(struct netif *netif, char *start_ip, u16_t ip_num)
NETIFAPI_VAR_ALLOC
(
msg
);
NETIFAPI_VAR_ALLOC
(
msg
);
NETIFAPI_VAR_REF
(
msg
).
netif
=
netif
;
NETIFAPI_VAR_REF
(
msg
).
netif
=
netif
;
NETIFAPI_VAR_REF
(
msg
).
msg
.
dhcp_start_params
.
start_ip
=
start_ip
;
NETIFAPI_VAR_REF
(
msg
).
msg
.
dhcp_start_params
.
start_ip
=
start_ip
;
NETIFAPI_VAR_REF
(
msg
).
msg
.
dhcp_start_params
.
ip_num
=
ip_num
;
NETIFAPI_VAR_REF
(
msg
).
msg
.
dhcp_start_params
.
ip_num
=
ip_num
;
err
=
tcpip_api_call
(
netifapi_do_dhcps_start
,
&
API_VAR_REF
(
msg
).
call
);
err
=
tcpip_api_call
(
netifapi_do_dhcps_start
,
&
API_VAR_REF
(
msg
).
call
);
...
@@ -216,19 +212,19 @@ static struct netif *netif_find_by_name(const char *name)
...
@@ -216,19 +212,19 @@ static struct netif *netif_find_by_name(const char *name)
return
NULL
;
return
NULL
;
}
}
if
(
strcmp
(
"lo"
,
name
)
==
0
)
{
LWIP_DEBUGF
(
NETIF_DEBUG
,
(
"netif_find: found %c%c
\n
"
,
name
[
0
],
name
[
1
]));
return
netif_find
(
name
);
}
NETIF_FOREACH
(
netif
)
{
NETIF_FOREACH
(
netif
)
{
if
(
strcmp
(
"lo"
,
name
)
==
0
&&
(
netif
->
name
[
0
]
==
'l'
&&
netif
->
name
[
1
]
==
'o'
))
{
LWIP_DEBUGF
(
NETIF_DEBUG
,
(
"netif_find_by_name: found lo
\n
"
));
return
netif
;
}
if
(
strcmp
(
netif
->
full_name
,
name
)
==
0
)
{
if
(
strcmp
(
netif
->
full_name
,
name
)
==
0
)
{
LWIP_DEBUGF
(
NETIF_DEBUG
,
(
"netif_find
: found %c%c
\n
"
,
name
[
0
],
name
[
1
]
));
LWIP_DEBUGF
(
NETIF_DEBUG
,
(
"netif_find
_by_name: found %s
\n
"
,
name
));
return
netif
;
return
netif
;
}
}
}
}
LWIP_DEBUGF
(
NETIF_DEBUG
,
(
"netif_find
: didn't find %c%c
\n
"
,
name
[
0
],
name
[
1
]
));
LWIP_DEBUGF
(
NETIF_DEBUG
,
(
"netif_find
_by_name: didn't find %s
\n
"
,
name
));
return
NULL
;
return
NULL
;
}
}
...
@@ -294,7 +290,7 @@ err_t netif_set_mtu(struct netif *netif, u16_t netif_mtu)
...
@@ -294,7 +290,7 @@ err_t netif_set_mtu(struct netif *netif, u16_t netif_mtu)
#endif
/* LWIP_IPV6 && LWIP_ND6_ALLOW_RA_UPDATES */
#endif
/* LWIP_IPV6 && LWIP_ND6_ALLOW_RA_UPDATES */
LWIP_DEBUGF
(
NETIF_DEBUG
|
LWIP_DBG_STATE
,
(
"netif: MTU of interface %s is changed to %d
\n
"
,
LWIP_DEBUGF
(
NETIF_DEBUG
|
LWIP_DBG_STATE
,
(
"netif: MTU of interface %s is changed to %d
\n
"
,
netif_get_name
(
netif
),
netif
->
mtu
));
netif_get_name
(
netif
),
netif
->
mtu
));
return
ERR_OK
;
return
ERR_OK
;
}
}
...
@@ -322,31 +318,35 @@ err_t netif_set_hwaddr(struct netif *netif, const unsigned char *hw_addr, int hw
...
@@ -322,31 +318,35 @@ err_t netif_set_hwaddr(struct netif *netif, const unsigned char *hw_addr, int hw
LWIP_DEBUGF
(
NETIF_DEBUG
|
LWIP_DBG_TRACE
|
LWIP_DBG_STATE
,
LWIP_DEBUGF
(
NETIF_DEBUG
|
LWIP_DBG_TRACE
|
LWIP_DBG_STATE
,
(
"netif: HW address of interface %s set to %02X:%02X:%02X:%02X:%02X:%02X
\n
"
,
(
"netif: HW address of interface %s set to %02X:%02X:%02X:%02X:%02X:%02X
\n
"
,
netif_get_name
(
netif
),
netif_get_name
(
netif
),
netif
->
hwaddr
[
0
],
netif
->
hwaddr
[
1
],
netif
->
hwaddr
[
2
],
netif
->
hwaddr
[
0
],
netif
->
hwaddr
[
1
],
netif
->
hwaddr
[
2
],
netif
->
hwaddr
[
3
],
netif
->
hwaddr
[
4
],
netif
->
hwaddr
[
5
]));
netif
->
hwaddr
[
3
],
netif
->
hwaddr
[
4
],
netif
->
hwaddr
[
5
]));
return
ERR_OK
;
return
ERR_OK
;
}
}
err_t
etharp_update_arp_entry
(
struct
netif
*
netif
,
const
ip4_addr_t
*
ipaddr
,
struct
eth_addr
*
ethaddr
,
u8_t
flags
)
err_t
etharp_update_arp_entry
(
struct
netif
*
netif
,
const
ip4_addr_t
*
ipaddr
,
struct
eth_addr
*
ethaddr
,
u8_t
flags
)
{
{
// FIXME
return
0
;
return
0
;
}
}
err_t
etharp_delete_arp_entry
(
struct
netif
*
netif
,
ip4_addr_t
*
ipaddr
)
err_t
etharp_delete_arp_entry
(
struct
netif
*
netif
,
ip4_addr_t
*
ipaddr
)
{
{
// FIXME
return
0
;
return
0
;
}
}
err_t
lwip_dns_setserver
(
u8_t
numdns
,
ip_addr_t
*
dnsserver
)
err_t
lwip_dns_setserver
(
u8_t
numdns
,
ip_addr_t
*
dnsserver
)
{
{
// FIXME
return
0
;
return
0
;
}
}
err_t
lwip_dns_getserver
(
u8_t
numdns
,
ip_addr_t
*
dnsserver
)
err_t
lwip_dns_getserver
(
u8_t
numdns
,
ip_addr_t
*
dnsserver
)
{
{
// FIXME
return
0
;
return
0
;
}
}
...
@@ -354,57 +354,42 @@ err_t lwip_dns_getserver(u8_t numdns, ip_addr_t *dnsserver)
...
@@ -354,57 +354,42 @@ err_t lwip_dns_getserver(u8_t numdns, ip_addr_t *dnsserver)
struct
raw_pcb
*
pkt_raw_pcbs
;
struct
raw_pcb
*
pkt_raw_pcbs
;
#endif
#endif
struct
raw_pcb
*
raw_pcbs
;
#if LWIP_RAW
struct
raw_pcb
*
raw_pcbs
;
/* already defined in raw.c, but is static */
#endif
/******************************************************************/
#if LWIP_ENABLE_IP_CONFLICT_SIGNAL
#if LWIP_ENABLE_IP_CONFLICT_SIGNAL
u32_t
is_ip_conflict_signal
=
0
;
u32_t
is_ip_conflict_signal
=
0
;
sys_sem_t
ip_conflict_detect
;
sys_sem_t
ip_conflict_detect
;
#endif
#endif
u32_t
is_dup_detect_initialized
=
0
;
u32_t
is_dup_detect_initialized
=
0
;
sys_sem_t
dup_addr_detect
;
sys_sem_t
dup_addr_detect
;
int
lwip_sntp_start
(
int
server_num
,
char
**
sntp_server
,
struct
timeval
*
time
)
#if LWIP_SNTP
{
return
0
;
}
u32_t
lwip_tftp_get_file_by_filename
(
u32_t
ulHostAddr
,
#include <time.h>
u16_t
usTftpServPort
,
u8_t
ucTftpTransMode
,
s8_t
*
szSrcFileName
,
s8_t
*
szDestDirPath
)
{
return
0
;
}
u32_t
lwip_tftp_put_file_by_filename
(
u32_t
ulHostAddr
,
int
lwip_sntp_start
(
int
server_num
,
char
**
sntp_server
,
struct
timeval
*
time
)
u16_t
usTftpServPort
,
u8_t
cTftpTransMode
,
s8_t
*
szSrcFileName
,
s8_t
*
szDestDirPath
)
{
{
// FIXME
return
0
;
return
0
;
}
}
#endif
const
char
*
const
tcp_state_str
[]
=
{
const
char
*
const
tcp_state_str
[]
=
{
"CLOSED"
,
"CLOSED"
,
"LISTEN"
,
"LISTEN"
,
"SYN_SENT"
,
"SYN_SENT"
,
"SYN_RCVD"
,
"SYN_RCVD"
,
"ESTABLISHED"
,
"ESTABLISHED"
,
"FIN_WAIT_1"
,
"FIN_WAIT_1"
,
"FIN_WAIT_2"
,
"FIN_WAIT_2"
,
"CLOSE_WAIT"
,
"CLOSE_WAIT"
,
"CLOSING"
,
"CLOSING"
,
"LAST_ACK"
,
"LAST_ACK"
,
"TIME_WAIT"
"TIME_WAIT"
};
};
volatile
int
tcpip_init_finish
=
1
;
// needed by api_shell.c
volatile
int
tcpip_init_finish
=
1
;
// needed by api_shell.c
#endif
net/lwip-2.1/enhancement/src/tftpc.c
0 → 100644
浏览文件 @
4f55f678
/*
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* TFTP Client utility */
#include "lwip/opt.h"
#if LWIP_TFTP
/* don't build if not configured for use in lwipopts.h */
#include "lwip/tcpip.h"
#include "lwip/netif.h"
#include "lwip/mem.h"
#include "lwip/err.h"
#include "lwip/inet.h"
#include "netif/etharp.h"
#include "lwip/ip_addr.h"
#include "lwip/sockets.h"
#include "lwip/udp.h"
#include "lwip/ip_addr.h"
#include "lwip/netif.h"
#include "lwip/def.h"
#include "lwip/tftpc.h"
#include "fcntl.h"
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
/* Function Declarations */
#ifdef LOSCFG_NET_LWIP_SACK_TFTP
static
u32_t
lwip_tftp_create_bind_socket
(
s32_t
*
piSocketID
);
static
s32_t
lwip_tftp_make_tftp_packet
(
u16_t
usOpcode
,
s8_t
*
szFileName
,
u32_t
ulMode
,
TFTPC_PACKET_S
*
pstPacket
);
static
u32_t
lwip_tftp_recv_from_server
(
s32_t
iSockNum
,
u32_t
*
pulSize
,
TFTPC_PACKET_S
*
pstRecvBuf
,
u32_t
*
pulIgnorePkt
,
struct
sockaddr_in
*
pstServerAddr
,
TFTPC_PACKET_S
*
pstSendBuf
);
static
u32_t
lwip_tftp_send_to_server
(
s32_t
iSockNum
,
u32_t
ulSize
,
TFTPC_PACKET_S
*
pstSendBuf
,
struct
sockaddr_in
*
pstServerAddr
);
static
u32_t
lwip_tftp_validate_data_pkt
(
s32_t
iSockNum
,
u32_t
*
pulSize
,
TFTPC_PACKET_S
*
pstRecvBuf
,
u16_t
usCurrBlk
,
u32_t
*
pulResendPkt
,
struct
sockaddr_in
*
pstServerAddr
);
static
u32_t
lwip_tftp_inner_put_file
(
s32_t
iSockNum
,
TFTPC_PACKET_S
*
pstSendBuf
,
u32_t
ulSendSize
,
u16_t
usCurrBlk
,
struct
sockaddr_in
*
pstServerAddr
);
static
void
lwip_tftp_send_error
(
s32_t
iSockNum
,
u32_t
ulError
,
const
char
*
szErrMsg
,
struct
sockaddr_in
*
pstServerAddr
,
TFTPC_PACKET_S
*
pstSendBuf
);
/* Create and bind a UDP socket. */
u32_t
lwip_tftp_create_bind_socket
(
s32_t
*
piSocketID
)
{
int
retval
;
struct
sockaddr_in
stClientAddr
;
u32_t
ulTempClientIp
;
u32_t
set_non_block_socket
=
1
;
/* create a socket */
*
piSocketID
=
lwip_socket
(
PF_INET
,
SOCK_DGRAM
,
IPPROTO_UDP
);
if
(
*
piSocketID
==
-
1
)
{
LWIP_DEBUGF
(
TFTP_DEBUG
,
(
"lwip_tftp_create_bind_socket : lwip_socket create socket failed
\n
"
));
return
TFTPC_SOCKET_FAILURE
;
}
/* Make the socket as NON-BLOCKING. */
retval
=
lwip_ioctl
(
*
piSocketID
,
(
long
)
FIONBIO
,
&
set_non_block_socket
);
if
(
retval
!=
0
)
{
(
void
)
lwip_close
(
*
piSocketID
);
*
piSocketID
=
TFTP_NULL_INT32
;
return
TFTPC_IOCTLSOCKET_FAILURE
;
}
ulTempClientIp
=
INADDR_ANY
;
/* specify a local address for this socket */
(
void
)
memset_s
(
&
stClientAddr
,
sizeof
(
stClientAddr
),
0
,
sizeof
(
stClientAddr
));
stClientAddr
.
sin_family
=
AF_INET
;
stClientAddr
.
sin_port
=
0
;
stClientAddr
.
sin_addr
.
s_addr
=
htonl
(
ulTempClientIp
);
retval
=
lwip_bind
(
*
piSocketID
,
(
struct
sockaddr
*
)
&
stClientAddr
,
sizeof
(
stClientAddr
));
if
(
retval
!=
0
)
{
(
void
)
lwip_close
(
*
piSocketID
);
*
piSocketID
=
TFTP_NULL_INT32
;
return
TFTPC_BIND_FAILURE
;
}
return
ERR_OK
;
}
/* Function to create TFTP packet.
usOpcode - indiacting the nature of the operation
pFileName -filename on which the operation needs to done
ulMode -mode in which the operation needs to done
pstPacket - packet generated
Returns packet address on success
*/
static
s32_t
lwip_tftp_make_tftp_packet
(
u16_t
usOpcode
,
s8_t
*
szFileName
,
u32_t
ulMode
,
TFTPC_PACKET_S
*
pstPacket
)
{
s8_t
*
pcCp
=
NULL
;
pstPacket
->
usOpcode
=
htons
(
usOpcode
);
pcCp
=
pstPacket
->
u
.
ucName_Mode
;
/* Request packet format is:
| Opcode | Filename | 0 | Mode | 0 |
*/
(
void
)
strncpy_s
((
char
*
)
pcCp
,
TFTP_MAX_PATH_LENGTH
,
(
char
*
)
szFileName
,
(
TFTP_MAX_PATH_LENGTH
-
1
));
pcCp
[(
TFTP_MAX_PATH_LENGTH
-
1
)]
=
'\0'
;
pcCp
+=
(
strlen
((
char
*
)
szFileName
)
+
1
);
if
(
ulMode
==
TRANSFER_MODE_BINARY
)
{
(
void
)
strncpy_s
((
char
*
)
pcCp
,
TFTP_MAX_MODE_SIZE
,
"octet"
,
(
TFTP_MAX_MODE_SIZE
-
1
));
pcCp
[(
TFTP_MAX_MODE_SIZE
-
1
)]
=
'\0'
;
}
else
if
(
ulMode
==
TRANSFER_MODE_ASCII
)
{
(
void
)
strncpy_s
((
char
*
)
pcCp
,
TFTP_MAX_MODE_SIZE
,
"netascii"
,
(
TFTP_MAX_MODE_SIZE
-
1
));
pcCp
[(
TFTP_MAX_MODE_SIZE
-
1
)]
=
'\0'
;
}
pcCp
+=
(
strlen
((
char
*
)
pcCp
)
+
1
);
return
(
pcCp
-
(
s8_t
*
)
pstPacket
);
}
/* Function to recv a packet from server
iSockNum - Socket Number
pstServerAddr - Server address
pulIgnorePkt - Ignore packet flag
pstRecvBuf - received packet
pulSize - Size of the packet
*/
u32_t
lwip_tftp_recv_from_server
(
s32_t
iSockNum
,
u32_t
*
pulSize
,
TFTPC_PACKET_S
*
pstRecvBuf
,
u32_t
*
pulIgnorePkt
,
struct
sockaddr_in
*
pstServerAddr
,
TFTPC_PACKET_S
*
pstSendBuf
)
{
u32_t
ulError
;
socklen_t
slFromAddrLen
;
struct
sockaddr_in
stFromAddr
;
fd_set
stReadfds
;
struct
timeval
stTimeout
;
u16_t
usOpcode
;
/* Opcode value */
s32_t
iRet
;
slFromAddrLen
=
sizeof
(
stFromAddr
);
stTimeout
.
tv_sec
=
TFTPC_TIMEOUT_PERIOD
;
stTimeout
.
tv_usec
=
0
;
/* wait for DATA packet */
FD_ZERO
(
&
stReadfds
);
FD_SET
(
iSockNum
,
&
stReadfds
);
iRet
=
select
((
s32_t
)(
iSockNum
+
1
),
&
stReadfds
,
0
,
0
,
&
stTimeout
);
if
(
iRet
==
-
1
)
{
return
TFTPC_SELECT_ERROR
;
}
else
if
(
iRet
==
0
)
{
return
TFTPC_TIMEOUT_ERROR
;
/* Select timeout occured */
}
if
(
!
FD_ISSET
(
iSockNum
,
&
stReadfds
))
{
return
TFTPC_TIMEOUT_ERROR
;
/* FD not set*/
}
/* receive a packet from server */
iRet
=
lwip_recvfrom
(
iSockNum
,
(
s8_t
*
)
pstRecvBuf
,
TFTP_PKTSIZE
,
0
,
(
struct
sockaddr
*
)
&
stFromAddr
,
&
slFromAddrLen
);
if
(
iRet
<=
0
)
{
return
TFTPC_RECVFROM_ERROR
;
}
/* If received packet size < minimum packet size */
if
(
iRet
<
TFTPC_FOUR
)
{
/* Send Error packet to server */
lwip_tftp_send_error
(
iSockNum
,
TFTPC_PROTOCOL_PROTO_ERROR
,
"Packet size < min size"
,
pstServerAddr
,
pstSendBuf
);
return
TFTPC_PKT_SIZE_ERROR
;
}
/* convert network opcode to host format after receive. */
usOpcode
=
ntohs
(
pstRecvBuf
->
usOpcode
);
/* if this packet is ERROR packet */
if
(
usOpcode
==
TFTPC_OP_ERROR
)
{
ulError
=
ntohs
(
pstRecvBuf
->
u
.
stTFTP_Err
.
usErrNum
);
/*If the error is according to RFC,then convert to lwip error codes.
Constant values are used in the cases as these error codes are as per
the RFC, these are constant values returned by many standard TFTP
serevrs.*/
switch
(
ulError
)
{
case
TFTPC_PROTOCOL_USER_DEFINED
:
ulError
=
TFTPC_ERROR_NOT_DEFINED
;
break
;
case
TFTPC_PROTOCOL_FILE_NOT_FOUND
:
ulError
=
TFTPC_FILE_NOT_FOUND
;
break
;
case
TFTPC_PROTOCOL_ACCESS_ERROR
:
ulError
=
TFTPC_ACCESS_ERROR
;
break
;
case
TFTPC_PROTOCOL_DISK_FULL
:
ulError
=
TFTPC_DISK_FULL
;
break
;
case
TFTPC_PROTOCOL_PROTO_ERROR
:
ulError
=
TFTPC_PROTO_ERROR
;
break
;
case
TFTPC_PROTOCOL_UNKNOWN_TRANSFER_ID
:
ulError
=
TFTPC_UNKNOWN_TRANSFER_ID
;
break
;
case
TFTPC_PROTOCOL_FILE_EXISTS
:
ulError
=
TFTPC_FILE_EXISTS
;
break
;
case
TFTPC_PROTOCOL_CANNOT_RESOLVE_HOSTNAME
:
ulError
=
TFTPC_CANNOT_RESOLVE_HOSTNAME
;
break
;
default:
ulError
=
TFTPC_ERROR_NOT_DEFINED
;
break
;
}
/* If length of error msg > 100 chars */
pstRecvBuf
->
u
.
stTFTP_Err
.
ucErrMesg
[
TFTP_MAXERRSTRSIZE
-
1
]
=
'\0'
;
LWIP_DEBUGF
(
TFTP_DEBUG
,
(
"lwip_tftp_recv_from_server : ERROR pkt received: %s
\n
"
,
pstRecvBuf
->
u
.
stTFTP_Err
.
ucErrMesg
));
/* Now we get error block, so return. */
return
ulError
;
}
/* Store the size of received block */
*
pulSize
=
(
u32_t
)
iRet
;
/* If received packet is first block of data(for get operation) or if
received packet is acknowledgement for write request (put operation)
store the received port number */
if
(((
usOpcode
==
TFTPC_OP_DATA
)
&&
(
ntohs
(
pstRecvBuf
->
u
.
stTFTP_Data
.
usBlknum
)
==
1
))
||
((
usOpcode
==
TFTPC_OP_ACK
)
&&
(
ntohs
(
pstRecvBuf
->
u
.
usBlknum
)
==
0
)))
{
/* If received packet from correct server */
if
(
stFromAddr
.
sin_addr
.
s_addr
==
pstServerAddr
->
sin_addr
.
s_addr
)
{
/* set the server port to received port */
pstServerAddr
->
sin_port
=
stFromAddr
.
sin_port
;
}
else
{
/* Received packet form wrong server. */
LWIP_DEBUGF
(
TFTP_DEBUG
,
(
"lwip_tftp_recv_from_server : Received 1st packet from wrong Server or unknown server
\n
"
));
/* Set ignore packet flag */
*
pulIgnorePkt
=
1
;
}
}
else
{
/* If not first packet, check if the received packet is from correct
server and from correct port */
if
((
stFromAddr
.
sin_addr
.
s_addr
!=
pstServerAddr
->
sin_addr
.
s_addr
)
||
(
pstServerAddr
->
sin_port
!=
stFromAddr
.
sin_port
))
{
/* Received packet form wrong server or wrong port.Ignore packet. */
LWIP_DEBUGF
(
TFTP_DEBUG
,
(
"lwip_tftp_recv_from_server : Received a packet from wrong Server or unknown server
\n
"
));
/* Set ignore packet flag */
*
pulIgnorePkt
=
1
;
}
}
return
ERR_OK
;
}
/* Function to send a packet to server
iSockNum: Socket Number
ulSize: Size of the packet
pstSendBuf: Packet to send
pstServerAddr: Server address
*/
u32_t
lwip_tftp_send_to_server
(
s32_t
iSockNum
,
u32_t
ulSize
,
TFTPC_PACKET_S
*
pstSendBuf
,
struct
sockaddr_in
*
pstServerAddr
)
{
s32_t
iRet
;
/* Send packet to server */
iRet
=
lwip_sendto
(
iSockNum
,
(
s8_t
*
)
pstSendBuf
,
(
size_t
)
ulSize
,
0
,
(
struct
sockaddr
*
)
pstServerAddr
,
sizeof
(
struct
sockaddr_in
));
/* Size of data sent not equal to size of packet */
if
((
iRet
==
TFTP_NULL_INT32
)
||
((
u32_t
)
iRet
!=
ulSize
))
{
return
TFTPC_SENDTO_ERROR
;
}
return
ERR_OK
;
}
/* lwip_tftp_validate_data_pkt
* Get the data block from the received packet
* @param Input iSockNum Socket Number
* pulSize: Size of received packet,
pstRecvBuf - received packet
usCurrBlk - Current block number
* @param Output pulResendPkt - Resend packet flag
* @return VOS_OK on success.else error code*/
u32_t
lwip_tftp_validate_data_pkt
(
s32_t
iSockNum
,
u32_t
*
pulSize
,
TFTPC_PACKET_S
*
pstRecvBuf
,
u16_t
usCurrBlk
,
u32_t
*
pulResendPkt
,
struct
sockaddr_in
*
pstServerAddr
)
{
fd_set
stReadfds
;
struct
timeval
stTimeout
;
struct
sockaddr_in
stFromAddr
;
socklen_t
ulFromAddrLen
;
s32_t
iRecvLen
=
(
s32_t
)
*
pulSize
;
s32_t
iError
;
u16_t
usBlknum
;
u32_t
ulLoopCnt
=
0
;
ulFromAddrLen
=
sizeof
(
stFromAddr
);
/* Initialize from address to the server address at first */
if
(
memcpy_s
((
void
*
)
&
stFromAddr
,
sizeof
(
struct
sockaddr_in
),
(
void
*
)
pstServerAddr
,
sizeof
(
stFromAddr
))
!=
0
)
{
LWIP_DEBUGF
(
TFTP_DEBUG
,
(
"lwip_tftp_validate_data_pkt : memcpy_s error
\n
"
));
return
TFTPC_MEMCPY_FAILURE
;
}
/* Get Block Number */
usBlknum
=
ntohs
(
pstRecvBuf
->
u
.
stTFTP_Data
.
usBlknum
);
/* Now data blocks are not in sync. */
if
(
usBlknum
!=
usCurrBlk
)
{
/* Set timeout value */
stTimeout
.
tv_sec
=
1
;
stTimeout
.
tv_usec
=
0
;
/* Reset any stored packets. */
FD_ZERO
(
&
stReadfds
);
FD_SET
(
iSockNum
,
&
stReadfds
);
iError
=
select
((
s32_t
)(
iSockNum
+
1
),
&
stReadfds
,
0
,
0
,
&
stTimeout
);
/* Loop to get the last data packet from the receive buffer */
while
((
iError
!=
TFTP_NULL_INT32
)
&&
(
iError
!=
0
))
{
ulLoopCnt
++
;
/* MAX file size in TFTP is 32 MB.
Reason for keeping 75 here , is ((75*512=38400bytes)/1024) = 37MB. So the recv/Send
Loop can receive the complete MAX message from the network.
*/
if
(
ulLoopCnt
>
TFTPC_MAX_WAIT_IN_LOOP
)
{
LWIP_DEBUGF
(
TFTP_DEBUG
,
(
"lwip_tftp_validate_data_pkt : unexpected packets are received repeatedly
\n
"
));
*
pulSize
=
TFTP_NULL_UINT32
;
return
TFTPC_PKT_SIZE_ERROR
;
}
FD_ZERO
(
&
stReadfds
);
FD_SET
(
iSockNum
,
&
stReadfds
);
iRecvLen
=
lwip_recvfrom
(
iSockNum
,
(
s8_t
*
)
pstRecvBuf
,
TFTP_PKTSIZE
,
0
,
(
struct
sockaddr
*
)
&
stFromAddr
,
&
ulFromAddrLen
);
if
(
iRecvLen
==
-
1
)
{
*
pulSize
=
TFTP_NULL_UINT32
;
/* return from the function, recvfrom operation failed */
return
TFTPC_RECVFROM_ERROR
;
}
stTimeout
.
tv_sec
=
1
;
stTimeout
.
tv_usec
=
0
;
iError
=
select
((
s32_t
)(
iSockNum
+
1
),
&
stReadfds
,
0
,
0
,
&
stTimeout
);
}
/* If received packet size < minimum packet size */
if
(
iRecvLen
<
TFTPC_FOUR
)
{
return
TFTPC_PKT_SIZE_ERROR
;
}
/* Check if the received packet is from correct server and from
correct port
*/
if
((
stFromAddr
.
sin_addr
.
s_addr
!=
pstServerAddr
->
sin_addr
.
s_addr
)
||
(
pstServerAddr
->
sin_port
!=
stFromAddr
.
sin_port
))
{
/* resend ack packet */
*
pulResendPkt
=
1
;
LWIP_DEBUGF
(
TFTP_DEBUG
,
(
"lwip_tftp_validate_data_pkt : Received pkt from unknown server
\n
"
));
return
ERR_OK
;
}
/* if this packet is not DATA packet */
if
(
TFTPC_OP_DATA
!=
ntohs
(
pstRecvBuf
->
usOpcode
))
{
LWIP_DEBUGF
(
TFTP_DEBUG
,
(
"lwip_tftp_validate_data_pkt : Received pkt not a DATA pkt
\n
"
));
/* return from the function, incorrect packet received,
expected packet is data packet */
return
TFTPC_PROTO_ERROR
;
}
usBlknum
=
ntohs
(
pstRecvBuf
->
u
.
stTFTP_Data
.
usBlknum
);
/* if we now have the earlier data packet, then the host probably
never got our acknowledge packet, now we will send it again. */
if
(
usBlknum
==
(
usCurrBlk
-
1
))
{
/* resend ack packet */
*
pulResendPkt
=
1
;
LWIP_DEBUGF
(
TFTP_DEBUG
,
(
"lwip_tftp_validate_data_pkt : Received previous DATA pkt
\n
"
));
return
ERR_OK
;
}
/* If the block of data received is not current block or also
previous block, then it is abnormal case. */
if
(
usBlknum
!=
usCurrBlk
)
{
LWIP_DEBUGF
(
TFTP_DEBUG
,
(
"lwip_tftp_validate_data_pkt : Received DATA pkt no. %"
S32_F
" instead of pkt no.%"
S32_F
"
\n
"
,
usBlknum
,
usCurrBlk
));
return
TFTPC_SYNC_FAILURE
;
}
}
*
pulSize
=
(
u32_t
)
iRecvLen
;
return
ERR_OK
;
}
/* Send an error packet to the server
iSockNum : Socket Number
ulError: Error code
szErrMsg - Error message
pstServerAddr - Server address
*/
static
void
lwip_tftp_send_error
(
s32_t
iSockNum
,
u32_t
ulError
,
const
char
*
szErrMsg
,
struct
sockaddr_in
*
pstServerAddr
,
TFTPC_PACKET_S
*
pstSendBuf
)
{
u16_t
usOpCode
=
TFTPC_OP_ERROR
;
if
(
memset_s
((
void
*
)
pstSendBuf
,
sizeof
(
TFTPC_PACKET_S
),
0
,
sizeof
(
TFTPC_PACKET_S
))
!=
0
)
{
LWIP_DEBUGF
(
TFTP_DEBUG
,
(
"lwip_tftp_send_error : memset_s error
\n
"
));
return
;
}
/* Set up the send buffer */
pstSendBuf
->
usOpcode
=
htons
(
usOpCode
);
pstSendBuf
->
u
.
stTFTP_Err
.
usErrNum
=
htons
((
u16_t
)
ulError
);
if
(
strncpy_s
((
char
*
)(
pstSendBuf
->
u
.
stTFTP_Err
.
ucErrMesg
),
TFTP_MAXERRSTRSIZE
,
(
char
*
)
szErrMsg
,
(
TFTP_MAXERRSTRSIZE
-
1
))
!=
EOK
)
{
LWIP_DEBUGF
(
TFTP_DEBUG
,
(
"lwip_tftp_send_error : strncpy_s error
\n
"
));
return
;
}
pstSendBuf
->
u
.
stTFTP_Err
.
ucErrMesg
[(
TFTP_MAXERRSTRSIZE
-
1
)]
=
'\0'
;
/* Send to server */
if
(
lwip_tftp_send_to_server
(
iSockNum
,
sizeof
(
TFTPC_PACKET_S
),
pstSendBuf
,
pstServerAddr
)
!=
ERR_OK
)
{
LWIP_DEBUGF
(
TFTP_DEBUG
,
(
"lwip_tftp_send_to_server error."
));
return
;
}
}
/* INTEFACE to get a file using filename
ulHostAddr - IP address of Host
szSrcFileName - Source file
szDestDirPath - Destination file path
*/
u32_t
lwip_tftp_get_file_by_filename
(
u32_t
ulHostAddr
,
u16_t
usTftpServPort
,
u8_t
ucTftpTransMode
,
s8_t
*
szSrcFileName
,
s8_t
*
szDestDirPath
)
{
s32_t
iSockNum
=
TFTP_NULL_INT32
;
u32_t
ulSrcStrLen
;
u32_t
ulDestStrLen
;
u32_t
ulSize
;
u32_t
ulRecvSize
=
TFTP_NULL_UINT32
;
s32_t
iErrCode
;
u32_t
ulErrCode
;
u16_t
usReadReq
;
u16_t
usTempServPort
;
s8_t
*
pszTempDestName
=
NULL
;
s8_t
*
szTempSrcName
=
NULL
;
u32_t
ulCurrBlk
=
1
;
u32_t
ulResendPkt
=
0
;
/*Resend the previous packet*/
u32_t
ulIgnorePkt
=
0
;
/*Ignore received packet*/
u32_t
ulTotalTime
=
0
;
u32_t
isLocalFileOpened
=
false
;
TFTPC_PACKET_S
*
pstSendBuf
=
NULL
;
TFTPC_PACKET_S
*
pstRecvBuf
=
NULL
;
struct
sockaddr_in
stServerAddr
;
struct
stat
sb
;
u32_t
IsDirExist
=
0
;
s32_t
fp
=
-
1
;
/*Validate the parameters*/
if
((
szSrcFileName
==
NULL
)
||
(
szDestDirPath
==
NULL
))
{
return
TFTPC_INVALID_PARAVALUE
;
}
if
((
ucTftpTransMode
!=
TRANSFER_MODE_BINARY
)
&&
(
ucTftpTransMode
!=
TRANSFER_MODE_ASCII
))
{
return
TFTPC_INVALID_PARAVALUE
;
}
/*check IP address not within ( 1.0.0.0 - 126.255.255.255 )
and ( 128.0.0.0 - 223.255.255.255 ) range.*/
if
(
!
(((
ulHostAddr
>=
TFTPC_IP_ADDR_MIN
)
&&
(
ulHostAddr
<=
TFTPC_IP_ADDR_EX_RESV
))
||
((
ulHostAddr
>=
TFTPC_IP_ADDR_CLASS_B
)
&&
(
ulHostAddr
<=
TFTPC_IP_ADDR_EX_CLASS_DE
))))
{
return
TFTPC_IP_NOT_WITHIN_RANGE
;
}
/*Check validity of source filename*/
ulSrcStrLen
=
strlen
((
char
*
)
szSrcFileName
);
if
((
ulSrcStrLen
==
0
)
||
(
ulSrcStrLen
>=
TFTP_MAX_PATH_LENGTH
))
{
return
TFTPC_SRC_FILENAME_LENGTH_ERROR
;
}
/*Check validity of destination path*/
ulDestStrLen
=
strlen
((
char
*
)
szDestDirPath
);
if
((
ulDestStrLen
>=
TFTP_MAX_PATH_LENGTH
)
||
(
ulDestStrLen
==
0
))
{
return
TFTPC_DEST_PATH_LENGTH_ERROR
;
}
pstSendBuf
=
(
TFTPC_PACKET_S
*
)
mem_malloc
(
sizeof
(
TFTPC_PACKET_S
));
if
(
pstSendBuf
==
NULL
)
{
return
TFTPC_MEMALLOC_ERROR
;
}
pstRecvBuf
=
(
TFTPC_PACKET_S
*
)
mem_malloc
(
sizeof
(
TFTPC_PACKET_S
));
if
(
pstRecvBuf
==
NULL
)
{
mem_free
(
pstSendBuf
);
return
TFTPC_MEMALLOC_ERROR
;
}
pszTempDestName
=
(
s8_t
*
)
mem_malloc
(
TFTP_MAX_PATH_LENGTH
);
if
(
pszTempDestName
==
NULL
)
{
mem_free
(
pstSendBuf
);
mem_free
(
pstRecvBuf
);
return
TFTPC_MEMALLOC_ERROR
;
}
/* First time initialize the buffers */
(
void
)
memset_s
((
void
*
)
pstSendBuf
,
sizeof
(
TFTPC_PACKET_S
),
0
,
sizeof
(
TFTPC_PACKET_S
));
(
void
)
memset_s
((
void
*
)
pstRecvBuf
,
sizeof
(
TFTPC_PACKET_S
),
0
,
sizeof
(
TFTPC_PACKET_S
));
/*If given src filename is a relative path extract
the file name from the path*/
if
((
0
!=
strchr
((
char
*
)
szSrcFileName
,
'/'
))
||
(
0
!=
strchr
((
char
*
)
szSrcFileName
,
'\\'
)))
{
/*Move to the end of the src file path*/
szTempSrcName
=
szSrcFileName
+
(
ulSrcStrLen
-
1
);
while
(((
*
(
szTempSrcName
-
1
)
!=
'/'
)
&&
(
*
(
szTempSrcName
-
1
)
!=
'\\'
))
&&
(
szTempSrcName
!=
szSrcFileName
))
{
szTempSrcName
--
;
}
/*Get length of the extracted src filename*/
ulSrcStrLen
=
strlen
((
char
*
)
szTempSrcName
);
}
else
{
/*If not a relative src path use the given src filename*/
szTempSrcName
=
szSrcFileName
;
}
(
void
)
memset_s
(
pszTempDestName
,
TFTP_MAX_PATH_LENGTH
,
0
,
TFTP_MAX_PATH_LENGTH
);
if
(
strncpy_s
((
char
*
)
pszTempDestName
,
TFTP_MAX_PATH_LENGTH
,
(
char
*
)
szDestDirPath
,
TFTP_MAX_PATH_LENGTH
-
1
)
!=
0
)
{
ulErrCode
=
TFTPC_MEMCPY_FAILURE
;
goto
err_handler
;
}
pszTempDestName
[
TFTP_MAX_PATH_LENGTH
-
1
]
=
'\0'
;
if
(
stat
((
char
*
)
pszTempDestName
,
&
sb
)
==
0
&&
S_ISDIR
(
sb
.
st_mode
))
{
IsDirExist
=
1
;
}
if
(
IsDirExist
==
1
)
{
/*The filename is not present concat source filename and try*/
if
((
ulDestStrLen
+
ulSrcStrLen
)
>=
TFTP_MAX_PATH_LENGTH
)
{
/*If concatenating src filename exceeds 256 bytes*/
ulErrCode
=
TFTPC_DEST_PATH_LENGTH_ERROR
;
goto
err_handler
;
}
/*Check if / present at end of string*/
if
((
pszTempDestName
[
ulDestStrLen
-
1
]
!=
'/'
)
&&
(
pszTempDestName
[
ulDestStrLen
-
1
]
!=
'\\'
))
{
if
((
ulDestStrLen
+
ulSrcStrLen
+
1
)
>=
TFTP_MAX_PATH_LENGTH
)
{
/*If concatenating src filename exceeds 256 bytes*/
ulErrCode
=
TFTPC_DEST_PATH_LENGTH_ERROR
;
goto
err_handler
;
}
/*If not present concat / to the path*/
if
(
strncat_s
((
char
*
)
pszTempDestName
,
(
TFTP_MAX_PATH_LENGTH
-
strlen
((
char
*
)
pszTempDestName
)),
"/"
,
TFTP_MAX_PATH_LENGTH
-
strlen
((
char
*
)
pszTempDestName
)
-
1
)
!=
0
)
{
ulErrCode
=
TFTPC_ERROR_NOT_DEFINED
;
goto
err_handler
;
}
}
/*Concatenate src filename to destination path*/
if
(
strncat_s
((
char
*
)
pszTempDestName
,
(
TFTP_MAX_PATH_LENGTH
-
strlen
((
char
*
)
pszTempDestName
)),
(
char
*
)
szTempSrcName
,
TFTP_MAX_PATH_LENGTH
-
strlen
((
char
*
)
pszTempDestName
)
-
1
)
!=
0
)
{
ulErrCode
=
TFTPC_ERROR_NOT_DEFINED
;
goto
err_handler
;
}
}
ulErrCode
=
lwip_tftp_create_bind_socket
(
&
iSockNum
);
if
(
ulErrCode
!=
ERR_OK
)
{
goto
err_handler
;
}
if
(
usTftpServPort
==
0
)
{
usTftpServPort
=
TFTPC_SERVER_PORT
;
}
usTempServPort
=
usTftpServPort
;
/* set server IP address */
(
void
)
memset_s
(
&
stServerAddr
,
sizeof
(
stServerAddr
),
0
,
sizeof
(
stServerAddr
));
stServerAddr
.
sin_family
=
AF_INET
;
stServerAddr
.
sin_port
=
htons
(
usTempServPort
);
stServerAddr
.
sin_addr
.
s_addr
=
htonl
(
ulHostAddr
);
/* Make a request packet - TFTPC_OP_RRQ */
ulSize
=
(
u32_t
)
lwip_tftp_make_tftp_packet
(
TFTPC_OP_RRQ
,
szSrcFileName
,
(
u32_t
)
ucTftpTransMode
,
pstSendBuf
);
ulErrCode
=
lwip_tftp_send_to_server
(
iSockNum
,
ulSize
,
pstSendBuf
,
&
stServerAddr
);
if
(
ulErrCode
!=
ERR_OK
)
{
/* send to server failed */
(
void
)
lwip_close
(
iSockNum
);
goto
err_handler
;
}
for
(;;)
{
if
(
ulIgnorePkt
>
0
)
{
ulIgnorePkt
=
0
;
}
ulErrCode
=
lwip_tftp_recv_from_server
(
iSockNum
,
&
ulRecvSize
,
pstRecvBuf
,
&
ulIgnorePkt
,
&
stServerAddr
,
pstSendBuf
);
/* If select timeout occured */
if
(
ulErrCode
==
TFTPC_TIMEOUT_ERROR
)
{
ulTotalTime
++
;
if
(
ulTotalTime
<
TFTPC_MAX_SEND_REQ_ATTEMPTS
)
{
/* Max attempts not reached. Resend packet */
ulErrCode
=
lwip_tftp_send_to_server
(
iSockNum
,
ulSize
,
pstSendBuf
,
&
stServerAddr
);
if
(
ulErrCode
!=
ERR_OK
)
{
(
void
)
lwip_close
(
iSockNum
);
if
(
isLocalFileOpened
==
true
)
{
close
(
fp
);
}
goto
err_handler
;
}
continue
;
}
else
{
/* return from the function, max attempts limit reached */
(
void
)
lwip_close
(
iSockNum
);
if
(
isLocalFileOpened
==
true
)
{
close
(
fp
);
}
ulErrCode
=
TFTPC_TIMEOUT_ERROR
;
goto
err_handler
;
}
}
else
if
(
ulErrCode
!=
ERR_OK
)
{
(
void
)
lwip_close
(
iSockNum
);
if
(
isLocalFileOpened
==
true
)
{
close
(
fp
);
}
goto
err_handler
;
}
/* Now we have receive block from different server. */
if
(
ulIgnorePkt
>
0
)
{
/*Continue without processing this block. */
continue
;
}
/* if this packet is unkonwn or incorrect packet */
if
(
ntohs
(
pstRecvBuf
->
usOpcode
)
!=
TFTPC_OP_DATA
)
{
/* Send error packet to server */
lwip_tftp_send_error
(
iSockNum
,
TFTPC_PROTOCOL_PROTO_ERROR
,
"Protocol error."
,
&
stServerAddr
,
pstSendBuf
);
(
void
)
lwip_close
(
iSockNum
);
if
(
isLocalFileOpened
==
true
)
{
close
(
fp
);
}
LWIP_DEBUGF
(
TFTP_DEBUG
,
(
"lwip_tftp_get_file_by_filename : Received pkt not DATA pkt
\n
"
));
ulErrCode
=
TFTPC_PROTO_ERROR
;
goto
err_handler
;
}
/* Now the number of tries will be reset. */
ulTotalTime
=
0
;
/* Validate received DATA packet. */
ulErrCode
=
lwip_tftp_validate_data_pkt
(
iSockNum
,
&
ulRecvSize
,
pstRecvBuf
,
(
u16_t
)
ulCurrBlk
,
&
ulResendPkt
,
&
stServerAddr
);
if
(
ulErrCode
!=
ERR_OK
)
{
/* Send Error packet to server */
if
(
ulErrCode
!=
TFTPC_RECVFROM_ERROR
)
{
lwip_tftp_send_error
(
iSockNum
,
TFTPC_PROTOCOL_PROTO_ERROR
,
"Received unexpected packet"
,
&
stServerAddr
,
pstSendBuf
);
}
(
void
)
lwip_close
(
iSockNum
);
if
(
isLocalFileOpened
==
true
)
{
close
(
fp
);
}
goto
err_handler
;
}
/* Received previous data block again. Resend last packet */
if
(
ulResendPkt
>
0
)
{
/* Now set ulResendPkt to 0 to send the last packet. */
ulResendPkt
=
0
;
ulErrCode
=
lwip_tftp_send_to_server
(
iSockNum
,
ulSize
,
pstSendBuf
,
&
stServerAddr
);
if
(
ulErrCode
!=
ERR_OK
)
{
(
void
)
lwip_close
(
iSockNum
);
if
(
isLocalFileOpened
==
true
)
{
close
(
fp
);
}
goto
err_handler
;
}
/* Continue in loop to send last packet again. */
continue
;
}
/* Get the size of the data block received */
ulRecvSize
-=
TFTP_HDRSIZE
;
/* Check if the size of the received data block > max size */
if
(
ulRecvSize
>
TFTP_BLKSIZE
)
{
/* Send Error packet to server */
lwip_tftp_send_error
(
iSockNum
,
TFTPC_PROTOCOL_PROTO_ERROR
,
"Packet size > max size"
,
&
stServerAddr
,
pstSendBuf
);
(
void
)
lwip_close
(
iSockNum
);
if
(
isLocalFileOpened
==
true
)
{
close
(
fp
);
}
LWIP_DEBUGF
(
TFTP_DEBUG
,
(
"lwip_tftp_get_file_by_filename : Packet size > max size
\n
"
));
ulErrCode
=
TFTPC_PKT_SIZE_ERROR
;
goto
err_handler
;
}
usReadReq
=
(
u16_t
)
TFTPC_OP_ACK
;
pstSendBuf
->
usOpcode
=
htons
(
usReadReq
);
pstSendBuf
->
u
.
usBlknum
=
htons
((
u16_t
)
ulCurrBlk
);
ulSize
=
TFTP_HDRSIZE
;
if
(
isLocalFileOpened
==
false
)
{
fp
=
open
((
char
*
)
pszTempDestName
,
(
O_WRONLY
|
O_CREAT
|
O_TRUNC
),
DEFFILEMODE
);
if
(
fp
==
TFTP_NULL_INT32
)
{
ulErrCode
=
TFTPC_FILECREATE_ERROR
;
(
void
)
lwip_close
(
iSockNum
);
goto
err_handler
;
}
isLocalFileOpened
=
true
;
}
if
(
ulRecvSize
!=
TFTP_BLKSIZE
)
{
(
void
)
lwip_tftp_send_to_server
(
iSockNum
,
ulSize
,
pstSendBuf
,
&
stServerAddr
);
/* If the received packet has only header and do not have payload, the return failure */
if
(
ulRecvSize
!=
0
)
{
/* Write the last packet to the file */
iErrCode
=
write
(
fp
,
(
void
*
)
pstRecvBuf
->
u
.
stTFTP_Data
.
ucDataBuf
,
(
size_t
)
ulRecvSize
);
if
(
ulRecvSize
!=
(
u32_t
)
iErrCode
)
{
/* Write to file failed. */
lwip_tftp_send_error
(
iSockNum
,
TFTPC_PROTOCOL_USER_DEFINED
,
"Write to file failed"
,
&
stServerAddr
,
pstSendBuf
);
(
void
)
lwip_close
(
iSockNum
);
close
(
fp
);
/* return from the function, file write failed */
ulErrCode
=
TFTPC_FILEWRITE_ERROR
;
goto
err_handler
;
}
}
/* Now free allocated resourdes and return,
data block receiving is already completed */
(
void
)
lwip_close
(
iSockNum
);
close
(
fp
);
ulErrCode
=
ERR_OK
;
goto
err_handler
;
}
ulErrCode
=
lwip_tftp_send_to_server
(
iSockNum
,
ulSize
,
pstSendBuf
,
&
stServerAddr
);
if
(
ulErrCode
!=
ERR_OK
)
{
(
void
)
lwip_close
(
iSockNum
);
close
(
fp
);
goto
err_handler
;
}
iErrCode
=
write
(
fp
,
(
void
*
)
pstRecvBuf
->
u
.
stTFTP_Data
.
ucDataBuf
,
(
size_t
)
ulRecvSize
);
if
(
ulRecvSize
!=
(
u32_t
)
iErrCode
)
{
/* Write to file failed. */
lwip_tftp_send_error
(
iSockNum
,
TFTPC_PROTOCOL_USER_DEFINED
,
"Write to file failed"
,
&
stServerAddr
,
pstSendBuf
);
(
void
)
lwip_close
(
iSockNum
);
close
(
fp
);
/* return from the function, file write failed */
ulErrCode
=
TFTPC_FILEWRITE_ERROR
;
goto
err_handler
;
}
/* form the ACK packet for the DATA packet received */
/* Go to the next packet no. */
ulCurrBlk
++
;
/* if the file is too big, exit */
if
(
ulCurrBlk
>
TFTP_MAX_BLK_NUM
)
{
/* Send error packet to server */
lwip_tftp_send_error
(
iSockNum
,
TFTPC_PROTOCOL_USER_DEFINED
,
"File is too big."
,
&
stServerAddr
,
pstSendBuf
);
(
void
)
lwip_close
(
iSockNum
);
close
(
fp
);
LWIP_DEBUGF
(
TFTP_DEBUG
,
(
"lwip_tftp_get_file_by_filename : Data block number exceeded max value
\n
"
));
ulErrCode
=
TFTPC_FILE_TOO_BIG
;
goto
err_handler
;
}
}
err_handler:
mem_free
(
pstSendBuf
);
mem_free
(
pstRecvBuf
);
mem_free
(
pszTempDestName
);
return
ulErrCode
;
}
/* INTERFACE Function to put a file using filename
ulHostAddr: IP address of Host
szSrcFileName: Source file
szDestDirPath: Destination file path
*/
u32_t
lwip_tftp_put_file_by_filename
(
u32_t
ulHostAddr
,
u16_t
usTftpServPort
,
u8_t
ucTftpTransMode
,
s8_t
*
szSrcFileName
,
s8_t
*
szDestDirPath
)
{
u32_t
ulSrcStrLen
;
u32_t
ulDestStrLen
;
s32_t
iSockNum
=
TFTP_NULL_INT32
;
s32_t
iErrCode
;
u32_t
ulErrCode
;
u16_t
usTempServPort
;
TFTPC_PACKET_S
*
pstSendBuf
=
NULL
;
u16_t
usReadReq
;
u32_t
ulSize
;
s8_t
*
pucBuffer
=
0
;
s8_t
*
szTempDestName
=
NULL
;
/*Initialize the block number*/
u16_t
usCurrBlk
=
0
;
struct
sockaddr_in
stServerAddr
;
struct
stat
buffer
;
s32_t
fp
=
-
1
;
/* Validate parameters */
if
((
szSrcFileName
==
NULL
)
||
(
szDestDirPath
==
NULL
))
{
return
TFTPC_INVALID_PARAVALUE
;
}
if
((
ucTftpTransMode
!=
TRANSFER_MODE_BINARY
)
&&
(
ucTftpTransMode
!=
TRANSFER_MODE_ASCII
))
{
return
TFTPC_INVALID_PARAVALUE
;
}
/*check IP address not within ( 1.0.0.0 - 126.255.255.255 )
and ( 128.0.0.0 - 223.255.255.255 ) range.*/
if
(
!
(((
ulHostAddr
>=
TFTPC_IP_ADDR_MIN
)
&&
(
ulHostAddr
<=
TFTPC_IP_ADDR_EX_RESV
))
||
((
ulHostAddr
>=
TFTPC_IP_ADDR_CLASS_B
)
&&
(
ulHostAddr
<=
TFTPC_IP_ADDR_EX_CLASS_DE
))))
{
return
TFTPC_IP_NOT_WITHIN_RANGE
;
}
/* If Src filename is empty or exceeded max length */
ulSrcStrLen
=
strlen
((
char
*
)
szSrcFileName
);
if
((
ulSrcStrLen
==
0
)
||
(
ulSrcStrLen
>=
TFTP_MAX_PATH_LENGTH
))
{
return
TFTPC_SRC_FILENAME_LENGTH_ERROR
;
}
/* Check if source file exists */
if
(
stat
((
char
*
)
szSrcFileName
,
&
buffer
)
!=
0
)
{
return
TFTPC_FILE_NOT_EXIST
;
}
/* Check if the file is too big */
if
(
buffer
.
st_size
>=
(
off_t
)(
TFTP_MAX_BLK_NUM
*
TFTP_BLKSIZE
))
{
return
TFTPC_FILE_TOO_BIG
;
}
/* Check validity of destination path */
ulDestStrLen
=
strlen
((
char
*
)
szDestDirPath
);
/* If dest path length exceeded max value */
if
(
ulDestStrLen
>=
TFTP_MAX_PATH_LENGTH
)
{
return
TFTPC_DEST_PATH_LENGTH_ERROR
;
}
pstSendBuf
=
(
TFTPC_PACKET_S
*
)
mem_malloc
(
sizeof
(
TFTPC_PACKET_S
));
if
(
pstSendBuf
==
NULL
)
{
return
TFTPC_MEMALLOC_ERROR
;
}
/* First time intialize the buffer */
(
void
)
memset_s
((
void
*
)
pstSendBuf
,
sizeof
(
TFTPC_PACKET_S
),
0
,
sizeof
(
TFTPC_PACKET_S
));
/* The destination path can only be one of the following:
1. Only filename
2. Relative path WITH filename
3. Empty string
*/
if
(
ulDestStrLen
!=
0
)
{
/* If not empty string use the Destination path name */
szTempDestName
=
szDestDirPath
;
}
else
{
/* If destination directory is empty string use source filename
If given src filename is a relative path extract the file name
from the path */
if
((
strchr
((
char
*
)
szSrcFileName
,
'/'
)
!=
0
)
||
(
strchr
((
char
*
)
szSrcFileName
,
'\\'
)
!=
0
))
{
/* Move to the end of the src file path */
szTempDestName
=
szSrcFileName
+
(
ulSrcStrLen
-
1
);
while
(((
*
(
szTempDestName
-
1
)
!=
'/'
)
&&
(
*
(
szTempDestName
-
1
)
!=
'\\'
))
&&
(
szTempDestName
!=
szSrcFileName
))
{
szTempDestName
--
;
}
}
else
{
/* If not a relative src path use the given src filename */
szTempDestName
=
szSrcFileName
;
}
}
/* Create a socket and bind it to an available port number */
ulErrCode
=
lwip_tftp_create_bind_socket
(
&
iSockNum
);
if
(
ulErrCode
!=
EOK
)
{
/* Create and Bind socket failed */
goto
err_handler
;
}
if
(
usTftpServPort
==
0
)
{
usTftpServPort
=
TFTPC_SERVER_PORT
;
}
usTempServPort
=
usTftpServPort
;
/* set server internet address */
(
void
)
memset_s
(
&
stServerAddr
,
sizeof
(
stServerAddr
),
0
,
sizeof
(
stServerAddr
));
stServerAddr
.
sin_family
=
AF_INET
;
stServerAddr
.
sin_port
=
htons
(
usTempServPort
);
stServerAddr
.
sin_addr
.
s_addr
=
htonl
(
ulHostAddr
);
/* Make request packet - TFTPC_OP_WRQ */
ulSize
=
(
u32_t
)
lwip_tftp_make_tftp_packet
(
TFTPC_OP_WRQ
,
szTempDestName
,
ucTftpTransMode
,
pstSendBuf
);
ulErrCode
=
lwip_tftp_send_to_server
(
iSockNum
,
ulSize
,
pstSendBuf
,
&
stServerAddr
);
if
(
ulErrCode
!=
ERR_OK
)
{
/* Send to server error */
(
void
)
lwip_close
(
iSockNum
);
goto
err_handler
;
}
/* Send the request packet */
ulErrCode
=
lwip_tftp_inner_put_file
(
iSockNum
,
pstSendBuf
,
ulSize
,
usCurrBlk
,
&
stServerAddr
);
if
(
ulErrCode
!=
ERR_OK
)
{
/* Send request packet failed */
(
void
)
lwip_close
(
iSockNum
);
LWIP_DEBUGF
(
TFTP_DEBUG
,
(
"lwip_tftp_put_file_by_filename : Failed to send request packet
\n
"
));
goto
err_handler
;
}
/* Create buffer block size */
pucBuffer
=
mem_malloc
(
TFTP_BLKSIZE
);
if
(
pucBuffer
==
NULL
)
{
/* Memory allocation failed */
lwip_tftp_send_error
(
iSockNum
,
TFTPC_PROTOCOL_USER_DEFINED
,
"Memory allocation failed."
,
&
stServerAddr
,
pstSendBuf
);
(
void
)
lwip_close
(
iSockNum
);
ulErrCode
=
TFTPC_MEMALLOC_ERROR
;
goto
err_handler
;
}
(
void
)
memset_s
((
void
*
)
pucBuffer
,
TFTP_BLKSIZE
,
0
,
TFTP_BLKSIZE
);
fp
=
open
((
char
*
)
szSrcFileName
,
O_RDONLY
);
if
(
TFTP_NULL_INT32
==
fp
)
{
/* If file could not be opened send error to server */
lwip_tftp_send_error
(
iSockNum
,
TFTPC_PROTOCOL_USER_DEFINED
,
"File open error."
,
&
stServerAddr
,
pstSendBuf
);
(
void
)
lwip_close
(
iSockNum
);
close
(
fp
);
mem_free
(
pucBuffer
);
ulErrCode
=
TFTPC_FILEOPEN_ERROR
;
goto
err_handler
;
}
iErrCode
=
read
(
fp
,
pucBuffer
,
TFTP_BLKSIZE
);
if
(
iErrCode
<
0
)
{
/* If failed to read from file */
lwip_tftp_send_error
(
iSockNum
,
TFTPC_PROTOCOL_USER_DEFINED
,
"File read error."
,
&
stServerAddr
,
pstSendBuf
);
(
void
)
lwip_close
(
iSockNum
);
close
(
fp
);
mem_free
(
pucBuffer
);
ulErrCode
=
TFTPC_FILEREAD_ERROR
;
goto
err_handler
;
}
/* Read from source file and send to server */
/* To send empty packet to server when file is a 0 byte file */
do
{
if
(((
u32_t
)
usCurrBlk
+
1
)
>
TFTP_MAX_BLK_NUM
)
{
lwip_tftp_send_error
(
iSockNum
,
TFTPC_PROTOCOL_USER_DEFINED
,
"File is too big."
,
&
stServerAddr
,
pstSendBuf
);
(
void
)
lwip_close
(
iSockNum
);
close
(
fp
);
mem_free
(
pucBuffer
);
LWIP_DEBUGF
(
TFTP_DEBUG
,
(
"lwip_tftp_put_file_by_filename : Data block number exceeded max value
\n
"
));
ulErrCode
=
TFTPC_FILE_TOO_BIG
;
goto
err_handler
;
}
/* Increment block number */
usCurrBlk
++
;
ulSize
=
(
u32_t
)
iErrCode
+
TFTP_HDRSIZE
;
/* Form the DATA packet */
usReadReq
=
(
u16_t
)
TFTPC_OP_DATA
;
pstSendBuf
->
usOpcode
=
htons
(
usReadReq
);
pstSendBuf
->
u
.
stTFTP_Data
.
usBlknum
=
htons
(
usCurrBlk
);
if
(
memcpy_s
((
void
*
)
pstSendBuf
->
u
.
stTFTP_Data
.
ucDataBuf
,
TFTP_BLKSIZE
,
(
void
*
)
pucBuffer
,
(
u32_t
)
iErrCode
)
!=
EOK
)
{
(
void
)
lwip_close
(
iSockNum
);
close
(
fp
);
mem_free
(
pucBuffer
);
goto
err_handler
;
}
ulErrCode
=
lwip_tftp_send_to_server
(
iSockNum
,
ulSize
,
pstSendBuf
,
&
stServerAddr
);
if
((
ulErrCode
!=
ERR_OK
)
||
(
memset_s
((
void
*
)
pucBuffer
,
TFTP_BLKSIZE
,
0
,
TFTP_BLKSIZE
)
!=
0
))
{
(
void
)
lwip_close
(
iSockNum
);
close
(
fp
);
mem_free
(
pucBuffer
);
goto
err_handler
;
}
/* Read a block from the file to buffer */
iErrCode
=
read
(
fp
,
pucBuffer
,
TFTP_BLKSIZE
);
if
(
iErrCode
<
0
)
{
/*If failed to read from file*/
lwip_tftp_send_error
(
iSockNum
,
TFTPC_PROTOCOL_USER_DEFINED
,
"File read error."
,
&
stServerAddr
,
pstSendBuf
);
(
void
)
lwip_close
(
iSockNum
);
close
(
fp
);
mem_free
(
pucBuffer
);
ulErrCode
=
TFTPC_FILEREAD_ERROR
;
goto
err_handler
;
}
/* Send the request packet */
ulErrCode
=
lwip_tftp_inner_put_file
(
iSockNum
,
pstSendBuf
,
ulSize
,
usCurrBlk
,
&
stServerAddr
);
if
(
ulErrCode
!=
ERR_OK
)
{
/* Sending buffer contents failed */
(
void
)
lwip_close
(
iSockNum
);
close
(
fp
);
mem_free
(
pucBuffer
);
LWIP_DEBUGF
(
TFTP_DEBUG
,
(
"lwip_tftp_put_file_by_filename : Sending file to server failed
\n
"
));
goto
err_handler
;
}
}
while
(
ulSize
==
(
TFTP_BLKSIZE
+
TFTP_HDRSIZE
));
/* Transfer of data is finished */
(
void
)
lwip_close
(
iSockNum
);
close
(
fp
);
mem_free
(
pucBuffer
);
ulErrCode
=
ERR_OK
;
err_handler:
mem_free
(
pstSendBuf
);
return
ulErrCode
;
}
/* Put file function
iSockNum: Socket ID
pstSendBuf: Packet to send to server
ulSendSize: Packet length
usCurrBlk: Current block number
pstServerAddr: Server address
*/
u32_t
lwip_tftp_inner_put_file
(
s32_t
iSockNum
,
TFTPC_PACKET_S
*
pstSendBuf
,
u32_t
ulSendSize
,
u16_t
usCurrBlk
,
struct
sockaddr_in
*
pstServerAddr
)
{
u32_t
ulPktSize
;
u32_t
ulError
;
s32_t
iError
;
int
iRecvLen
=
0
;
socklen_t
iFromAddrLen
;
u32_t
ulTotalTime
=
0
;
fd_set
stReadfds
;
struct
sockaddr_in
stFromAddr
;
struct
timeval
stTimeout
;
TFTPC_PACKET_S
*
pstRecvBuf
=
NULL
;
u32_t
ulIgnorePkt
=
0
;
u16_t
usBlknum
;
u32_t
ulLoopCnt
=
0
;
iFromAddrLen
=
sizeof
(
stFromAddr
);
pstRecvBuf
=
(
TFTPC_PACKET_S
*
)
mem_malloc
(
sizeof
(
TFTPC_PACKET_S
));
if
(
pstRecvBuf
==
NULL
)
{
return
TFTPC_MEMALLOC_ERROR
;
}
/* First time intialize the buffer */
(
void
)
memset_s
((
void
*
)
pstRecvBuf
,
sizeof
(
TFTPC_PACKET_S
),
0
,
sizeof
(
TFTPC_PACKET_S
));
/* Initialize from address to the server address at first */
if
(
memcpy_s
((
void
*
)
&
stFromAddr
,
sizeof
(
struct
sockaddr_in
),
(
void
*
)
pstServerAddr
,
sizeof
(
stFromAddr
))
!=
EOK
)
{
ulError
=
TFTPC_MEMCPY_FAILURE
;
goto
err_handler
;
}
for
(;;)
{
ulError
=
lwip_tftp_recv_from_server
(
iSockNum
,
&
ulPktSize
,
pstRecvBuf
,
&
ulIgnorePkt
,
pstServerAddr
,
pstSendBuf
);
/* If select timeout occured */
if
(
ulError
==
TFTPC_TIMEOUT_ERROR
)
{
ulTotalTime
++
;
if
(
ulTotalTime
<
TFTPC_MAX_SEND_REQ_ATTEMPTS
)
{
/*Max attempts not reached. Resend packet*/
ulError
=
lwip_tftp_send_to_server
(
iSockNum
,
ulSendSize
,
pstSendBuf
,
pstServerAddr
);
if
(
ulError
!=
ERR_OK
)
{
goto
err_handler
;
}
continue
;
}
else
{
/* return from the function, max attempts limit reached */
ulError
=
TFTPC_TIMEOUT_ERROR
;
goto
err_handler
;
}
}
else
if
(
ulError
!=
ERR_OK
)
{
/* return from the function, RecvFromServer failed */
goto
err_handler
;
}
/* If Received packet from another server */
if
(
ulIgnorePkt
>
0
)
{
/* The packet that is received is to be ignored.
So continue without processing it. */
ulIgnorePkt
=
0
;
continue
;
}
/* if this packet is unknown or incorrect packet */
if
(
TFTPC_OP_ACK
!=
ntohs
(
pstRecvBuf
->
usOpcode
))
{
lwip_tftp_send_error
(
iSockNum
,
TFTPC_PROTOCOL_PROTO_ERROR
,
"Protocol error."
,
pstServerAddr
,
pstSendBuf
);
LWIP_DEBUGF
(
TFTP_DEBUG
,
(
"lwip_tftp_inner_put_file : Received pkt not Ack pkt
\n
"
));
ulError
=
TFTPC_PROTO_ERROR
;
goto
err_handler
;
}
ulTotalTime
=
0
;
/* if the packet is acknowledge packet */
usBlknum
=
ntohs
(
pstRecvBuf
->
u
.
usBlknum
);
iRecvLen
=
(
int
)
ulPktSize
;
/* If not correct block no. */
if
(
usBlknum
!=
usCurrBlk
)
{
/* we are not in sync now */
/* reset any collected packets. */
stTimeout
.
tv_sec
=
1
;
stTimeout
.
tv_usec
=
0
;
FD_ZERO
(
&
stReadfds
);
FD_SET
(
iSockNum
,
&
stReadfds
);
/*
Need to take care of timeout scenario in Select call.
Since the socket used is blocking, if select timeout occurs,
the following recvfrom will block indefinitely.
*/
iError
=
select
((
s32_t
)(
iSockNum
+
1
),
&
stReadfds
,
0
,
0
,
&
stTimeout
);
/* Loop to get the last data packet from the receive buffer */
while
((
iError
!=
-
1
)
&&
(
iError
!=
0
))
{
ulLoopCnt
++
;
/* MAX file size in TFTP is 32 MB.
Reason for keeping 75 here , is ((75*512=38400bytes)/1024) = 37MB. So the recv/Snd
Loop can receive the complete MAX message from the network.
*/
if
(
ulLoopCnt
>
TFTPC_MAX_WAIT_IN_LOOP
)
{
LWIP_DEBUGF
(
TFTP_DEBUG
,
(
"lwip_tftp_inner_put_file : unexpected packets are received repeatedly
\n
"
));
ulError
=
TFTPC_PKT_SIZE_ERROR
;
goto
err_handler
;
}
FD_ZERO
(
&
stReadfds
);
FD_SET
(
iSockNum
,
&
stReadfds
);
iRecvLen
=
lwip_recvfrom
(
iSockNum
,
(
s8_t
*
)
pstRecvBuf
,
TFTP_PKTSIZE
,
0
,
(
struct
sockaddr
*
)
&
stFromAddr
,
&
iFromAddrLen
);
if
(
TFTP_NULL_INT32
==
iRecvLen
)
{
ulError
=
TFTPC_RECVFROM_ERROR
;
goto
err_handler
;
}
stTimeout
.
tv_sec
=
1
;
stTimeout
.
tv_usec
=
0
;
iError
=
select
((
s32_t
)(
iSockNum
+
1
),
&
stReadfds
,
0
,
0
,
&
stTimeout
);
}
/* If a new packet is not received then donot change the byte order
* as it has already been done
*/
/* If received packet size < minimum packet size */
if
(
iRecvLen
<
TFTPC_FOUR
)
{
lwip_tftp_send_error
(
iSockNum
,
TFTPC_PROTOCOL_PROTO_ERROR
,
"Packet size < min packet size"
,
pstServerAddr
,
pstSendBuf
);
LWIP_DEBUGF
(
TFTP_DEBUG
,
(
"lwip_tftp_inner_put_file : Received pkt not Ack pkt
\n
"
));
ulError
=
TFTPC_PKT_SIZE_ERROR
;
goto
err_handler
;
}
/* Check if the received packet is from correct server and from
correct port
*/
if
((
stFromAddr
.
sin_addr
.
s_addr
!=
pstServerAddr
->
sin_addr
.
s_addr
)
||
(
pstServerAddr
->
sin_port
!=
stFromAddr
.
sin_port
))
{
/* This ACK packet is invalid. Just ignore it. */
LWIP_DEBUGF
(
TFTP_DEBUG
,
(
"lwip_tftp_inner_put_file : Received pkt from unknown server
\n
"
));
continue
;
}
/* if this packet is not ACK packet */
if
(
TFTPC_OP_ACK
!=
ntohs
(
pstRecvBuf
->
usOpcode
))
{
lwip_tftp_send_error
(
iSockNum
,
TFTPC_PROTOCOL_PROTO_ERROR
,
"Protocol error."
,
pstServerAddr
,
pstSendBuf
);
LWIP_DEBUGF
(
TFTP_DEBUG
,
(
"lwip_tftp_inner_put_file : Received pkt not Ack pkt
\n
"
));
ulError
=
TFTPC_PROTO_ERROR
;
goto
err_handler
;
}
usBlknum
=
ntohs
(
pstRecvBuf
->
u
.
usBlknum
);
/*
* In this case we have received a duplicate ACK for data block.
* (ACK for this data block was aready received earlier)
* In this case we have usRecvBlkNum == (usNextBlkNum - 1).
* This could mean that:
* (i) last data packet that was sent was not received at server side
* (ii) Acknowledgement of peer side is delayed.
*
* In this case, this duplicate ACK will be ignored and return to the
* state machine to initiate a receive of this data packet.
*/
if
((
usCurrBlk
-
1
)
==
usBlknum
)
{
/* This ACK packet is invalid. Just ignore it. */
continue
;
}
/* Now check the block number with current block.
* If it is not the previous block and the current block,
* then it is an unexpected packet.
*/
if
(
usBlknum
!=
usCurrBlk
)
{
lwip_tftp_send_error
(
iSockNum
,
TFTPC_PROTOCOL_PROTO_ERROR
,
"Received unexpected packet"
,
pstServerAddr
,
pstSendBuf
);
LWIP_DEBUGF
(
TFTP_DEBUG
,
(
"lwip_tftp_inner_put_file : Received DATA pkt no. %"
S32_F
"instead of pkt no. %"
S32_F
"
\n
"
,
usBlknum
,
usCurrBlk
));
ulError
=
TFTPC_SYNC_FAILURE
;
goto
err_handler
;
}
}
ulError
=
ERR_OK
;
goto
err_handler
;
}
err_handler:
mem_free
(
pstRecvBuf
);
return
ulError
;
}
#ifdef TFTP_TO_RAWMEM
/* INTEFACE to get a file using filename
ulHostAddr - IP address of Host
szSrcFileName - Source file
szDestMemAddr - The target memory address in the client
Example :
ulHostAddr = ntohl(inet_addr ("192.168.1.3"));
lwip_tftp_get_file_by_filename_to_rawmem(ulHostAddr, "/ramfs/vs_server.bin", memaddr, &filelen);
*/
u32_t
lwip_tftp_get_file_by_filename_to_rawmem
(
u32_t
ulHostAddr
,
u16_t
usTftpServPort
,
u8_t
ucTftpTransMode
,
s8_t
*
szSrcFileName
,
s8_t
*
szDestMemAddr
,
u32_t
*
ulFileLength
)
{
s32_t
iSockNum
=
TFTP_NULL_INT32
;
u32_t
ulSrcStrLen
;
u32_t
lDestStrLen
;
u32_t
ulSize
;
u32_t
ulRecvSize
=
TFTP_NULL_UINT32
;
s32_t
iErrCode
;
u32_t
ulErrCode
;
u16_t
usReadReq
;
u16_t
usTempServPort
;
u32_t
ulCurrBlk
=
1
;
u32_t
ulResendPkt
=
0
;
/* Resend the previous packet */
u32_t
ulIgnorePkt
=
0
;
/* Ignore received packet */
u32_t
ulTotalTime
=
0
;
TFTPC_PACKET_S
*
pstSendBuf
=
NULL
;
TFTPC_PACKET_S
*
pstRecvBuf
=
NULL
;
struct
sockaddr_in
stServerAddr
;
u32_t
ulMemOffset
=
0
;
/* Validate the parameters */
if
((
szSrcFileName
==
NULL
)
||
(
szDestMemAddr
==
NULL
)
||
(
*
ulFileLength
==
0
))
{
return
TFTPC_INVALID_PARAVALUE
;
}
if
((
ucTftpTransMode
!=
TRANSFER_MODE_BINARY
)
&&
(
ucTftpTransMode
!=
TRANSFER_MODE_ASCII
))
{
return
TFTPC_INVALID_PARAVALUE
;
}
/* check IP address not within ( 1.0.0.0 - 126.255.255.255 )
and ( 128.0.0.0 - 223.255.255.255 ) range. */
if
(
!
(((
ulHostAddr
>=
TFTPC_IP_ADDR_MIN
)
&&
(
ulHostAddr
<=
TFTPC_IP_ADDR_EX_RESV
))
||
((
ulHostAddr
>=
TFTPC_IP_ADDR_CLASS_B
)
&&
(
ulHostAddr
<=
TFTPC_IP_ADDR_EX_CLASS_DE
))))
{
return
TFTPC_IP_NOT_WITHIN_RANGE
;
}
/*Check validity of source filename*/
ulSrcStrLen
=
strlen
(
szSrcFileName
);
if
((
ulSrcStrLen
==
0
)
||
(
ulSrcStrLen
>=
TFTP_MAX_PATH_LENGTH
))
{
return
TFTPC_SRC_FILENAME_LENGTH_ERROR
;
}
pstSendBuf
=
(
TFTPC_PACKET_S
*
)
mem_malloc
(
sizeof
(
TFTPC_PACKET_S
));
if
(
pstSendBuf
==
NULL
)
{
return
TFTPC_MEMALLOC_ERROR
;
}
pstRecvBuf
=
(
TFTPC_PACKET_S
*
)
mem_malloc
(
sizeof
(
TFTPC_PACKET_S
));
if
(
pstRecvBuf
==
NULL
)
{
mem_free
(
pstSendBuf
);
return
TFTPC_MEMALLOC_ERROR
;
}
/* First time initialize the buffers */
(
void
)
memset_s
((
void
*
)
pstSendBuf
,
sizeof
(
TFTPC_PACKET_S
),
0
,
sizeof
(
TFTPC_PACKET_S
));
(
void
)
memset_s
((
void
*
)
pstRecvBuf
,
sizeof
(
TFTPC_PACKET_S
),
0
,
sizeof
(
TFTPC_PACKET_S
));
ulErrCode
=
lwip_tftp_create_bind_socket
(
&
iSockNum
);
if
(
ulErrCode
!=
EOK
)
{
goto
err_handler
;
}
if
(
usTftpServPort
==
0
)
{
usTftpServPort
=
TFTPC_SERVER_PORT
;
}
usTempServPort
=
usTftpServPort
;
/* set server IP address */
(
void
)
memset_s
(
&
stServerAddr
,
sizeof
(
stServerAddr
),
0
,
sizeof
(
stServerAddr
));
stServerAddr
.
sin_family
=
AF_INET
;
stServerAddr
.
sin_port
=
htons
(
usTempServPort
);
stServerAddr
.
sin_addr
.
s_addr
=
htonl
(
ulHostAddr
);
/* Make a request packet - TFTPC_OP_RRQ */
ulSize
=
(
u32_t
)
lwip_tftp_make_tftp_packet
(
TFTPC_OP_RRQ
,
szSrcFileName
,
(
u32_t
)
ucTftpTransMode
,
pstSendBuf
);
ulErrCode
=
lwip_tftp_send_to_server
(
iSockNum
,
ulSize
,
pstSendBuf
,
&
stServerAddr
);
if
(
ulErrCode
!=
ERR_OK
)
{
/* send to server failed */
(
void
)
lwip_close
(
iSockNum
);
goto
err_handler
;
}
for
(;;)
{
if
(
ulIgnorePkt
>
0
)
{
ulIgnorePkt
=
0
;
}
ulErrCode
=
lwip_tftp_recv_from_server
(
iSockNum
,
&
ulRecvSize
,
pstRecvBuf
,
&
ulIgnorePkt
,
&
stServerAddr
,
pstSendBuf
);
/* If select timeout occured */
if
(
ulErrCode
==
TFTPC_TIMEOUT_ERROR
)
{
ulTotalTime
++
;
if
(
ulTotalTime
<
TFTPC_MAX_SEND_REQ_ATTEMPTS
)
{
/* Max attempts not reached. Resend packet */
ulErrCode
=
lwip_tftp_send_to_server
(
iSockNum
,
ulSize
,
pstSendBuf
,
&
stServerAddr
);
if
(
ulErrCode
!=
ERR_OK
)
{
(
void
)
lwip_close
(
iSockNum
);
goto
err_handler
;
}
continue
;
}
else
{
/* return from the function, max attempts limit reached */
(
void
)
lwip_close
(
iSockNum
);
ulErrCode
=
TFTPC_TIMEOUT_ERROR
;
goto
err_handler
;
}
}
else
if
(
ulErrCode
!=
ERR_OK
)
{
(
void
)
lwip_close
(
iSockNum
);
goto
err_handler
;
}
/* Now we have receive block from different server. */
if
(
ulIgnorePkt
>
0
)
{
/*Continue without processing this block. */
continue
;
}
/* if this packet is unkonwn or incorrect packet */
if
(
ntohs
(
pstRecvBuf
->
usOpcode
)
!=
TFTPC_OP_DATA
)
{
/* Send error packet to server */
lwip_tftp_send_error
(
iSockNum
,
TFTPC_PROTOCOL_PROTO_ERROR
,
"Protocol error."
,
&
stServerAddr
,
pstSendBuf
);
(
void
)
lwip_close
(
iSockNum
);
LWIP_DEBUGF
(
TFTP_DEBUG
,
(
"lwip_tftp_get_file_by_filename : Received pkt not DATA pkt
\n
"
));
ulErrCode
=
TFTPC_PROTO_ERROR
;
goto
err_handler
;
}
/* Now the number of tries will be reset. */
ulTotalTime
=
0
;
/* Validate received DATA packet. */
ulErrCode
=
lwip_tftp_validate_data_pkt
(
iSockNum
,
&
ulRecvSize
,
pstRecvBuf
,
(
u16_t
)
ulCurrBlk
,
&
ulResendPkt
,
&
stServerAddr
);
if
(
ulErrCode
!=
ERR_OK
)
{
/* Send Error packet to server */
if
(
ulErrCode
!=
TFTPC_RECVFROM_ERROR
)
{
lwip_tftp_send_error
(
iSockNum
,
TFTPC_PROTOCOL_PROTO_ERROR
,
"Received unexpected packet"
,
&
stServerAddr
,
pstSendBuf
);
}
(
void
)
lwip_close
(
iSockNum
);
goto
err_handler
;
}
/* Received previous data block again. Resend last packet */
if
(
ulResendPkt
>
0
)
{
/* Now set ulResendPkt to 0 to send the last packet. */
ulResendPkt
=
0
;
ulErrCode
=
lwip_tftp_send_to_server
(
iSockNum
,
ulSize
,
pstSendBuf
,
&
stServerAddr
);
if
(
ulErrCode
!=
ERR_OK
)
{
(
void
)
lwip_close
(
iSockNum
);
goto
err_handler
;
}
/* Continue in loop to send last packet again. */
continue
;
}
/* Get the size of the data block received */
ulRecvSize
-=
TFTP_HDRSIZE
;
/* Check if the size of the received data block > max size */
if
(
ulRecvSize
>
TFTP_BLKSIZE
)
{
/* Send Error packet to server */
lwip_tftp_send_error
(
iSockNum
,
TFTPC_PROTOCOL_PROTO_ERROR
,
"Packet size > max size"
,
&
stServerAddr
,
pstSendBuf
);
(
void
)
lwip_close
(
iSockNum
);
LWIP_DEBUGF
(
TFTP_DEBUG
,
(
"lwip_tftp_get_file_by_filename : Packet size > max size
\n
"
));
ulErrCode
=
TFTPC_PKT_SIZE_ERROR
;
goto
err_handler
;
}
usReadReq
=
(
u16_t
)
TFTPC_OP_ACK
;
pstSendBuf
->
usOpcode
=
htons
(
usReadReq
);
pstSendBuf
->
u
.
usBlknum
=
htons
((
u16_t
)
ulCurrBlk
);
ulSize
=
TFTP_HDRSIZE
;
if
(
ulRecvSize
!=
TFTP_BLKSIZE
)
{
(
void
)
lwip_tftp_send_to_server
(
iSockNum
,
ulSize
,
pstSendBuf
,
&
stServerAddr
);
/* If the received packet has only header and do not have payload, the return failure */
if
(
ulRecvSize
!=
0
)
{
/* memcopy filed */
if
(
*
ulFileLength
<
(
ulMemOffset
+
ulRecvSize
))
{
ulErrCode
=
TFTPC_MEMCPY_FAILURE
;
(
void
)
lwip_close
(
iSockNum
);
*
ulFileLength
=
ulMemOffset
;
goto
err_handler
;
}
/* copy the last packet to the memory */
if
(
memcpy_s
(
szDestMemAddr
+
ulMemOffset
,
TFTP_MAX_BLK_NUM
*
TFTP_BLKSIZE
,
(
void
*
)
pstRecvBuf
->
u
.
stTFTP_Data
.
ucDataBuf
,
(
size_t
)
ulRecvSize
)
!=
EOK
)
{
ulErrCode
=
TFTPC_MEMCPY_FAILURE
;
(
void
)
lwip_close
(
iSockNum
);
*
ulFileLength
=
ulMemOffset
;
goto
err_handler
;
}
ulMemOffset
+=
ulRecvSize
;
}
/* Now free allocated resourdes and return,
data block receiving is already completed */
(
void
)
lwip_close
(
iSockNum
);
ulErrCode
=
ERR_OK
;
*
ulFileLength
=
ulMemOffset
;
goto
err_handler
;
}
ulErrCode
=
lwip_tftp_send_to_server
(
iSockNum
,
ulSize
,
pstSendBuf
,
&
stServerAddr
);
if
(
ulErrCode
!=
ERR_OK
)
{
(
void
)
lwip_close
(
iSockNum
);
goto
err_handler
;
}
/* memcopy filed */
if
(
*
ulFileLength
<
ulRecvSize
*
ulCurrBlk
)
{
ulErrCode
=
TFTPC_MEMCPY_FAILURE
;
(
void
)
lwip_close
(
iSockNum
);
*
ulFileLength
=
ulMemOffset
;
goto
err_handler
;
}
if
(
memcpy_s
(
szDestMemAddr
+
ulMemOffset
,
TFTP_MAX_BLK_NUM
*
TFTP_BLKSIZE
,
(
void
*
)
pstRecvBuf
->
u
.
stTFTP_Data
.
ucDataBuf
,
(
size_t
)
ulRecvSize
)
!=
EOK
)
{
ulErrCode
=
TFTPC_MEMCPY_FAILURE
;
(
void
)
lwip_close
(
iSockNum
);
*
ulFileLength
=
ulMemOffset
;
goto
err_handler
;
}
ulMemOffset
+=
ulRecvSize
;
/* form the ACK packet for the DATA packet received */
/* Go to the next packet no. */
ulCurrBlk
++
;
/* if the file is too big, exit */
if
(
ulCurrBlk
>
TFTP_MAX_BLK_NUM
)
{
/* Send error packet to server */
lwip_tftp_send_error
(
iSockNum
,
TFTPC_PROTOCOL_USER_DEFINED
,
"File is too big."
,
&
stServerAddr
,
pstSendBuf
);
(
void
)
lwip_close
(
iSockNum
);
LWIP_DEBUGF
(
TFTP_DEBUG
,
(
"lwip_tftp_get_file_by_filename : Data block number exceeded max value
\n
"
));
ulErrCode
=
TFTPC_FILE_TOO_BIG
;
goto
err_handler
;
}
}
err_handler:
mem_free
(
pstSendBuf
);
mem_free
(
pstRecvBuf
);
return
ulErrCode
;
}
#endif
#endif
/* LOSCFG_NET_LWIP_SACK_TFTP */
#endif
/* LWIP_TFTP */
net/lwip-2.1/porting/include/lwip/dhcp.h
浏览文件 @
4f55f678
...
@@ -32,13 +32,32 @@
...
@@ -32,13 +32,32 @@
#ifndef _LWIP_PORTING_DHCP_H_
#ifndef _LWIP_PORTING_DHCP_H_
#define _LWIP_PORTING_DHCP_H_
#define _LWIP_PORTING_DHCP_H_
#include <lwip/opt.h>
#if LWIP_DHCPS
#define DHCP_OPTION_IDX_SERVER_ID DHCP_OPTION_IDX_SERVER_ID, \
DHCP_OPTION_IDX_REQUESTED_IP
#endif
#include_next <lwip/dhcp.h>
#include_next <lwip/dhcp.h>
#if LWIP_DHCPS
#undef DHCP_OPTION_IDX_SERVER_ID
#endif
#include <lwip/prot/dhcp.h> // For DHCP_STATE_BOUND, DHCP_DISCOVER etc. by `mac/common/mac_data.c'
#include <lwip/prot/dhcp.h> // For DHCP_STATE_BOUND, DHCP_DISCOVER etc. by `mac/common/mac_data.c'
#ifdef __cplusplus
#ifdef __cplusplus
extern
"C"
{
extern
"C"
{
#endif
#endif
#if LWIP_DHCPS
#define LWIP_HOOK_DHCP_PARSE_OPTION(netif, dhcp, state, msg, msg_type, option, len, pbuf, offset) \
LWIP_UNUSED_ARG(msg); \
break; \
case (DHCP_OPTION_REQUESTED_IP): \
LWIP_ERROR("len == 4", len == 4, return ERR_VAL); \
decode_idx = DHCP_OPTION_IDX_REQUESTED_IP;
#endif
err_t
dhcp_is_bound
(
struct
netif
*
netif
);
err_t
dhcp_is_bound
(
struct
netif
*
netif
);
#ifdef __cplusplus
#ifdef __cplusplus
...
...
net/lwip-2.1/porting/include/lwip/lwipopts.h
浏览文件 @
4f55f678
...
@@ -32,6 +32,7 @@
...
@@ -32,6 +32,7 @@
#ifndef _LWIP_PORTING_LWIPOPTS_H_
#ifndef _LWIP_PORTING_LWIPOPTS_H_
#define _LWIP_PORTING_LWIPOPTS_H_
#define _LWIP_PORTING_LWIPOPTS_H_
#include "menuconfig.h"
// lwIP debug options, comment the ones you don't want
// lwIP debug options, comment the ones you don't want
#if LWIP_DEBUG
#if LWIP_DEBUG
...
@@ -215,6 +216,9 @@
...
@@ -215,6 +216,9 @@
#define LWIP_CONFIG_NUM_SOCKETS 128
#define LWIP_CONFIG_NUM_SOCKETS 128
#define IP_REASS_MAX_MEM_SIZE (MEM_SIZE / 4)
#define IP_REASS_MAX_MEM_SIZE (MEM_SIZE / 4)
// Options for enhancement code, same for old lwipopts.h
#define LWIP_NETIF_PROMISC 1
#define LWIP_TFTP LOSCFG_NET_LWIP_SACK_TFTP
#define LWIP_DHCPS 1
#define LWIP_DHCPS 1
#define LWIP_ENABLE_NET_CAPABILITY 1
#define LWIP_ENABLE_NET_CAPABILITY 1
...
...
net/lwip-2.1/porting/include/lwip/netif.h
浏览文件 @
4f55f678
...
@@ -35,16 +35,23 @@
...
@@ -35,16 +35,23 @@
#include <net/if.h> // For IFNAMSIZ/IF_NAMESIZE and `struct ifreq', by `lwip/netif.h' and `api/sockets.c'
#include <net/if.h> // For IFNAMSIZ/IF_NAMESIZE and `struct ifreq', by `lwip/netif.h' and `api/sockets.c'
#include <netinet/ip.h> // For IP_OFFMASK, by `core/ipv4/ip4_frag.c'
#include <netinet/ip.h> // For IP_OFFMASK, by `core/ipv4/ip4_frag.c'
struct
dhcps
;
#define netif_find netifapi_netif_find_by_name
#if LWIP_DHCPS
#define LWIP_NETIF_CLIENT_DATA_INDEX_DHCP LWIP_NETIF_CLIENT_DATA_INDEX_DHCP, \
LWIP_NETIF_CLIENT_DATA_INDEX_DHCPS
#endif
#define linkoutput linkoutput; \
#define linkoutput linkoutput; \
void (*drv_send)(struct netif *netif, struct pbuf *p); \
void (*drv_send)(struct netif *netif, struct pbuf *p); \
u8_t (*drv_set_hwaddr)(struct netif *netif, u8_t *addr, u8_t len); \
u8_t (*drv_set_hwaddr)(struct netif *netif, u8_t *addr, u8_t len); \
void (*drv_config)(struct netif *netif, u32_t config_flags, u8_t setBit); \
void (*drv_config)(struct netif *netif, u32_t config_flags, u8_t setBit); \
struct dhcps *dhcps; \
char full_name[IFNAMSIZ]; \
char full_name[IFNAMSIZ]; \
u16_t link_layer_type
u16_t link_layer_type
#include_next <lwip/netif.h>
#include_next <lwip/netif.h>
#undef linkoutput
#undef linkoutput
#if LWIP_DHCPS
#undef LWIP_NETIF_CLIENT_DATA_INDEX_DHCP
#endif
#include <lwip/etharp.h> // For ETHARP_HWADDR_LEN, by `hieth-sf src/interface.c' and `wal/wal_net.c'
#include <lwip/etharp.h> // For ETHARP_HWADDR_LEN, by `hieth-sf src/interface.c' and `wal/wal_net.c'
...
@@ -64,9 +71,7 @@ err_t driverif_init(struct netif *netif);
...
@@ -64,9 +71,7 @@ err_t driverif_init(struct netif *netif);
void
driverif_input
(
struct
netif
*
netif
,
struct
pbuf
*
p
);
void
driverif_input
(
struct
netif
*
netif
,
struct
pbuf
*
p
);
#ifndef __LWIP__
#ifndef __LWIP__
struct
netif
*
netifapi_netif_find_by_name
(
const
char
*
name
);
#define PF_PKT_SUPPORT LWIP_NETIF_PROMISC
#define PF_PKT_SUPPORT 1 // For netif->drv_config
#define netif_find(name) netifapi_netif_find_by_name(name)
#define netif_add(a, b, c, d) netif_add(a, b, c, d, (a)->state, driverif_init, tcpip_input)
#define netif_add(a, b, c, d) netif_add(a, b, c, d, (a)->state, driverif_init, tcpip_input)
#else
/* __LWIP__ */
#else
/* __LWIP__ */
#define netif_get_name(netif) ((netif)->full_name)
#define netif_get_name(netif) ((netif)->full_name)
...
...
net/lwip-2.1/porting/include/lwip/netifapi.h
浏览文件 @
4f55f678
...
@@ -45,6 +45,7 @@ err_t netifapi_dhcps_stop(struct netif *netif);
...
@@ -45,6 +45,7 @@ err_t netifapi_dhcps_stop(struct netif *netif);
#define netifapi_dhcp_is_bound(n) netifapi_netif_common(n, NULL, dhcp_is_bound)
#define netifapi_dhcp_is_bound(n) netifapi_netif_common(n, NULL, dhcp_is_bound)
void
netifapi_netif_rmv_ip6_address
(
struct
netif
*
netif
,
ip_addr_t
*
ipaddr
);
void
netifapi_netif_rmv_ip6_address
(
struct
netif
*
netif
,
ip_addr_t
*
ipaddr
);
struct
netif
*
netifapi_netif_find_by_name
(
const
char
*
name
);
#ifndef __LWIP__
#ifndef __LWIP__
#define netifapi_netif_add(a, b, c, d) netifapi_netif_add(a, b, c, d, (a)->state, driverif_init, tcpip_input)
#define netifapi_netif_add(a, b, c, d) netifapi_netif_add(a, b, c, d, (a)->state, driverif_init, tcpip_input)
...
...
net/lwip-2.1/porting/src/driverif.c
浏览文件 @
4f55f678
...
@@ -44,7 +44,6 @@
...
@@ -44,7 +44,6 @@
#define link_rx_drop cachehit
#define link_rx_drop cachehit
#define link_rx_overrun cachehit
#define link_rx_overrun cachehit
#define NETIF_NAME_LEN 2
#define LWIP_STATIC static
#define LWIP_STATIC static
#ifndef LWIP_NETIF_IFINDEX_MAX_EX
#ifndef LWIP_NETIF_IFINDEX_MAX_EX
...
@@ -57,6 +56,9 @@ driverif_init_ifname(struct netif *netif)
...
@@ -57,6 +56,9 @@ driverif_init_ifname(struct netif *netif)
struct
netif
*
tmpnetif
=
NULL
;
struct
netif
*
tmpnetif
=
NULL
;
const
char
*
prefix
=
(
netif
->
link_layer_type
==
WIFI_DRIVER_IF
)
?
"wlan"
:
"eth"
;
const
char
*
prefix
=
(
netif
->
link_layer_type
==
WIFI_DRIVER_IF
)
?
"wlan"
:
"eth"
;
netif
->
name
[
0
]
=
prefix
[
0
];
netif
->
name
[
1
]
=
prefix
[
1
];
for
(
int
i
=
0
;
i
<
LWIP_NETIF_IFINDEX_MAX_EX
;
++
i
)
{
for
(
int
i
=
0
;
i
<
LWIP_NETIF_IFINDEX_MAX_EX
;
++
i
)
{
if
(
snprintf_s
(
netif
->
full_name
,
sizeof
(
netif
->
full_name
),
sizeof
(
netif
->
full_name
)
-
1
,
if
(
snprintf_s
(
netif
->
full_name
,
sizeof
(
netif
->
full_name
),
sizeof
(
netif
->
full_name
)
-
1
,
"%s%d"
,
prefix
,
i
)
<
0
)
{
"%s%d"
,
prefix
,
i
)
<
0
)
{
...
@@ -140,7 +142,7 @@ driverif_input(struct netif *netif, struct pbuf *p)
...
@@ -140,7 +142,7 @@ driverif_input(struct netif *netif, struct pbuf *p)
#endif
#endif
#else
#else
u16_t
ethhdr_type
;
u16_t
ethhdr_type
;
struct
eth_hdr
*
ethhdr
=
NULL
;
struct
eth_hdr
*
ethhdr
=
NULL
;
#endif
#endif
err_t
ret
=
ERR_VAL
;
err_t
ret
=
ERR_VAL
;
...
@@ -241,7 +243,6 @@ err_t
...
@@ -241,7 +243,6 @@ err_t
driverif_init
(
struct
netif
*
netif
)
driverif_init
(
struct
netif
*
netif
)
{
{
u16_t
link_layer_type
;
u16_t
link_layer_type
;
err_t
ret
;
if
(
netif
==
NULL
)
{
if
(
netif
==
NULL
)
{
return
ERR_IF
;
return
ERR_IF
;
...
@@ -262,17 +263,7 @@ driverif_init(struct netif *netif)
...
@@ -262,17 +263,7 @@ driverif_init(struct netif *netif)
#if LWIP_NETIF_HOSTNAME
#if LWIP_NETIF_HOSTNAME
/* Initialize interface hostname */
/* Initialize interface hostname */
#if LOSCFG_NET_LWIP_SACK_2_0
if
(
strncpy_s
(
netif
->
hostname
,
NETIF_HOSTNAME_MAX_LEN
,
LWIP_NETIF_HOSTNAME_DEFAULT
,
NETIF_HOSTNAME_MAX_LEN
-
1
)
==
EOK
)
{
netif
->
hostname
[
NETIF_HOSTNAME_MAX_LEN
-
1
]
=
'\0'
;
}
else
{
LWIP_DEBUGF
(
DRIVERIF_DEBUG
,
(
"driverif_init: hostname %s in invalid
\n
"
,
LWIP_NETIF_HOSTNAME_DEFAULT
));
netif
->
hostname
[
0
]
=
'\0'
;
}
#else
netif
->
hostname
=
LWIP_NETIF_HOSTNAME_DEFAULT
;
netif
->
hostname
=
LWIP_NETIF_HOSTNAME_DEFAULT
;
#endif
#endif
/* LWIP_NETIF_HOSTNAME */
#endif
/* LWIP_NETIF_HOSTNAME */
/*
/*
...
@@ -285,21 +276,6 @@ driverif_init(struct netif *netif)
...
@@ -285,21 +276,6 @@ driverif_init(struct netif *netif)
netif
->
output
=
etharp_output
;
netif
->
output
=
etharp_output
;
netif
->
linkoutput
=
driverif_output
;
netif
->
linkoutput
=
driverif_output
;
if
(
link_layer_type
==
ETHERNET_DRIVER_IF
)
{
ret
=
memcpy_s
(
netif
->
name
,
sizeof
(
netif
->
name
),
"et"
,
NETIF_NAME_LEN
);
}
else
{
ret
=
memcpy_s
(
netif
->
name
,
sizeof
(
netif
->
name
),
"wl"
,
NETIF_NAME_LEN
);
}
if
(
ret
!=
EOK
)
{
#if LWIP_NETIF_HOSTNAME
#if LOSCFG_NET_LWIP_SACK_2_0
netif
->
hostname
[
0
]
=
'\0'
;
#else
netif
->
hostname
=
NULL
;
#endif
#endif
return
ERR_IF
;
}
/* init the netif's full name */
/* init the netif's full name */
driverif_init_ifname
(
netif
);
driverif_init_ifname
(
netif
);
...
@@ -309,30 +285,30 @@ driverif_init(struct netif *netif)
...
@@ -309,30 +285,30 @@ driverif_init(struct netif *netif)
/* device capabilities */
/* device capabilities */
/* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */
/* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */
netif
->
flags
=
NETIF_FLAG_BROADCAST
|
NETIF_FLAG_ETHARP
|
netif
->
flags
=
NETIF_FLAG_BROADCAST
|
NETIF_FLAG_ETHARP
|
#if DRIVER_STATUS_CHECK
#if DRIVER_STATUS_CHECK
NETIF_FLAG_DRIVER_RDY
|
NETIF_FLAG_DRIVER_RDY
|
#endif
#endif
#if LWIP_IGMP
#if LWIP_IGMP
NETIF_FLAG_IGMP
|
NETIF_FLAG_IGMP
|
#endif
#endif
/**
/**
@page RFC-2710 RFC-2710
@page RFC-2710 RFC-2710
@par Compliant Sections
@par Compliant Sections
Section 5. Node State Transition Diagram
Section 5. Node State Transition Diagram
@par Behavior Description
@par Behavior Description
MLD messages are sent for multicast addresses whose scope is 2
MLD messages are sent for multicast addresses whose scope is 2
(link-local), including Solicited-Node multicast addresses.\n
(link-local), including Solicited-Node multicast addresses.\n
Behavior:Stack will send MLD6 report /Done to solicited node multicast address
Behavior:Stack will send MLD6 report /Done to solicited node multicast address
if the LWIP_MLD6_ENABLE_MLD_ON_DAD is enabled. By default, this is disabled.
if the LWIP_MLD6_ENABLE_MLD_ON_DAD is enabled. By default, this is disabled.
*/
*/
/* Enable sending MLD report /done for solicited address during neighbour discovery */
/* Enable sending MLD report /done for solicited address during neighbour discovery */
#if LWIP_IPV6 && LWIP_IPV6_MLD
#if LWIP_IPV6 && LWIP_IPV6_MLD
#if LWIP_MLD6_ENABLE_MLD_ON_DAD
#if LWIP_MLD6_ENABLE_MLD_ON_DAD
NETIF_FLAG_MLD6
|
NETIF_FLAG_MLD6
|
#endif
/* LWIP_MLD6_ENABLE_MLD_ON_DAD */
#endif
/* LWIP_MLD6_ENABLE_MLD_ON_DAD */
#endif
#endif
NETIF_FLAG_LINK_UP
;
NETIF_FLAG_LINK_UP
;
#if DRIVER_STATUS_CHECK
#if DRIVER_STATUS_CHECK
netif
->
waketime
=
-
1
;
netif
->
waketime
=
-
1
;
...
...
net/lwip-2.1/porting/src/fixme.c
已删除
100755 → 0
浏览文件 @
9b25a48d
/*
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <lwip/netif.h>
#include <lwip/dhcp.h>
err_t
dhcp_is_bound
(
struct
netif
*
netif
)
{
return
(
netif_dhcp_data
(
netif
)
?
(
netif_dhcp_data
(
netif
)
->
state
==
DHCP_STATE_BOUND
)
?
ERR_OK
:
ERR_INPROGRESS
:
ERR_ARG
);
}
#if (LWIP_CHKSUM_ALGORITHM == 4)
/* version #4, asm based */
#include "in_cksum.h"
u16_t
lwip_standard_chksum
(
const
void
*
dataptr
,
int
len
)
{
return
~
(
u16_t
)(
in_cksum
(
dataptr
,
len
));
}
#endif
net/lwip-2.1/porting/src/sockets.c
浏览文件 @
4f55f678
...
@@ -31,7 +31,7 @@
...
@@ -31,7 +31,7 @@
#include <lwip/sockets.h>
#include <lwip/sockets.h>
#include <lwip/priv/tcpip_priv.h>
#include <lwip/priv/tcpip_priv.h>
#include <
api_shell_fix
.h>
#include <
lwip/fixme
.h>
#if LWIP_ENABLE_NET_CAPABILITY
#if LWIP_ENABLE_NET_CAPABILITY
#include "capability_type.h"
#include "capability_type.h"
...
@@ -39,8 +39,6 @@
...
@@ -39,8 +39,6 @@
#define BIND_SERVICE_CAP_MIN_PORT 1024
#define BIND_SERVICE_CAP_MIN_PORT 1024
#endif
#endif
#define netif_find netifapi_netif_find_by_name
#define IOCTL_CMD_CASE_HANDLER() \
#define IOCTL_CMD_CASE_HANDLER() \
{ \
{ \
err_t err; \
err_t err; \
...
@@ -86,7 +84,8 @@ int lwip_bind(int s, const struct sockaddr *name, socklen_t namelen)
...
@@ -86,7 +84,8 @@ int lwip_bind(int s, const struct sockaddr *name, socklen_t namelen)
return
lwip_bind_wrap
(
s
,
name
,
namelen
);
return
lwip_bind_wrap
(
s
,
name
,
namelen
);
}
}
static
ssize_t
lwip_sendto_wrap
(
int
s
,
const
void
*
dataptr
,
size_t
size
,
int
flags
,
const
struct
sockaddr
*
to
,
socklen_t
tolen
);
static
ssize_t
lwip_sendto_wrap
(
int
s
,
const
void
*
dataptr
,
size_t
size
,
int
flags
,
const
struct
sockaddr
*
to
,
socklen_t
tolen
);
ssize_t
lwip_sendto
(
int
s
,
const
void
*
dataptr
,
size_t
size
,
int
flags
,
const
struct
sockaddr
*
to
,
socklen_t
tolen
)
ssize_t
lwip_sendto
(
int
s
,
const
void
*
dataptr
,
size_t
size
,
int
flags
,
const
struct
sockaddr
*
to
,
socklen_t
tolen
)
{
{
return
lwip_sendto_wrap
(
s
,
dataptr
,
size
,
flags
,
to
,
tolen
);
return
lwip_sendto_wrap
(
s
,
dataptr
,
size
,
flags
,
to
,
tolen
);
...
@@ -233,12 +232,12 @@ static int lwip_bind_wrap(int s, const struct sockaddr *name, socklen_t namelen)
...
@@ -233,12 +232,12 @@ static int lwip_bind_wrap(int s, const struct sockaddr *name, socklen_t namelen)
}
}
static
ssize_t
lwip_sendto_wrap
(
int
s
,
const
void
*
dataptr
,
size_t
size
,
int
flags
,
static
ssize_t
lwip_sendto_wrap
(
int
s
,
const
void
*
dataptr
,
size_t
size
,
int
flags
,
const
struct
sockaddr
*
to
,
socklen_t
tolen
)
const
struct
sockaddr
*
to
,
socklen_t
tolen
)
{
{
#if LWIP_ENABLE_NET_CAPABILITY
#if LWIP_ENABLE_NET_CAPABILITY
if
(
to
&&
if
(
to
&&
((
to
->
sa_family
==
AF_INET
&&
tolen
>=
sizeof
(
struct
sockaddr_in
))
||
((
to
->
sa_family
==
AF_INET
&&
tolen
>=
sizeof
(
struct
sockaddr_in
))
||
(
to
->
sa_family
==
AF_INET6
&&
tolen
>=
sizeof
(
struct
sockaddr_in6
))))
{
(
to
->
sa_family
==
AF_INET6
&&
tolen
>=
sizeof
(
struct
sockaddr_in6
))))
{
ip_addr_t
ipaddr
;
ip_addr_t
ipaddr
;
u16_t
port
;
u16_t
port
;
...
@@ -372,7 +371,6 @@ int get_unused_socket_num(void)
...
@@ -372,7 +371,6 @@ int get_unused_socket_num(void)
// Options for lwip ioctl
// Options for lwip ioctl
#define LWIP_IOCTL_ROUTE 1
#define LWIP_IOCTL_ROUTE 1
#define LWIP_IOCTL_IF 1
#define LWIP_IOCTL_IF 1
#define LWIP_NETIF_PROMISC 1
#define LWIP_NETIF_ETHTOOL 0
#define LWIP_NETIF_ETHTOOL 0
#define LWIP_IOCTL_IPV6DPCTD 0
#define LWIP_IOCTL_IPV6DPCTD 0
#undef LWIP_IPV6_DUP_DETECT_ATTEMPTS
#undef LWIP_IPV6_DUP_DETECT_ATTEMPTS
...
@@ -764,7 +762,7 @@ static u8_t lwip_ioctl_internal_SIOCSIFNETMASK(struct ifreq *ifr)
...
@@ -764,7 +762,7 @@ static u8_t lwip_ioctl_internal_SIOCSIFNETMASK(struct ifreq *ifr)
loc_netif
=
loc_netif
->
next
;
loc_netif
=
loc_netif
->
next
;
}
}
#if LWIP_DHCP
// LWIP_DHCP
#if LWIP_DHCP
if
((
netif_dhcp_data
(
netif
)
!=
NULL
)
&&
if
((
netif_dhcp_data
(
netif
)
!=
NULL
)
&&
(
netif_dhcp_data
(
netif
)
->
state
!=
DHCP_STATE_OFF
))
{
(
netif_dhcp_data
(
netif
)
->
state
!=
DHCP_STATE_OFF
))
{
(
void
)
netif_dhcp_off
(
netif
);
(
void
)
netif_dhcp_off
(
netif
);
...
...
net/lwip-2.1/porting/src/sys_arch.c
浏览文件 @
4f55f678
...
@@ -46,6 +46,7 @@ static u32_t lwprot_thread = LOS_ERRNO_TSK_ID_INVALID;
...
@@ -46,6 +46,7 @@ static u32_t lwprot_thread = LOS_ERRNO_TSK_ID_INVALID;
static
int
lwprot_count
=
0
;
static
int
lwprot_count
=
0
;
#endif
/* LOSCFG_KERNEL_SMP == YES */
#endif
/* LOSCFG_KERNEL_SMP == YES */
#define ROUND_UP_DIV(val, div) (((val) + (div) - 1) / (div))
/**
/**
* Thread and System misc
* Thread and System misc
...
@@ -59,11 +60,11 @@ sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread, void *arg,
...
@@ -59,11 +60,11 @@ sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread, void *arg,
/* Create host Task */
/* Create host Task */
task
.
pfnTaskEntry
=
(
TSK_ENTRY_FUNC
)
thread
;
task
.
pfnTaskEntry
=
(
TSK_ENTRY_FUNC
)
thread
;
task
.
uwStackSize
=
stackSize
;
task
.
uwStackSize
=
stackSize
;
task
.
pcName
=
(
char
*
)
name
;
task
.
pcName
=
(
char
*
)
name
;
task
.
usTaskPrio
=
prio
;
task
.
usTaskPrio
=
prio
;
task
.
auwArgs
[
0
]
=
(
UINTPTR
)
arg
;
task
.
auwArgs
[
0
]
=
(
UINTPTR
)
arg
;
task
.
uwResved
=
LOS_TASK_STATUS_DETACHED
;
task
.
uwResved
=
LOS_TASK_STATUS_DETACHED
;
ret
=
LOS_TaskCreate
(
&
taskID
,
&
task
);
ret
=
LOS_TaskCreate
(
&
taskID
,
&
task
);
if
(
ret
!=
LOS_OK
)
{
if
(
ret
!=
LOS_OK
)
{
LWIP_DEBUGF
(
SYS_DEBUG
,
(
"sys_thread_new: LOS_TaskCreate error %u
\n
"
,
ret
));
LWIP_DEBUGF
(
SYS_DEBUG
,
(
"sys_thread_new: LOS_TaskCreate error %u
\n
"
,
ret
));
...
@@ -84,9 +85,17 @@ void sys_init(void)
...
@@ -84,9 +85,17 @@ void sys_init(void)
u32_t
sys_now
(
void
)
u32_t
sys_now
(
void
)
{
{
/* Lwip docs mentioned like wraparound is not a problem in this funtion */
/* Lwip docs mentioned like wraparound is not a problem in this funtion */
return
(
u32_t
)((
(
double
)
LOS_TickCountGet
()
*
OS_SYS_MS_PER_SECOND
)
/
LOSCFG_BASE_CORE_TICK_PER_SECOND
);
return
(
u32_t
)((
LOS_TickCountGet
()
*
OS_SYS_MS_PER_SECOND
)
/
LOSCFG_BASE_CORE_TICK_PER_SECOND
);
}
}
#if (LWIP_CHKSUM_ALGORITHM == 4)
/* version #4, asm based */
#include "in_cksum.h"
u16_t
lwip_standard_chksum
(
const
void
*
dataptr
,
int
len
)
{
return
~
(
u16_t
)(
in_cksum
(
dataptr
,
len
));
}
#endif
/**
/**
* Protector
* Protector
...
@@ -140,7 +149,7 @@ void sys_arch_unprotect(sys_prot_t pval)
...
@@ -140,7 +149,7 @@ void sys_arch_unprotect(sys_prot_t pval)
err_t
sys_mbox_new
(
sys_mbox_t
*
mbox
,
int
size
)
err_t
sys_mbox_new
(
sys_mbox_t
*
mbox
,
int
size
)
{
{
CHAR
qName
[]
=
"lwIP"
;
CHAR
qName
[]
=
"lwIP"
;
UINT32
ret
=
LOS_QueueCreate
(
qName
,
(
UINT16
)
size
,
mbox
,
0
,
sizeof
(
void
*
));
UINT32
ret
=
LOS_QueueCreate
(
qName
,
(
UINT16
)
size
,
mbox
,
0
,
sizeof
(
void
*
));
switch
(
ret
)
{
switch
(
ret
)
{
case
LOS_OK
:
case
LOS_OK
:
return
ERR_OK
;
return
ERR_OK
;
...
@@ -184,8 +193,8 @@ err_t sys_mbox_trypost_fromisr(sys_mbox_t *mbox, void *msg);
...
@@ -184,8 +193,8 @@ err_t sys_mbox_trypost_fromisr(sys_mbox_t *mbox, void *msg);
u32_t
sys_arch_mbox_fetch
(
sys_mbox_t
*
mbox
,
void
**
msg
,
u32_t
timeoutMs
)
u32_t
sys_arch_mbox_fetch
(
sys_mbox_t
*
mbox
,
void
**
msg
,
u32_t
timeoutMs
)
{
{
void
*
ignore
=
0
;
/* if msg==NULL, the fetched msg should be dropped */
void
*
ignore
=
0
;
/* if msg==NULL, the fetched msg should be dropped */
UINT64
tick
=
((
UINT64
)
timeoutMs
*
LOSCFG_BASE_CORE_TICK_PER_SECOND
+
OS_SYS_MS_PER_SECOND
-
1
)
/
OS_SYS_MS_PER_SECOND
;
UINT64
tick
=
ROUND_UP_DIV
((
UINT64
)
timeoutMs
*
LOSCFG_BASE_CORE_TICK_PER_SECOND
,
OS_SYS_MS_PER_SECOND
)
;
UINT32
ret
=
LOS_QueueRead
(
*
mbox
,
msg
?
msg
:
&
ignore
,
sizeof
(
void
*
),
tick
?
(
UINT32
)
tick
:
LOS_WAIT_FOREVER
);
UINT32
ret
=
LOS_QueueRead
(
*
mbox
,
msg
?
msg
:
&
ignore
,
sizeof
(
void
*
),
tick
?
(
UINT32
)
tick
:
LOS_WAIT_FOREVER
);
switch
(
ret
)
{
switch
(
ret
)
{
case
LOS_OK
:
case
LOS_OK
:
return
ERR_OK
;
return
ERR_OK
;
...
@@ -202,7 +211,7 @@ u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeoutMs)
...
@@ -202,7 +211,7 @@ u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeoutMs)
u32_t
sys_arch_mbox_tryfetch
(
sys_mbox_t
*
mbox
,
void
**
msg
)
u32_t
sys_arch_mbox_tryfetch
(
sys_mbox_t
*
mbox
,
void
**
msg
)
{
{
void
*
ignore
=
0
;
/* if msg==NULL, the fetched msg should be dropped */
void
*
ignore
=
0
;
/* if msg==NULL, the fetched msg should be dropped */
UINT32
ret
=
LOS_QueueRead
(
*
mbox
,
msg
?
msg
:
&
ignore
,
sizeof
(
void
*
),
0
);
UINT32
ret
=
LOS_QueueRead
(
*
mbox
,
msg
?
msg
:
&
ignore
,
sizeof
(
void
*
),
0
);
switch
(
ret
)
{
switch
(
ret
)
{
case
LOS_OK
:
case
LOS_OK
:
return
ERR_OK
;
return
ERR_OK
;
...
@@ -255,7 +264,7 @@ void sys_sem_signal(sys_sem_t *sem)
...
@@ -255,7 +264,7 @@ void sys_sem_signal(sys_sem_t *sem)
u32_t
sys_arch_sem_wait
(
sys_sem_t
*
sem
,
u32_t
timeoutMs
)
u32_t
sys_arch_sem_wait
(
sys_sem_t
*
sem
,
u32_t
timeoutMs
)
{
{
UINT64
tick
=
((
UINT64
)
timeoutMs
*
LOSCFG_BASE_CORE_TICK_PER_SECOND
+
OS_SYS_MS_PER_SECOND
-
1
)
/
OS_SYS_MS_PER_SECOND
;
UINT64
tick
=
ROUND_UP_DIV
((
UINT64
)
timeoutMs
*
LOSCFG_BASE_CORE_TICK_PER_SECOND
,
OS_SYS_MS_PER_SECOND
)
;
UINT32
ret
=
LOS_SemPend
(
*
sem
,
tick
?
(
UINT32
)
tick
:
LOS_WAIT_FOREVER
);
// timeoutMs 0 means wait forever
UINT32
ret
=
LOS_SemPend
(
*
sem
,
tick
?
(
UINT32
)
tick
:
LOS_WAIT_FOREVER
);
// timeoutMs 0 means wait forever
switch
(
ret
)
{
switch
(
ret
)
{
case
LOS_OK
:
case
LOS_OK
:
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录