blob: 64aa27f8ad4786b6bc47d1b68592c4d572bdd4ba [file] [log] [blame]
Chetan Gaonker25470972016-02-26 08:52:15 -08001from socket import *
2from struct import *
3from scapy.all import *
4from itertools import *
5
6IGMPV3_REPORT = 0x22
7IGMP_LEAVE = 0x17
8IGMP_EXCLUDE = 0x04
9IGMP_INCLUDE = 0x03
10IGMPV3_ALL_ROUTERS = '224.0.0.22'
11IGMPv3 = 3
12IP_SRC = '1.2.3.4'
13ETHERTYPE_IP = 0x0800
14IGMP_DST_MAC = "01:00:5e:00:01:01"
15IGMP_SRC_MAC = "5a:e1:ac:ec:4d:a1"
16
17class IGMP:
18
19 def __init__(self, mtype = None, group = '', rtype = None, src_list = []):
20 self.version = IGMPv3
21 self.mtype = mtype
22 self.group = group
23 self.src_list= src_list
24 self.rtype = rtype
25
26 def checksum(self, msg):
27 s = 0
28 for i in range(0, len(msg), 2):
29 w = ord(msg[i]) + (ord(msg[i+1]) << 8)
30 c = s + w
31 s = (c & 0xffff) + (c >> 16)
32 return ~s & 0xffff
33
34 def update_igmp_checksum(self, pkt):
35 cs = self.checksum(pkt)
36 #print 'igmp checksum: ' + str(hex(cs))
37 m = []
38 for x in pkt:
39 m.append(ord(x))
40 higher = (cs >> 8) & 0xff
41 lower = cs & 0xff
42 m[2] = lower
43 m[3] = higher
44 m = pack("%dB" % len(m), *m)
45 return m
46
47 def update_ip_checksum(self, pkt):
48 cs = self.checksum(pkt)
49 #print 'ip hdr checksum: ' + str(hex(cs))
50 m = []
51 for x in pkt:
52 m.append(ord(x))
53 higher = (cs >> 8) & 0xff
54 lower = cs & 0xff
55 m[10] = lower
56 m[11] = higher
57 m = pack("%dB" % len(m), *m)
58 return m
59
60 def build_ip_hdr(self, s, d):
61 ip_ihl_len = 0x46 #8 bits
62 ip_dscp = 0xc0 #8 bits
63 ip_hdr_total_len = 0x0028 #16 bits
64 ip_id = 0x0000 #16 bits
65 ip_flags = 0x4000 #16 bits
66 ip_ttl = 1 #8 bits
67 ip_protocol = 0x02 #8 bits
68 ip_cs = 0x0000 #16 bits (should filled by kernel but seems not???)
69 #ip_src #32 bits
70 #ip_dst #32 bits
71 ip_options = 0x94040000 #32 bits
72 #total len 24 bytes
73 ip_header = pack('!BBHHHBBH4s4sI', ip_ihl_len, ip_dscp, ip_hdr_total_len,
74 ip_id, ip_flags, ip_ttl, ip_protocol, ip_cs, inet_aton(s),
75 inet_aton(d), ip_options)
76 return ip_header
77
78 def dump_packet(self, data):
79 i = 0
80 for x in data:
81 if i == 4:
82 print ''
83 i = 0
84 i += 1
85 sys.stdout.write(' %0.2x' % ord(x))
86 print ''
87
88 def build_igmp(self, msg_type = None, group = None, record_type = None, src_list = None):
89 msg_type = self.mtype if msg_type == None else msg_type
90 group = self.group if group == None else group
91 record_type = self.rtype if record_type == None else record_type
92 src_list = self.src_list if src_list == None else src_list
93 if msg_type == IGMP_LEAVE:
94 pkt = pack('!BBH4s', msg_type, 0, 0, inet_aton(group))
95 elif msg_type == IGMPV3_REPORT:
96 pkt = pack('!BBHHHBBH', msg_type, 0x00, 0x0000, 0x0000, 0x0001, record_type,
97 0x00, len(src_list))
98 pkt += pack('!4s', inet_aton(group))
99 for a in src_list:
100 pkt += pack('!4s', inet_aton(a))
101 else:
102 print 'unsupported report type: ' + str(msg_type)
103 return None
104 return pkt
105
106 def build_join_msg(self, group = None, record_type = None, src_list = None):
107 return self.build_igmp(msg_type = IGMPV3_REPORT,
108 group = group,
109 record_type = record_type,
110 src_list = src_list)
111
112 def build_leave_msg(self, group = None):
113 return self.build_igmp(msg_type = IGMPV3_REPORT,
114 group = group,
Chetan Gaonkereb2b24b2016-03-01 14:04:45 -0800115 record_type = IGMP_EXCLUDE,
Chetan Gaonker25470972016-02-26 08:52:15 -0800116 src_list = [])
117
118 def build_ip_igmp(self,
119 src = IP_SRC,
120 msg_type = None,
121 group = None,
122 record_type = None,
123 src_list = None):
124
125 igmp = self.build_igmp(msg_type = msg_type,
126 group = group,
127 record_type = record_type,
128 src_list = src_list)
129 igmp = self.update_igmp_checksum(igmp)
130 ip_hdr = self.build_ip_hdr(src, IGMPV3_ALL_ROUTERS)
131 p = ip_hdr + igmp
132 p = self.update_ip_checksum(p)
133 return p
134
135 def scapify(self,
136 src = IP_SRC,
137 msg_type = None,
138 group = None,
139 record_type = None,
140 src_list = None):
141
142 ip_igmp = self.build_ip_igmp(src = src,
143 msg_type = msg_type,
144 group = group,
145 record_type = record_type,
146 src_list = src_list)
147 eth = Ether(dst = IGMP_DST_MAC, src = IGMP_SRC_MAC, type = ETHERTYPE_IP)
148 return eth/ip_igmp