icmp.py 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. """Internet Control Message Protocol for IPv4."""
  2. from pypacker import pypacker, checksum
  3. import logging
  4. logger = logging.getLogger("pypacker")
  5. # Types (icmp_type) and codes (icmp_code) -
  6. # http://www.iana.org/assignments/icmp-parameters
  7. ICMP_CODE_NONE = 0 # for types without codes
  8. ICMP_ECHOREPLY = 0 # echo reply
  9. ICMP_UNREACH = 3 # dest unreachable, codes:
  10. ICMP_UNREACH_NET = 0 # bad net
  11. ICMP_UNREACH_HOST = 1 # bad host
  12. ICMP_UNREACH_PROTO = 2 # bad protocol
  13. ICMP_UNREACH_PORT = 3 # bad port
  14. ICMP_UNREACH_NEEDFRAG = 4 # IP_DF caused drop
  15. ICMP_UNREACH_SRCFAIL = 5 # src route failed
  16. ICMP_UNREACH_NET_UNKNOWN = 6 # unknown net
  17. ICMP_UNREACH_HOST_UNKNOWN = 7 # unknown host
  18. ICMP_UNREACH_ISOLATED = 8 # src host isolated
  19. ICMP_UNREACH_NET_PROHIB = 9 # for crypto devs
  20. ICMP_UNREACH_HOST_PROHIB = 10 # ditto
  21. ICMP_UNREACH_TOSNET = 11 # bad tos for net
  22. ICMP_UNREACH_TOSHOST = 12 # bad tos for host
  23. ICMP_UNREACH_FILTER_PROHIB = 13 # prohibited access
  24. ICMP_UNREACH_HOST_PRECEDENCE = 14 # precedence error
  25. ICMP_UNREACH_PRECEDENCE_CUTOFF = 15 # precedence cutoff
  26. ICMP_SRCQUENCH = 4 # packet lost, slow down
  27. ICMP_REDIRECT = 5 # shorter route, codes:
  28. ICMP_REDIRECT_NET = 0 # for network
  29. ICMP_REDIRECT_HOST = 1 # for host
  30. ICMP_REDIRECT_TOSNET = 2 # for tos and net
  31. ICMP_REDIRECT_TOSHOST = 3 # for tos and host
  32. ICMP_ALTHOSTADDR = 6 # alternate host address
  33. ICMP_ECHO = 8 # echo service
  34. ICMP_RTRADVERT = 9 # router advertise, codes:
  35. ICMP_RTRADVERT_NORMAL = 0 # normal
  36. ICMP_RTRADVERT_NOROUTE_COMMON = 16 # selective routing
  37. ICMP_RTRSOLICIT = 10 # router solicitation
  38. ICMP_TIMEXCEED = 11 # time exceeded, code:
  39. ICMP_TIMEXCEED_INTRANS = 0 # ttl==0 in transit
  40. ICMP_TIMEXCEED_REASS = 1 # ttl==0 in reass
  41. ICMP_PARAMPROB = 12 # ip header bad
  42. ICMP_PARAMPROB_ERRATPTR = 0 # req. opt. absent
  43. ICMP_PARAMPROB_OPTABSENT = 1 # req. opt. absent
  44. ICMP_PARAMPROB_LENGTH = 2 # bad length
  45. ICMP_TSTAMP = 13 # timestamp request
  46. ICMP_TSTAMPREPLY = 14 # timestamp reply
  47. ICMP_INFO = 15 # information request
  48. ICMP_INFOREPLY = 16 # information reply
  49. ICMP_MASK = 17 # address mask request
  50. ICMP_MASKREPLY = 18 # address mask reply
  51. ICMP_TRACEROUTE = 30 # traceroute
  52. ICMP_DATACONVERR = 31 # data conversion error
  53. ICMP_MOBILE_REDIRECT = 32 # mobile host redirect
  54. ICMP_IP6_WHEREAREYOU = 33 # IPv6 where-are-you
  55. ICMP_IP6_IAMHERE = 34 # IPv6 i-am-here
  56. ICMP_MOBILE_REG = 35 # mobile registration req
  57. ICMP_MOBILE_REGREPLY = 36 # mobile registration reply
  58. ICMP_DNS = 37 # domain name request
  59. ICMP_DNSREPLY = 38 # domain name reply
  60. ICMP_SKIP = 39 # SKIP
  61. ICMP_PHOTURIS = 40 # Photuris
  62. ICMP_PHOTURIS_UNKNOWN_INDEX = 0 # unknown sec index
  63. ICMP_PHOTURIS_AUTH_FAILED = 1 # auth failed
  64. ICMP_PHOTURIS_DECOMPRESS_FAILED = 2 # decompress failed
  65. ICMP_PHOTURIS_DECRYPT_FAILED = 3 # decrypt failed
  66. ICMP_PHOTURIS_NEED_AUTHN = 4 # no authentication
  67. ICMP_PHOTURIS_NEED_AUTHZ = 5 # no authorization
  68. ICMP_TYPE_MAX = 40
  69. class ICMP(pypacker.Packet):
  70. __hdr__ = (
  71. ("type", "B", ICMP_ECHO),
  72. ("code", "B", 0),
  73. ("sum", "H", 0)
  74. )
  75. def bin(self, update_auto_fields=True):
  76. # logger.debug("sum is: %d" % self.sum)
  77. if update_auto_fields and self._changed():
  78. # logger.debug("sum is: %d" % self.sum)
  79. self.sum = 0
  80. self.sum = checksum.in_cksum(self._pack_header() + self.body_bytes)
  81. # logger.debug("sum is: %d" % self.sum)
  82. return pypacker.Packet.bin(self, update_auto_fields=update_auto_fields)
  83. def _dissect(self, buf):
  84. # logger.debug("ICMP: adding fields for type: %d" % buf[0])
  85. self._init_handler(buf[0], buf[4:])
  86. return 4
  87. class Echo(pypacker.Packet):
  88. __hdr__ = (
  89. ("id", "H", 0),
  90. ("seq", "H", 1),
  91. ("ts", "d", 0)
  92. )
  93. class Unreach(pypacker.Packet):
  94. __hdr__ = (
  95. ("pad", "H", 0),
  96. ("mtu", "H", 0)
  97. )
  98. class Redirect(pypacker.Packet):
  99. __hdr__ = (
  100. ("gw", "I", 0),
  101. ("seq", "H", 0)
  102. )
  103. # load handler
  104. ICMP_TYPE_ECHO = (0, 8)
  105. ICMP_TYPE_UNREACH = 3
  106. ICMP_TYPE_REDIRECT = 5
  107. pypacker.Packet.load_handler(ICMP,
  108. {
  109. ICMP_TYPE_ECHO: ICMP.Echo,
  110. ICMP_TYPE_UNREACH: ICMP.Unreach,
  111. ICMP_TYPE_REDIRECT: ICMP.Redirect
  112. }
  113. )