Skip to content

Commit ae32104

Browse files
committed
Improved/fixed test for TTL exceeded
1 parent 729abe8 commit ae32104

1 file changed

Lines changed: 61 additions & 8 deletions

File tree

src/test/test_ttl_expired.c

Lines changed: 61 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
#define ROUTER_GW IP4(10,0,1,254)
5353
#define ROUTER_IF1 IP4(10,0,2,1)
5454
#define DEST_IP IP4(10,0,2,200)
55+
#define TTL_EXCEEDED_DATA_LEN 28
5556

5657
#define PACKED __attribute__((packed))
5758

@@ -82,6 +83,14 @@ struct icmp_echo {
8283
uint16_t seq;
8384
} PACKED;
8485

86+
struct icmp_ttl_exceeded {
87+
uint8_t type;
88+
uint8_t code;
89+
uint16_t csum;
90+
uint8_t unused[4];
91+
uint8_t data[TTL_EXCEEDED_DATA_LEN];
92+
} PACKED;
93+
8594
static uint16_t ones_csum(const void *buf, size_t len)
8695
{
8796
const uint16_t *p = buf;
@@ -344,19 +353,63 @@ int main(void)
344353
mem_host_send(&link, frame, sizeof(struct eth_hdr) + sizeof(struct ipv4_hdr) + sizeof(struct icmp_echo));
345354

346355
n = mem_host_recv(&link, frame, sizeof(frame), 1000);
347-
if (n > 0) {
356+
if (n <= 0) {
357+
fprintf(stderr, "No TTL expired response\n");
358+
goto cleanup;
359+
}
360+
361+
{
348362
struct eth_hdr *eth = (struct eth_hdr *)frame;
349363
struct ipv4_hdr *ip = (struct ipv4_hdr *)(frame + sizeof(*eth));
350-
struct icmp_echo *icmp = (struct icmp_echo *)(frame + sizeof(*eth) + sizeof(*ip));
351-
if (ntohs(eth->type) == ETH_P_IP && ip->proto == 1 && icmp->type == 11 &&
352-
ntohl(ip->src) == DEST_IP && ntohl(ip->dst) == HOST_IP) {
353-
printf("TTL expired response received\n");
354-
rc = EXIT_SUCCESS;
364+
struct icmp_ttl_exceeded *icmp = (struct icmp_ttl_exceeded *)(frame + sizeof(*eth) + sizeof(*ip));
365+
struct ipv4_hdr *orig_ip = (struct ipv4_hdr *)icmp->data;
366+
struct icmp_echo *orig_icmp = (struct icmp_echo *)(icmp->data + sizeof(*orig_ip));
367+
size_t expected_len = sizeof(*eth) + sizeof(*ip) + sizeof(*icmp);
368+
uint16_t ip_len = ntohs(ip->len);
369+
uint16_t expected_ip_len = (uint16_t)(sizeof(*ip) + sizeof(*icmp));
370+
371+
if ((size_t)n != expected_len) {
372+
fprintf(stderr, "Unexpected frame length: got %d expected %zu\n", n, expected_len);
373+
goto mismatch;
355374
}
356-
} else {
357-
fprintf(stderr, "No TTL expired response\n");
375+
if (ntohs(eth->type) != ETH_P_IP ||
376+
memcmp(eth->dst, host_mac, sizeof(host_mac)) != 0 ||
377+
memcmp(eth->src, router0_mac, sizeof(router0_mac)) != 0) {
378+
fprintf(stderr, "Ethernet header mismatch\n");
379+
goto mismatch;
380+
}
381+
if (ip->ver_ihl != 0x45 || ip->proto != 1 || ip->ttl != 64 ||
382+
ip_len != expected_ip_len ||
383+
ntohl(ip->src) != ROUTER_IF0 || ntohl(ip->dst) != HOST_IP) {
384+
fprintf(stderr, "IPv4 header mismatch\n");
385+
goto mismatch;
386+
}
387+
if (icmp->type != 11 || icmp->code != 0 ||
388+
memcmp(icmp->unused, "\x00\x00\x00\x00", sizeof(icmp->unused)) != 0) {
389+
fprintf(stderr, "ICMP header mismatch\n");
390+
goto mismatch;
391+
}
392+
if (orig_ip->ver_ihl != 0x45 || orig_ip->proto != 1 ||
393+
ntohl(orig_ip->src) != HOST_IP || ntohl(orig_ip->dst) != DEST_IP ||
394+
ntohs(orig_ip->len) != sizeof(*orig_ip) + sizeof(struct icmp_echo) ||
395+
ntohs(orig_ip->id) != 0x1234 || orig_ip->ttl != 1) {
396+
fprintf(stderr, "Embedded IPv4 header mismatch\n");
397+
goto mismatch;
398+
}
399+
if (orig_icmp->type != 8 || orig_icmp->code != 0 ||
400+
ntohs(orig_icmp->id) != 0x0101 || ntohs(orig_icmp->seq) != 1) {
401+
fprintf(stderr, "Embedded ICMP header mismatch\n");
402+
goto mismatch;
403+
}
404+
printf("TTL expired response received\n");
405+
rc = EXIT_SUCCESS;
406+
goto cleanup;
358407
}
359408

409+
mismatch:
410+
fprintf(stderr, "TTL expired response mismatch\n");
411+
412+
cleanup:
360413
running = 0;
361414
pthread_join(th, NULL);
362415
return rc;

0 commit comments

Comments
 (0)