Skip to content

Commit 729abe8

Browse files
committed
Fixed TTL expired. Traceroute now works
1 parent daeb5c1 commit 729abe8

1 file changed

Lines changed: 24 additions & 9 deletions

File tree

src/wolfip.c

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
417421
struct 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);
768780
static void iphdr_set_checksum(struct wolfIP_ip_packet *ip);
769781
static 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
778790
static 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
800815
static 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

Comments
 (0)