2626
2727static sys_slist_t handlers ;
2828
29+ struct net_icmp_hdr * net_icmpv4_set_hdr (struct net_pkt * pkt ,
30+ struct net_icmp_hdr * hdr )
31+ {
32+ struct net_icmp_hdr * icmp_hdr ;
33+ struct net_buf * frag ;
34+ u16_t pos ;
35+
36+ icmp_hdr = net_pkt_icmp_data (pkt );
37+ if (net_icmp_header_fits (pkt , icmp_hdr )) {
38+ return icmp_hdr ;
39+ }
40+
41+ frag = net_pkt_write_u8 (pkt , pkt -> frags ,
42+ net_pkt_ip_hdr_len (pkt ),
43+ & pos , hdr -> type );
44+ frag = net_pkt_write_u8 (pkt , frag , pos , & pos , hdr -> code );
45+ frag = net_pkt_write (pkt , frag , pos , & pos , sizeof (hdr -> chksum ),
46+ (u8_t * )& hdr -> chksum , PKT_WAIT_TIME );
47+ if (!frag ) {
48+ NET_ASSERT (frag );
49+ return NULL ;
50+ }
51+
52+ return hdr ;
53+ }
54+
55+ struct net_icmp_hdr * net_icmpv4_get_hdr (struct net_pkt * pkt ,
56+ struct net_icmp_hdr * hdr )
57+ {
58+ struct net_icmp_hdr * icmp_hdr ;
59+ struct net_buf * frag ;
60+ u16_t pos ;
61+
62+ icmp_hdr = net_pkt_icmp_data (pkt );
63+ if (net_icmp_header_fits (pkt , icmp_hdr )) {
64+ return icmp_hdr ;
65+ }
66+
67+ frag = net_frag_read_u8 (pkt -> frags , net_pkt_ip_hdr_len (pkt ), & pos ,
68+ & hdr -> type );
69+ frag = net_frag_read_u8 (frag , pos , & pos , & hdr -> code );
70+ frag = net_frag_read (frag , pos , & pos , sizeof (hdr -> chksum ),
71+ (u8_t * )& hdr -> chksum );
72+ if (!frag ) {
73+ NET_ASSERT (frag );
74+ return NULL ;
75+ }
76+
77+ return hdr ;
78+ }
79+
80+ struct net_buf * net_icmpv4_set_chksum (struct net_pkt * pkt ,
81+ struct net_buf * frag )
82+ {
83+ struct net_icmp_hdr * icmp_hdr ;
84+ u16_t chksum = 0 ;
85+ u16_t pos ;
86+
87+ icmp_hdr = net_pkt_icmp_data (pkt );
88+ if (net_icmp_header_fits (pkt , icmp_hdr )) {
89+ icmp_hdr -> chksum = 0 ;
90+ icmp_hdr -> chksum = ~net_calc_chksum_icmpv4 (pkt );
91+
92+ return frag ;
93+ }
94+
95+ frag = net_pkt_write (pkt , frag ,
96+ net_pkt_ip_hdr_len (pkt ) +
97+ 1 + 1 /* type + code */ , & pos ,
98+ sizeof (chksum ), (u8_t * )& chksum , PKT_WAIT_TIME );
99+
100+ chksum = ~net_calc_chksum_icmpv4 (pkt );
101+
102+ frag = net_pkt_write (pkt , frag , pos - 2 , & pos , sizeof (chksum ),
103+ (u8_t * )& chksum , PKT_WAIT_TIME );
104+
105+ NET_ASSERT (frag );
106+
107+ return frag ;
108+ }
109+
29110static inline enum net_verdict handle_echo_request (struct net_pkt * pkt )
30111{
31112 /* Note that we send the same data packets back and just swap
32113 * the addresses etc.
33114 */
115+ struct net_icmp_hdr hdr , * icmp_hdr ;
34116 struct in_addr addr ;
35117
36118#if defined(CONFIG_NET_DEBUG_ICMPV4 )
@@ -47,10 +129,12 @@ static inline enum net_verdict handle_echo_request(struct net_pkt *pkt)
47129 & NET_IPV4_HDR (pkt )-> dst );
48130 net_ipaddr_copy (& NET_IPV4_HDR (pkt )-> dst , & addr );
49131
50- NET_ICMP_HDR (pkt )-> type = NET_ICMPV4_ECHO_REPLY ;
51- NET_ICMP_HDR (pkt )-> code = 0 ;
52- NET_ICMP_HDR (pkt )-> chksum = 0 ;
53- NET_ICMP_HDR (pkt )-> chksum = ~net_calc_chksum_icmpv4 (pkt );
132+ icmp_hdr = net_icmpv4_get_hdr (pkt , & hdr );
133+ icmp_hdr -> type = NET_ICMPV4_ECHO_REPLY ;
134+ icmp_hdr -> code = 0 ;
135+ icmp_hdr -> chksum = 0 ;
136+ net_icmpv4_set_hdr (pkt , icmp_hdr );
137+ net_icmpv4_set_chksum (pkt , pkt -> frags );
54138
55139#if defined(CONFIG_NET_DEBUG_ICMPV4 )
56140 snprintk (out , sizeof (out ), "%s" ,
@@ -75,6 +159,9 @@ static inline void setup_ipv4_header(struct net_pkt *pkt, u8_t extra_len,
75159 u8_t ttl , u8_t icmp_type ,
76160 u8_t icmp_code )
77161{
162+ struct net_buf * frag = pkt -> frags ;
163+ u16_t pos ;
164+
78165 NET_IPV4_HDR (pkt )-> vhl = 0x45 ;
79166 NET_IPV4_HDR (pkt )-> tos = 0x00 ;
80167 NET_IPV4_HDR (pkt )-> len [0 ] = 0 ;
@@ -91,11 +178,10 @@ static inline void setup_ipv4_header(struct net_pkt *pkt, u8_t extra_len,
91178 NET_IPV4_HDR (pkt )-> chksum = 0 ;
92179 NET_IPV4_HDR (pkt )-> chksum = ~net_calc_chksum_ipv4 (pkt );
93180
94- NET_ICMP_HDR (pkt )-> type = icmp_type ;
95- NET_ICMP_HDR (pkt )-> code = icmp_code ;
96-
97- memset (net_pkt_icmp_data (pkt ) + sizeof (struct net_icmp_hdr ), 0 ,
98- NET_ICMPV4_UNUSED_LEN );
181+ frag = net_pkt_write_u8 (pkt , frag , net_pkt_ip_hdr_len (pkt ), & pos ,
182+ icmp_type );
183+ frag = net_pkt_write_u8 (pkt , frag , pos , & pos , icmp_code );
184+ net_pkt_write_be32 (pkt , frag , pos , & pos , 0 );
99185}
100186
101187int net_icmpv4_send_echo_request (struct net_if * iface ,
@@ -133,8 +219,7 @@ int net_icmpv4_send_echo_request(struct net_if *iface,
133219 NET_ICMPV4_ECHO_REQ (pkt )-> identifier = htons (identifier );
134220 NET_ICMPV4_ECHO_REQ (pkt )-> sequence = htons (sequence );
135221
136- NET_ICMP_HDR (pkt )-> chksum = 0 ;
137- NET_ICMP_HDR (pkt )-> chksum = ~net_calc_chksum_icmpv4 (pkt );
222+ net_icmpv4_set_chksum (pkt , pkt -> frags );
138223
139224#if defined(CONFIG_NET_DEBUG_ICMPV4 )
140225 do {
@@ -174,7 +259,10 @@ int net_icmpv4_send_error(struct net_pkt *orig, u8_t type, u8_t code)
174259 int err = - EIO ;
175260
176261 if (NET_IPV4_HDR (orig )-> proto == IPPROTO_ICMP ) {
177- if (NET_ICMP_HDR (orig )-> code < 8 ) {
262+ struct net_icmp_hdr icmp_hdr [1 ];
263+
264+ if (!net_icmpv4_get_hdr (orig , icmp_hdr ) ||
265+ icmp_hdr -> code < 8 ) {
178266 /* We must not send ICMP errors back */
179267 err = - EINVAL ;
180268 goto drop_no_pkt ;
@@ -241,8 +329,7 @@ int net_icmpv4_send_error(struct net_pkt *orig, u8_t type, u8_t code)
241329 net_pkt_ll_dst (pkt )-> addr = net_pkt_ll_src (orig )-> addr ;
242330 net_pkt_ll_dst (pkt )-> len = net_pkt_ll_src (orig )-> len ;
243331
244- NET_ICMP_HDR (pkt )-> chksum = 0 ;
245- NET_ICMP_HDR (pkt )-> chksum = ~net_calc_chksum_icmpv4 (pkt );
332+ net_icmpv4_set_chksum (pkt , pkt -> frags );
246333
247334#if defined(CONFIG_NET_DEBUG_ICMPV4 )
248335 do {
0 commit comments