/* Match an ICMP packet with payload len ICMP_PAYLOAD_SIZE */ staticint __expect_icmp_ipv4(char *buf, ssize_t len)
{ struct iphdr *ip = (struct iphdr *)buf; struct icmphdr *icmp = (struct icmphdr *)(ip + 1);
ssize_t min_header_len = sizeof(*ip) + sizeof(*icmp);
if (len < min_header_len) return -1;
if (ip->protocol != IPPROTO_ICMP) return -1;
if (icmp->type != ICMP_ECHO) return -1;
return len == ICMP_PAYLOAD_SIZE + min_header_len;
}
typedefint (*filter_t) (char *, ssize_t);
/* wait_for_packet - wait for a packet that matches the filter * * @fd: tun fd/packet socket to read packet * @filter: filter function, returning 1 if matches * @timeout: timeout to wait for the packet * * Returns 1 if a matching packet is read, 0 if timeout expired, -1 on error.
*/ staticint wait_for_packet(int fd, filter_t filter, struct timeval *timeout)
{ char buf[4096]; int max_retry = 5; /* in case we read some spurious packets */
fd_set fds;
FD_ZERO(&fds); while (max_retry--) { /* Linux modifies timeout arg... So make a copy */ struct timeval copied_timeout = *timeout;
ssize_t ret = -1;
FD_SET(fd, &fds);
ret = select(1 + fd, &fds, NULL, NULL, &copied_timeout); if (ret <= 0) { if (errno == EINTR) continue; elseif (errno == EAGAIN || ret == 0) return 0;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.