@@ -414,11 +414,23 @@ union transport_pseudo_header {
414414};
415415
416416/* ICMP */
417+
418+ #define TTL_EXCEEDED_ORIG_PACKET_SIZE (28)
419+ #define ICMP_TTL_EXCEEDED_SIZE (36)
420+
417421struct PACKED wolfIP_icmp_packet {
418422 struct wolfIP_ip_packet ip ;
419423 uint8_t type , code ;
420424 uint16_t csum ;
421- uint8_t data [0 ];
425+ uint8_t unused [4 ];
426+ };
427+
428+ struct PACKED wolfIP_icmp_ttl_exceeded_packet {
429+ struct wolfIP_ip_packet ip ;
430+ uint8_t type , code ;
431+ uint16_t csum ;
432+ uint8_t unused [4 ];
433+ uint8_t orig_packet [TTL_EXCEEDED_ORIG_PACKET_SIZE ];
422434};
423435
424436/* DHCP */
@@ -764,7 +776,7 @@ static unsigned int wolfIP_if_for_local_ip(struct wolfIP *s, ip4 local_ip, int *
764776}
765777
766778#ifdef ETHERNET
767- static uint16_t icmp_checksum (struct wolfIP_icmp_packet * icmp );
779+ static uint16_t icmp_checksum (struct wolfIP_icmp_packet * icmp , uint16_t len );
768780static void iphdr_set_checksum (struct wolfIP_ip_packet * ip );
769781static int eth_output_add_header (struct wolfIP * S , unsigned int if_idx , const uint8_t * dst , struct wolfIP_eth_frame * eth ,
770782 uint16_t type );
@@ -778,23 +790,26 @@ static int arp_lookup(struct wolfIP *s, unsigned int if_idx, ip4 ip, uint8_t *ma
778790static void wolfIP_send_ttl_exceeded (struct wolfIP * s , unsigned int if_idx , struct wolfIP_ip_packet * orig )
779791{
780792 struct wolfIP_ll_dev * ll = wolfIP_ll_at (s , if_idx );
781- struct wolfIP_icmp_packet icmp ;
793+ struct wolfIP_icmp_ttl_exceeded_packet icmp ;
782794 if (!ll || !ll -> send )
783795 return ;
784796 memset (& icmp , 0 , sizeof (icmp ));
785797 icmp .type = ICMP_TTL_EXCEEDED ;
786- icmp .csum = ee16 (icmp_checksum (& icmp ));
798+ memcpy (icmp .orig_packet , ((uint8_t * )orig ) + ETH_HEADER_LEN ,
799+ TTL_EXCEEDED_ORIG_PACKET_SIZE );
800+ icmp .csum = ee16 (icmp_checksum ((struct wolfIP_icmp_packet * )& icmp ,
801+ ICMP_TTL_EXCEEDED_SIZE ));
787802 icmp .ip .ver_ihl = 0x45 ;
788803 icmp .ip .ttl = 64 ;
789804 icmp .ip .proto = WI_IPPROTO_ICMP ;
790805 icmp .ip .id = ee16 (s -> ipcounter ++ );
791- icmp .ip .len = ee16 (IP_HEADER_LEN + ICMP_HEADER_LEN );
792- icmp .ip .src = orig -> dst ;
806+ icmp .ip .len = ee16 (IP_HEADER_LEN + ICMP_TTL_EXCEEDED_SIZE );
807+ icmp .ip .src = ee32 ( wolfIP_ipconf_at ( s , if_idx ) -> ip ) ;
793808 icmp .ip .dst = orig -> src ;
794809 icmp .ip .csum = 0 ;
795810 iphdr_set_checksum (& icmp .ip );
796811 eth_output_add_header (s , if_idx , orig -> eth .src , & icmp .ip .eth , ETH_TYPE_IP );
797- ll -> send (ll , & icmp , sizeof (struct wolfIP_icmp_packet ));
812+ ll -> send (ll , & icmp , sizeof (icmp ));
798813}
799814#else
800815static void wolfIP_send_ttl_exceeded (struct wolfIP * s , unsigned int if_idx , struct wolfIP_ip_packet * orig )
@@ -1093,12 +1108,12 @@ static uint16_t transport_checksum(union transport_pseudo_header *ph, void *_dat
10931108 return ~sum ;
10941109}
10951110
1096- static uint16_t icmp_checksum (struct wolfIP_icmp_packet * icmp )
1111+ static uint16_t icmp_checksum (struct wolfIP_icmp_packet * icmp , uint16_t len )
10971112{
10981113 uint32_t sum = 0 ;
10991114 uint32_t i = 0 ;
11001115 uint16_t * ptr = (uint16_t * )(& icmp -> type );
1101- for (i = 0 ; i < ICMP_HEADER_LEN / 2 ; i ++ ) {
1116+ for (i = 0 ; i < len / 2 ; i ++ ) {
11021117 sum += ee16 (ptr [i ]);
11031118 }
11041119 while (sum >> 16 ) {
0 commit comments