Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Host-unreachable replies #20

Open
blueoak opened this issue Dec 20, 2018 · 1 comment
Open

Host-unreachable replies #20

blueoak opened this issue Dec 20, 2018 · 1 comment

Comments

@blueoak
Copy link

blueoak commented Dec 20, 2018

Looks like replies to ICMP Echo-request messages (ping) which are not Echo-reply are not being handled properly in the receive method and can be interpreted as a positive reply. Specifically, pings to some addresses can return an ICMP host-unreachable message, which, for my specific purpose, should be interpreted as a non-reply. As a quick fix, I added an
else: pass
clause after the
if pkt[_ICMPV6_HDR_OFFSET] == _ICMPV6_ECHO_REPLY:
...
elif pkt[_ICMP_HDR_OFFSET] == _ICMP_ECHO_REPLY:
...
clauses, but I would also suggest a better check for IP4 vs. IP6 packets instead of looking at a byte at a particular location.

@sheffieldnikki
Copy link

Agreed! treating "host unreachable" reply packets as a non-reply is essential. Based on the above, this is my version which also does a better check to distinguish IPv4 from IPv6 packets:

# Some offsets we use when extracting data from the header
_ICMP_VER_OFFSET       = 0

                try:
                    pkt_id = None
                    pkt_ident = None
                    pkt_ver = pkt[_ICMP_VER_OFFSET] >> 4
                    if pkt_ver == 6 and \
                       pkt[_ICMPV6_HDR_OFFSET] == _ICMPV6_ECHO_REPLY:

                        pkt_id = (pkt[_ICMPV6_ID_OFFSET] << 8) + \
                            pkt[_ICMPV6_ID_OFFSET + 1]
                        pkt_ident = (pkt[_ICMPV6_IDENT_OFFSET] << 8) + \
                            pkt[_ICMPV6_IDENT_OFFSET + 1]
                        payload = pkt[_ICMPV6_PAYLOAD_OFFSET:]

                    elif pkt_ver == 4 and \
                       pkt[_ICMP_HDR_OFFSET] == _ICMP_ECHO_REPLY:

                        pkt_id = (pkt[_ICMP_ID_OFFSET] << 8) + \
                            pkt[_ICMP_ID_OFFSET + 1]
                        pkt_ident = (pkt[_ICMP_IDENT_OFFSET] << 8) + \
                            pkt[_ICMP_IDENT_OFFSET + 1]
                        payload = pkt[_ICMP_PAYLOAD_OFFSET:]
                    
                    else:
                        # Silently ignore other ICMP packet types (not _ECHO_REPLY)
                        pass

Possibly could be improved further by extracting the pkt_id/pkt_ident for other ICMP packet types, and removing those from self._remaining_ids without setting the results dict? That would allow the function to return sooner in the event of non-ECHO_REPLY packets, instead of waiting for timeout.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants