/usr/share/python-support/python-pyip/ip.py is in python-pyip 0.7-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 | #
# pyip is a Python package offering assembling/disassembling of raw ip packet
# including ip, udp, and icmp. Also it includes 2 utilities based on raw ip,
# traceroute and ping.
#
# pyip is released under PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2, and is
# a project inspired by 'ping' written by Jeremy Hylton.
#
# Author: Kenneth Jiang, kenneth.jiang@gmail.com
#
import inetutils
import socket
import struct
import string
import os
IPVERSION = 4
IP_DF = 0x4000
IP_MF = 0x2000
IP_MAXPACKET = 65535
IPTOS_LOWDELAY = 0x10
IPTOS_THROUGHPUT = 0x08
IPTOS_RELIABILITY = 0x04
IPTOS_PREC_NETCONTROL = 0xe0
IPTOS_PREC_INTERNETCONTROL = 0xc0
IPTOS_PREC_CRITIC_ECP = 0xa0
IPTOS_PREC_FLASHOVERRIDE = 0x80
IPTOS_PREC_FLASH = 0x60
IPTOS_PREC_IMMEDIATE = 0x40
IPTOS_PREC_PRIORITY = 0x20
IPTOS_PREC_ROUTINE = 0x00
IPOPT_CONTROL = 0x00
IPOPT_RESERVED1 = 0x20
IPOPT_DEBMEAS = 0x40
IPOPT_RESERVED2 = 0x60
IPOPT_EOL = 0
IPOPT_NOP = 1
IPOPT_RR = 7
IPOPT_TS = 68
IPOPT_SECURITY = 130
IPOPT_LSRR = 131
IPOPT_SATID = 136
IPOPT_SSRR = 137
IPOPT_OPTVAL = 0
IPOPT_OLEN = 1
IPOPT_OFFSET = 2
IPOPT_MINOFF = 4
IPOPT_TS_TSONLY = 0
IPOPT_TS_TSANDADDR = 1
IPOPT_TS_PRESPEC = 2
IPOPT_SECUR_UNCLASS = 0x0000
IPOPT_SECUR_CONFID = 0xf135
IPOPT_SECUR_EFTO = 0x789a
IPOPT_SECUR_MMMM = 0xbc4d
IPOPT_SECUR_RESTR = 0xaf13
IPOPT_SECUR_SECRET = 0xd788
IPOPT_SECUR_TOPSECRET = 0x6bc5
MAXTTL = 255
IPFRAGTTL = 60
IPTTLDEC = 1
IP_MSS = 576
MIN_HDR_SIZE_IN_BYTES = 20
class Packet:
"""An IP packet.
Doesn't handle IP options yet (but you have the option of adding
support).
"""
def __init__(self,
v = IPVERSION,
hl = 5,
tos = IPTOS_PREC_ROUTINE,
len = 20,
id = 0,
df = 0,
off = 0,
ttl = 0,
p = 0,
sum = 0,
src = None,
dst = None,
data = ''):
self.v = v
self.hl = hl # this implement punts on options
self.tos = tos
self.len = len # begin with header length
self.id = id
self.df = df
self.off = off
self.ttl = ttl
self.p = p
self.sum = sum
self.src = src
self.dst = dst
self.data = data
self.raw_packet = ''
def __repr__(self):
begin = "<IPv%d id=%d proto=%d src=%s dst=%s datalen=%d " % \
(self.v, self.id, self.p, self.src, self.dst,
self.len - self.hl * 4)
if len(self.data) == 0:
rep = begin + "\'\'>"
elif len(self.data) < 10:
rep = begin + "%s>" % repr(self.data)
else:
rep = begin + "%s>" % repr(self.data[:10] + '...')
return rep
def __eq__(self, other):
if not isinstance(other, Packet):
return 0
return self.v == other.v and \
self.hl == other.hl and \
self.tos == other.tos and \
self.len == other.len and \
self.id == other.id and \
self.df == other.df and \
self.off == other.off and \
self.ttl == other.ttl and \
self.p == other.p and \
self.sum == other.sum and \
self.src == other.src and \
self.dst == other.dst and \
self.data == other.data
def _assemble(self, cksum):
"Get a packet suitable for sending over an IP socket."
# make sure all the data is ready
assert self.src, "src needed before assembling."
assert self.dst, "dst needed before assembling."
self.len = self.hl * 4 + len(self.data)
self.__parse_addrs()
# create the packet
header = struct.pack('ccHHHcc',
chr((self.v & 0x0f) << 4
| (self.hl & 0x0f)), # 4bits each
chr(self.tos & 0xff),
self.len,
self.id,
(self.df & 0x01) << 14
| self.off, # what about flags?
chr(self.ttl & 0xff),
chr(self.p & 0xff))
if cksum:
self.sum = inetutils.cksum(header + '\000\000' + self.__src +
self.__dst)
packet = header + struct.pack('H', self.sum) \
+ self.__src + self.__dst
else:
packet = header + '\000\000' + self.__src + self.__dst
packet = packet + self.data
self.__packet = inetutils.iph2net(packet)
return self.__packet
def __parse_addrs(self):
try:
self.__src = socket.inet_aton(self.src)
except ValueError:
try:
self.__src = socket.inet_aton(socket.gethostbyname(self.src))
except ValueError:
raise ValueError, "invalid source address"
try:
self.__dst = socket.inet_aton(self.dst)
except ValueError:
try:
self.__dst = socket.inet_aton(socket.gethostbyname(self.dst))
except ValueError:
raise ValueError, "invalid source address"
def __unparse_addrs(self):
src = struct.unpack('cccc', self.src)
self.src = string.joinfields(map(lambda x:str(ord(x)), src), '.')
dst = struct.unpack('cccc', self.dst)
self.dst = string.joinfields(map(lambda x:str(ord(x)), dst), '.')
def _disassemble(self, raw_packet, cksum):
# The kernel computes the checksum, even on a raw packet.
packet = inetutils.net2iph(raw_packet)
b1 = ord(packet[0])
self.v = (b1 >> 4) & 0x0f
self.hl = b1 & 0x0f
if self.v != IPVERSION:
raise ValueError, "cannot handle IPv%d packets" % self.v
hl = self.hl * 4
# verify the checksum
self.sum = struct.unpack('H', packet[10:12])[0] & 0xffff
if cksum:
our_cksum = inetutils.cksum(packet[:20])
if our_cksum != 0:
raise ValueError, packet
# unpack the fields
elts = struct.unpack('ccHHHcc', packet[:hl-10])
# struct didn't do !<> when this was written
self.tos = ord(elts[1])
self.len = elts[2] & 0xffff
self.id = elts[3] & 0xffff
self.off = elts[4] & 0xffff
self.ttl = ord(elts[5])
self.p = ord(elts[6])
self.data = packet[hl:]
self.src = packet[hl-8:hl-4]
self.dst = packet[hl-4:hl]
self.__unparse_addrs()
def assemble(packet, cksum = 0):
return packet._assemble(cksum)
def disassemble(buffer, cksum = 0):
packet = Packet()
packet._disassemble(buffer, cksum)
return packet
|