icmp.py 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. import struct
  2. import socket
  3. import select
  4. import random
  5. ICMP_CODE = socket.getprotobyname('icmp')
  6. def checksum(source_string):
  7. sum = 0
  8. count_to = (len(source_string) / 2) * 2
  9. count = 0
  10. while count < count_to:
  11. this_val = source_string[count + 1]*256+source_string[count]
  12. sum = sum + this_val
  13. sum = sum & 0xffffffff
  14. count = count + 2
  15. if count_to < len(source_string):
  16. sum = sum + source_string[len(source_string) - 1]
  17. sum = sum & 0xffffffff
  18. sum = (sum >> 16) + (sum & 0xffff)
  19. sum = sum + (sum >> 16)
  20. answer = ~sum
  21. answer = answer & 0xffff
  22. answer = answer >> 8 | (answer << 8 & 0xff00)
  23. return answer
  24. def create_packet(id, data):
  25. ICMP_ECHO_REQUEST = 8 #Код типа ICMP - в нашем случае ECHO
  26. header = struct.pack('bbHHh', ICMP_ECHO_REQUEST, 0, 0, id, 1)
  27. data = data
  28. my_checksum = checksum(header + data)
  29. header = struct.pack('bbHHh', ICMP_ECHO_REQUEST, 0, socket.htons(my_checksum), id, 1)
  30. return header + data
  31. def send(dest_addr,data):
  32. my_socket = socket.socket(socket.AF_INET, socket.SOCK_RAW, ICMP_CODE)
  33. host = socket.gethostbyname(dest_addr)
  34. packet_id = random.randint(0,65535)
  35. packet = create_packet(packet_id,data)
  36. while packet:
  37. sent = my_socket.sendto(packet, (dest_addr, 1))
  38. packet = packet[sent:]
  39. return my_socket,packet_id
  40. def recv(my_socket, packet_id):
  41. ready = select.select([my_socket], [], [], 2) #таймаут 2с
  42. rec_packet, addr = my_socket.recvfrom(1024)
  43. icmp_header = rec_packet[20:28] # Байты с 20 по 28 - заголовок ICMP
  44. type, code, checksum, p_id, sequence = struct.unpack(
  45. 'bbHHh', icmp_header)
  46. data = rec_packet[28:] # Наш hello будет лежать после заголовка ICMP
  47. return data
  48. def main():
  49. sock, id=send("8.8.8.8",b"hohoho")
  50. print(recv(sock,id))
  51. if __name__ == '__main__':
  52. main()