Hi my friends!
It's my first python experience. I wanted to write a simple generator of IGMP packets. And I wrote it. :)
Best regards,
It's my first python experience. I wanted to write a simple generator of IGMP packets. And I wrote it. :)
#! /usr/bin/env python # ****************************************************************************** # Program name: igmp_generator # Description: IGMP packet generator for IPv4 # Version: 0.1 (Hydrocyclone) # Author: Vasiliy V. Bodrov aka Bodro (mailto:mobile.ipbsoftware@gmail.com) # Date: 12.06.2015 # Programming language: Python # Commenting language: English # ****************************************************************************** # The MIT License (MIT) # # Copyright (c) 2015 IPB Software (Vasiliy V. Bodrov aka Bodro) # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the "Software"), # Software is furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT # OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR # THE USE OR OTHER DEALINGS IN THE SOFTWARE. # ****************************************************************************** # ****************************************************************************** # Import # ****************************************************************************** import getopt, sys from struct import * from socket import socket, inet_aton, AF_PACKET, SOCK_RAW # ****************************************************************************** # Global variable # ****************************************************************************** # Self variable version_num_str = '0.1' version_name = 'Hydrocyclone' # Common variable common_interface = "eth0" # Layer 2 l2_header = 0x00; l2_src_addr1 = 0x02 l2_src_addr2 = 0x02 l2_src_addr3 = 0x03 l2_src_addr4 = 0x04 l2_src_addr5 = 0x05 l2_src_addr6 = 0x06 l2_dst_addr1 = 0x01 l2_dst_addr2 = 0x02 l2_dst_addr3 = 0x03 l2_dst_addr4 = 0x04 l2_dst_addr5 = 0x05 l2_dst_addr6 = 0x06 l2_ether_type = 0x0800 # Layer 3 (IP) l3_ip_v4_header = 0x00 l3_ip_v4_source = '192.168.0.1' l3_ip_v4_dest = '192.168.1.1' l3_ip_v4_ihl = 5 l3_ip_v4_ver = 4 l3_ip_v4_tos = 0 l3_ip_v4_tot_len = 0 l3_ip_v4_id = 54321 l3_ip_v4_frag_off = 0 l3_ip_v4_ttl = 255 l3_ip_v4_proto = 2 l3_ip_v4_check = 0 l3_ip_v4_saddr = 0x00 l3_ip_v4_daddr = 0x00 l3_ip_v4_ihl_ver = 0x00 # Layer 3 (IGMP) l3_igmp_data = 0x00 l3_igmp_v3_t22 = 0x00 l3_igmp_v3_t22_prefix = 0x00 l3_igmp_v3_t22_group_record1 = 0x00 l3_igmp_v3_t22_group_record1_src_addr1 = 0x00 l3_igmp_v3_t22_group_record1_src_addr2 = 0x00 l3_igmp_v3_t22_group_record1_src_addr3 = 0x00 l3_igmp_v3_t22_group_record1_src_addr4 = 0x00 l3_igmp_v3_t22_group_record1_src_addr5 = 0x00 l3_igmp_v3_t22_type = 0x22 l3_igmp_v3_t22_reserved = 0x00 l3_igmp_v3_t22_check = 0x0000 l3_igmp_v3_t22_reserved = 0x0000 l3_igmp_v3_t22_num_of_grp_rec = 0x0001; l3_igmp_v3_t22_group_record1_rec_type = 0x00 l3_igmp_v3_t22_group_record1_aux_data_len = 0x00 l3_igmp_v3_t22_group_record1_num_of_src = 0x0001 l3_igmp_v3_t22_group_record1_milticast_addr1 = 0xE0 l3_igmp_v3_t22_group_record1_milticast_addr2 = 0x01 l3_igmp_v3_t22_group_record1_milticast_addr3 = 0x01 l3_igmp_v3_t22_group_record1_milticast_addr4 = 0x01 l3_igmp_v3_t22_group_record1_aux_data = 0x00 l3_igmp_v3_t22_group_record1_src_addr1_1 = 0xC0 l3_igmp_v3_t22_group_record1_src_addr1_2 = 0xA8 l3_igmp_v3_t22_group_record1_src_addr1_3 = 0x01 l3_igmp_v3_t22_group_record1_src_addr1_4 = 0x01 l3_igmp_v3_t22_group_record1_src_addr2_1 = 0xC0 l3_igmp_v3_t22_group_record1_src_addr2_2 = 0xA8 l3_igmp_v3_t22_group_record1_src_addr2_3 = 0x01 l3_igmp_v3_t22_group_record1_src_addr2_4 = 0x02 l3_igmp_v3_t22_group_record1_src_addr3_1 = 0xC0 l3_igmp_v3_t22_group_record1_src_addr3_2 = 0xA8 l3_igmp_v3_t22_group_record1_src_addr3_3 = 0x01 l3_igmp_v3_t22_group_record1_src_addr3_4 = 0x03 l3_igmp_v3_t22_group_record1_src_addr4_1 = 0xC0 l3_igmp_v3_t22_group_record1_src_addr4_2 = 0xA8 l3_igmp_v3_t22_group_record1_src_addr4_3 = 0x01 l3_igmp_v3_t22_group_record1_src_addr4_4 = 0x04 l3_igmp_v3_t22_group_record1_src_addr5_1 = 0xC0 l3_igmp_v3_t22_group_record1_src_addr5_2 = 0xA8 l3_igmp_v3_t22_group_record1_src_addr5_3 = 0x01 l3_igmp_v3_t22_group_record1_src_addr5_4 = 0x05 # ****************************************************************************** # Code # ****************************************************************************** # ------------------------------------------------------------------------------ # Function: version # Description: show version info # ------------------------------------------------------------------------------ def version(): print("Program: " + sys.argv[0]) print("version " + version_num_str + ' (' + version_name + ')') print("IGMP packet generator for IPv4") # ------------------------------------------------------------------------------ # Function: license # Description: show license # ------------------------------------------------------------------------------ def license(): version() print("") print("The MIT License (MIT)") print("") print("Copyright (c) 2015 IPB Software (Vasiliy V. Bodrov aka Bodro)") print("") print("Permission is hereby granted, free of charge, to any person obtaining a") print("copy of this software and associated documentation files (the \"Software\"),") print("Software is furnished to do so, subject to the following conditions:") print("") print("The above copyright notice and this permission notice shall be included") print("in all copies or substantial portions of the Software.") print("") print("THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS") print("OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF") print("MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.") print("IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY") print("CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT") print("OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR") print("THE USE OR OTHER DEALINGS IN THE SOFTWARE.") # ------------------------------------------------------------------------------ # Function: usage # Description: # ------------------------------------------------------------------------------ def usage(): print("Use --help or -h for help") print("Example: " + sys.argv[0] + " --help") # ------------------------------------------------------------------------------ # Function: help # Description: # ------------------------------------------------------------------------------ def help(): version(); print("Example: " + "\n\t# " + sys.argv[0] + " \\\n\t\t\ --interface=eth0 \\\n\t\t\ --ip-src=\"200.100.1.1\" \\\n\t\t\ --ip-dst=\"224.0.0.22\" \\\n\t\t\ --mac-src=\"23:A1:01:02:02:05\" \\\n\t\t\ --mac-dst=\"F0:FA:00:05:07:FF\" \\\n\t\t\ --gr1-rec-type=\"2\" \\\n\t\t\ --gr1-mult-addr=\"225.1.2.3\" \\\n\t\t\ --gr1-num-of-src=5 \\\n\t\t\ --gr1-src-addr1=\"127.0.0.1\" \\\n\t\t\ --gr1-src-addr2=\"127.0.0.2\" \\\n\t\t\ --gr1-src-addr3=\"127.0.0.3\" \\\n\t\t\ --gr1-src-addr4=\"127.0.0.4\" \\\n\t\t\ --gr1-src-addr5=\"127.0.0.5\" \\\n\t\t\ --ttl=1") # ------------------------------------------------------------------------------ # Function: data_send # Description: # ------------------------------------------------------------------------------ def data_send(): l3_ip_v4_saddr = inet_aton(l3_ip_v4_source) l3_ip_v4_daddr = inet_aton(l3_ip_v4_dest) l3_ip_v4_ihl_ver = (l3_ip_v4_ver << 4) + l3_ip_v4_ihl l2_header = pack('!BBBBBBBBBBBBH',\ l2_dst_addr1,\ l2_dst_addr2,\ l2_dst_addr3,\ l2_dst_addr4,\ l2_dst_addr5,\ l2_dst_addr6,\ l2_src_addr1,\ l2_src_addr2,\ l2_src_addr3,\ l2_src_addr4,\ l2_src_addr5,\ l2_src_addr6,\ l2_ether_type) l3_ip_v4_header = pack('!BBHHHBBH4s4s',\ l3_ip_v4_ihl_ver,\ l3_ip_v4_tos,\ l3_ip_v4_tot_len,\ l3_ip_v4_id,\ l3_ip_v4_frag_off,\ l3_ip_v4_ttl,\ l3_ip_v4_proto,\ l3_ip_v4_check,\ l3_ip_v4_saddr,\ l3_ip_v4_daddr) l3_igmp_v3_t22_prefix = pack('!BBHHH',\ l3_igmp_v3_t22_type,\ l3_igmp_v3_t22_reserved,\ l3_igmp_v3_t22_check,\ l3_igmp_v3_t22_reserved,\ l3_igmp_v3_t22_num_of_grp_rec) l3_igmp_v3_t22_group_record1_src_addr1 = pack('!BBBB',\ l3_igmp_v3_t22_group_record1_src_addr1_1,\ l3_igmp_v3_t22_group_record1_src_addr1_2,\ l3_igmp_v3_t22_group_record1_src_addr1_3,\ l3_igmp_v3_t22_group_record1_src_addr1_4) l3_igmp_v3_t22_group_record1_src_addr2 = pack('!BBBB',\ l3_igmp_v3_t22_group_record1_src_addr2_1,\ l3_igmp_v3_t22_group_record1_src_addr2_2,\ l3_igmp_v3_t22_group_record1_src_addr2_3,\ l3_igmp_v3_t22_group_record1_src_addr2_4) l3_igmp_v3_t22_group_record1_src_addr3 = pack('!BBBB',\ l3_igmp_v3_t22_group_record1_src_addr3_1,\ l3_igmp_v3_t22_group_record1_src_addr3_2,\ l3_igmp_v3_t22_group_record1_src_addr3_3,\ l3_igmp_v3_t22_group_record1_src_addr3_4) l3_igmp_v3_t22_group_record1_src_addr4 = pack('!BBBB',\ l3_igmp_v3_t22_group_record1_src_addr4_1,\ l3_igmp_v3_t22_group_record1_src_addr4_2,\ l3_igmp_v3_t22_group_record1_src_addr4_3,\ l3_igmp_v3_t22_group_record1_src_addr4_4) l3_igmp_v3_t22_group_record1_src_addr5 = pack('!BBBB',\ l3_igmp_v3_t22_group_record1_src_addr5_1,\ l3_igmp_v3_t22_group_record1_src_addr5_2,\ l3_igmp_v3_t22_group_record1_src_addr5_3,\ l3_igmp_v3_t22_group_record1_src_addr5_4) l3_igmp_v3_t22_group_record1 = pack('!BBHBBBB',\ l3_igmp_v3_t22_group_record1_rec_type,\ l3_igmp_v3_t22_group_record1_aux_data_len,\ l3_igmp_v3_t22_group_record1_num_of_src,\ l3_igmp_v3_t22_group_record1_milticast_addr1,\ l3_igmp_v3_t22_group_record1_milticast_addr2,\ l3_igmp_v3_t22_group_record1_milticast_addr3,\ l3_igmp_v3_t22_group_record1_milticast_addr4) if(l3_igmp_v3_t22_group_record1_num_of_src >= 1): l3_igmp_v3_t22_group_record1 = l3_igmp_v3_t22_group_record1 + l3_igmp_v3_t22_group_record1_src_addr1 if(l3_igmp_v3_t22_group_record1_num_of_src >= 2): l3_igmp_v3_t22_group_record1 = l3_igmp_v3_t22_group_record1 + l3_igmp_v3_t22_group_record1_src_addr2 if(l3_igmp_v3_t22_group_record1_num_of_src >= 3): l3_igmp_v3_t22_group_record1 = l3_igmp_v3_t22_group_record1 + l3_igmp_v3_t22_group_record1_src_addr3 if(l3_igmp_v3_t22_group_record1_num_of_src >= 4): l3_igmp_v3_t22_group_record1 = l3_igmp_v3_t22_group_record1 + l3_igmp_v3_t22_group_record1_src_addr4 if(l3_igmp_v3_t22_group_record1_num_of_src >= 5): l3_igmp_v3_t22_group_record1 = l3_igmp_v3_t22_group_record1 + l3_igmp_v3_t22_group_record1_src_addr5 if(l3_igmp_v3_t22_group_record1_num_of_src >= 6): print("Support only 5 source addresses") l3_igmp_v3_t22 = l3_igmp_v3_t22_prefix + l3_igmp_v3_t22_group_record1 l3_igmp_data = l3_igmp_v3_t22 s = socket(AF_PACKET, SOCK_RAW) s.bind((common_interface, 0)) s.send(l2_header + l3_ip_v4_header + l3_igmp_data) # ------------------------------------------------------------------------------ # Function: main # Description: # ------------------------------------------------------------------------------ def main(): global common_interface global l3_ip_v4_source global l3_ip_v4_dest global l3_ip_v4_ttl global l2_src_addr1 global l2_src_addr2 global l2_src_addr3 global l2_src_addr4 global l2_src_addr5 global l2_src_addr6 global l2_dst_addr1 global l2_dst_addr2 global l2_dst_addr3 global l2_dst_addr4 global l2_dst_addr5 global l2_dst_addr6 global l3_igmp_v3_t22_group_record1_rec_type global l3_igmp_v3_t22_group_record1_milticast_addr1 global l3_igmp_v3_t22_group_record1_milticast_addr2 global l3_igmp_v3_t22_group_record1_milticast_addr3 global l3_igmp_v3_t22_group_record1_milticast_addr4 global l3_igmp_v3_t22_group_record1_num_of_src global l3_igmp_v3_t22_group_record1_src_addr1_1 global l3_igmp_v3_t22_group_record1_src_addr1_2 global l3_igmp_v3_t22_group_record1_src_addr1_3 global l3_igmp_v3_t22_group_record1_src_addr1_4 global l3_igmp_v3_t22_group_record1_src_addr2_1 global l3_igmp_v3_t22_group_record1_src_addr2_2 global l3_igmp_v3_t22_group_record1_src_addr2_3 global l3_igmp_v3_t22_group_record1_src_addr2_4 global l3_igmp_v3_t22_group_record1_src_addr3_1 global l3_igmp_v3_t22_group_record1_src_addr3_2 global l3_igmp_v3_t22_group_record1_src_addr3_3 global l3_igmp_v3_t22_group_record1_src_addr3_4 global l3_igmp_v3_t22_group_record1_src_addr4_1 global l3_igmp_v3_t22_group_record1_src_addr4_2 global l3_igmp_v3_t22_group_record1_src_addr4_3 global l3_igmp_v3_t22_group_record1_src_addr4_4 global l3_igmp_v3_t22_group_record1_src_addr5_1 global l3_igmp_v3_t22_group_record1_src_addr5_2 global l3_igmp_v3_t22_group_record1_src_addr5_3 global l3_igmp_v3_t22_group_record1_src_addr5_4 try: opts, args = getopt.getopt(sys.argv[1:], "hvli:",\ ["help",\ "version",\ "license",\ "interface=",\ "ip-src=",\ "ip-dst=", "mac-src=",\ "mac-dst=",\ "ttl=",\ "gr1-rec-type=",\ "gr1-mult-addr=",\ "gr1-num-of-src=",\ "gr1-src-addr1=",\ "gr1-src-addr2=",\ "gr1-src-addr3=",\ "gr1-src-addr4=",\ "gr1-src-addr5="] ) except getopt.GetoptError as err: print(err) # will print something like "option -a not recognized" usage() sys.exit(2) for o, a in opts: if o == "-v": version() sys.exit() elif o in ("-h", "--help"): help() sys.exit() elif o in ("-v", "--version"): version() sys.exit() elif o in ("-l", "--license"): license() sys.exit() elif o in ("-i", "--interface"): common_interface = a elif o in ("--ip-src"): l3_ip_v4_source = a elif o in ("--ip-dst"): l3_ip_v4_dest = a elif o in ("--mac-src"): mac_src = a.split(':') l2_src_addr1 = int(mac_src[0], 16) l2_src_addr2 = int(mac_src[1], 16) l2_src_addr3 = int(mac_src[2], 16) l2_src_addr4 = int(mac_src[3], 16) l2_src_addr5 = int(mac_src[4], 16) l2_src_addr6 = int(mac_src[5], 16) elif o in ("--mac-dst"): mac_dst = a.split(":") l2_dst_addr1 = int(mac_dst[0], 16) l2_dst_addr2 = int(mac_dst[1], 16) l2_dst_addr3 = int(mac_dst[2], 16) l2_dst_addr4 = int(mac_dst[3], 16) l2_dst_addr5 = int(mac_dst[4], 16) l2_dst_addr6 = int(mac_dst[5], 16) elif o in ("--ttl"): l3_ip_v4_ttl = int(a, 10) elif o in ("--gr1-rec-type"): l3_igmp_v3_t22_group_record1_rec_type = int(a, 16) elif o in ("--gr1-mult-addr"): gr1_milticast_address = a.split(".") l3_igmp_v3_t22_group_record1_milticast_addr1 = int(gr1_milticast_address[0], 10) l3_igmp_v3_t22_group_record1_milticast_addr2 = int(gr1_milticast_address[1], 10) l3_igmp_v3_t22_group_record1_milticast_addr3 = int(gr1_milticast_address[2], 10) l3_igmp_v3_t22_group_record1_milticast_addr4 = int(gr1_milticast_address[3], 10) elif o in ("--gr1-num-of-src"): if(int(a, 10) > 5): print("Support only 5 source addresses") sys.exit() l3_igmp_v3_t22_group_record1_num_of_src = int(a, 10) elif o in ("--gr1-src-addr1"): gr1_source_address1 = a.split(".") l3_igmp_v3_t22_group_record1_src_addr1_1 = int(gr1_source_address1[0], 10) l3_igmp_v3_t22_group_record1_src_addr1_2 = int(gr1_source_address1[1], 10) l3_igmp_v3_t22_group_record1_src_addr1_3 = int(gr1_source_address1[2], 10) l3_igmp_v3_t22_group_record1_src_addr1_4 = int(gr1_source_address1[3], 10) elif o in ("--gr1-src-addr2"): gr1_source_address2 = a.split(".") l3_igmp_v3_t22_group_record1_src_addr2_1 = int(gr1_source_address2[0], 10) l3_igmp_v3_t22_group_record1_src_addr2_2 = int(gr1_source_address2[1], 10) l3_igmp_v3_t22_group_record1_src_addr2_3 = int(gr1_source_address2[2], 10) l3_igmp_v3_t22_group_record1_src_addr2_4 = int(gr1_source_address2[3], 10) elif o in ("--gr1-src-addr3"): gr1_source_address3 = a.split(".") l3_igmp_v3_t22_group_record1_src_addr3_1 = int(gr1_source_address3[0], 10) l3_igmp_v3_t22_group_record1_src_addr3_2 = int(gr1_source_address3[1], 10) l3_igmp_v3_t22_group_record1_src_addr3_3 = int(gr1_source_address3[2], 10) l3_igmp_v3_t22_group_record1_src_addr3_4 = int(gr1_source_address3[3], 10) elif o in ("--gr1-src-addr4"): gr1_source_address4 = a.split(".") l3_igmp_v3_t22_group_record1_src_addr4_1 = int(gr1_source_address4[0], 10) l3_igmp_v3_t22_group_record1_src_addr4_2 = int(gr1_source_address4[1], 10) l3_igmp_v3_t22_group_record1_src_addr4_3 = int(gr1_source_address4[2], 10) l3_igmp_v3_t22_group_record1_src_addr4_4 = int(gr1_source_address4[3], 10) elif o in ("--gr1-src-addr5"): gr1_source_address5 = a.split(".") l3_igmp_v3_t22_group_record1_src_addr5_1 = int(gr1_source_address5[0], 10) l3_igmp_v3_t22_group_record1_src_addr5_2 = int(gr1_source_address5[1], 10) l3_igmp_v3_t22_group_record1_src_addr5_3 = int(gr1_source_address5[2], 10) l3_igmp_v3_t22_group_record1_src_addr5_4 = int(gr1_source_address5[3], 10) else: assert False, "unhandled option" data_send() # ------------------------------------------------------------------------------ # Run # ------------------------------------------------------------------------------ main() # ****************************************************************************** # End of file # ******************************************************************************
$ ./igmp_generator.py --help Program: ./igmp_generator.py version 0.1 (Hydrocyclone) IGMP packet generator for IPv4 Example: # ./igmp_generator.py \ --interface=eth0 \ --ip-src="200.100.1.1" \ --ip-dst="224.0.0.22" \ --mac-src="23:A1:01:02:02:05" \ --mac-dst="F0:FA:00:05:07:FF" \ --gr1-rec-type="2" \ --gr1-mult-addr="225.1.2.3" \ --gr1-num-of-src=5 \ --gr1-src-addr1="127.0.0.1" \ --gr1-src-addr2="127.0.0.2" \ --gr1-src-addr3="127.0.0.3" \ --gr1-src-addr4="127.0.0.4" \ --gr1-src-addr5="127.0.0.5" \ --ttl=1 $ ./igmp_generator.py --license Program: ./igmp_generator.py version 0.1 (Hydrocyclone) IGMP packet generator for IPv4 The MIT License (MIT) Copyright (c) 2015 IPB Software (Vasiliy V. Bodrov aka Bodro) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. $
Best regards,
Vasiliy V. Bodrov aka Bodro,
the 10-th of May, 2017 year.
No comments:
Post a Comment