Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import socket
- import struct
- import sys
- import select
- class PingProtocolData(object):
- def __init__(self):
- self.seq_number = 0
- @property
- def ICMP_ECHO(self):
- return 8
- @property
- def seq_number(self):
- return self.__seq_number
- @property
- def identifier(self):
- return 0
- @seq_number.setter
- def seq_number(self, seq_number):
- self.__seq_number = seq_number
- def generate_ping_packet(self):
- checksum = 0
- header = struct.pack("!BBHHH", self.ICMP_ECHO, 0, checksum, self.identifier,
- self.seq_number)
- padBytes = "abcdefghijk"
- data = bytes(padBytes)
- #print data
- checksum = self.calculate_checksum(header+data)
- header = struct.pack("!BBHHH", self.ICMP_ECHO, 0, checksum, self.identifier,
- self.seq_number)
- packet = header + data
- print packet
- return packet
- def calculate_checksum(self, source_string):
- """
- A port of the functionality of in_cksum() from ping.c
- Ideally this would act on the string as a series of 16-bit ints (host
- packed), but this works.
- Network data is big-endian, hosts are typically little-endian
- """
- countTo = (int(len(source_string) / 2)) * 2
- sum = 0
- count = 0
- # Handle bytes in pairs (decoding as short ints)
- loByte = 0
- hiByte = 0
- while count < countTo:
- if (sys.byteorder == "little"):
- loByte = source_string[count]
- hiByte = source_string[count + 1]
- else:
- loByte = source_string[count + 1]
- hiByte = source_string[count]
- loByte = ord(loByte)
- hiByte = ord(hiByte)
- sum = sum + (hiByte * 256 + loByte)
- count += 2
- # Handle last byte if applicable (odd-number of bytes)
- # Endianness should be irrelevant in this case
- if countTo < len(source_string): # Check for odd length
- loByte = source_string[len(source_string) - 1]
- loByte = ord(loByte)
- sum += loByte
- sum &= 0xffffffff # Truncate sum to 32 bits (a variance from ping.c, which
- # uses signed ints, but overflow is unlikely in ping)
- sum = (sum >> 16) + (sum & 0xffff) # Add high 16 bits to low 16 bits
- sum += (sum >> 16) # Add carry from above (if any)
- answer = ~sum & 0xffff # Invert and truncate to 16 bits
- answer = socket.htons(answer)
- return answer
- class Pinger(object):
- def __init__(self, ppd):
- self.ppd = ppd
- def _send_ping(self, s, target):
- ping_packet = self.ppd.generate_ping_packet()
- s.sendto(ping_packet, (target, 1))
- def _receive_ping(self, s):
- timeout = 2.5
- select.select([s], [], [], timeout)
- packet_data, address = s.recvfrom(2048)
- print packet_data, address
- def do(self):
- s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.getprotobyname("icmp"))
- s.setsockopt(socket.IPPROTO_IP, socket.IP_TTL, 1)
- self._send_ping(s, "8.8.8.8")
- self._receive_ping(s)
- s.close()
- def main():
- pinger = Pinger(PingProtocolData())
- pinger.do()
- if __name__ == "__main__":
- main()
Add Comment
Please, Sign In to add comment