def interface_exists(option, config, value): """Network interface must exists""" try: socket.if_nametoindex(value) except OSError: raise OptionCheckError("Interface {} not found".format(value), option=option.__name__)
def main(): global sock, echolite_obj try: socket.if_nametoindex('ppp0') # check whether the machine is connected to VPN, exception thrown if it's ip_addr = (subprocess.check_output(['ifconfig', 'ppp0'])).decode("utf-8").split("inet ")[1].split(" -->")[0] sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.bind((ip_addr, 3610)) print(f"main() IP: {ip_addr}, Port: 3610") except OSError as e: logging.critical("main() VPN interface not found.") sys.exit(0) echolite_obj.append(echonet_lite.EchonetLite()) thread_list = [] thread_list.append(threading.Thread(target=udp_receiver, args=[])) thread_list.append(threading.Thread(target=echonet_parser, args=[])) thread_list.append(threading.Thread(target=echonet_poller, args=[])) for thread in thread_list: thread.daemon = True thread.start() signal.signal(signal.SIGINT, signal.default_int_handler) # catch SIGINT try: while True: try: socket.if_nametoindex('ppp0') # check status of VPN every 10 sec time.sleep(10) except OSError as e: logging.critical("main() VPN disconnected.") except KeyboardInterrupt: logging.info("main() Ctrl-C received.") finally: logging.info("main() exiting.") sys.exit(0)
def open_socket(self, interface, source): self.sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM, socket.IPPROTO_UDP) ifidx = socket.if_nametoindex(interface) self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.sock.bind((IP6_GROUP, DST_PORT, 0, ifidx)) src_sa = (struct.pack("@H", socket.AF_INET6) + struct.pack("!HI", SRC_PORT, 0) + socket.inet_pton(socket.AF_INET6, source) + struct.pack("@I", ifidx) + b"\x00" * 100) dst_sa = (struct.pack("@H", socket.AF_INET6) + struct.pack("!HI", DST_PORT, 0) + socket.inet_pton(socket.AF_INET6, IP6_GROUP) + struct.pack("@I", ifidx) + b"\x00" * 100) padding = b"\x00" * (len(struct.pack("@P", 0)) - len(struct.pack("@I", 0))) gsreq = struct.pack( "@I", socket.if_nametoindex(interface)) + padding + dst_sa + src_sa self.sock.setsockopt(socket.IPPROTO_IPV6, socket.MCAST_JOIN_SOURCE_GROUP, gsreq) self.addr = (socket.inet_ntop( socket.AF_INET6, socket.inet_pton(socket.AF_INET6, source)), SRC_PORT, 0, ifidx)
def verif_interface_reseau(interface): val_ret = False try: socket.if_nametoindex(interface) val_ret = True except OSError: val_ret = False return val_ret
def validate_config_section(self): """ Validate the interface information """ try: socket.if_nametoindex(self.name) except OSError: raise ValueError("Interface {} not found".format(self.name)) interface_addresses = [ IPv6Address(addr_info['addr'].split('%')[0]) for addr_info in netifaces.ifaddresses(self.name).get( netifaces.AF_INET6, []) ] # Pick the first link-local address as reply-from if none is specified in the configuration if not self.section.reply_from: for address in interface_addresses: if address.is_link_local: self.section.reply_from = address break if not self.section.reply_from: raise ValueError( "No link-local address found on interface {}".format( self.name)) else: # Validate what the user supplied if not self.section.reply_from.is_link_local: raise ValueError( "The reply-from address must be a link-local address") if self.section.reply_from not in interface_addresses: raise ValueError( "Cannot find reply-from address {} on interface {}".format( self.section.reply_from, self.name)) # Pick the first global unicast address as link-address if none is specified in the configuration if not self.section.link_address: for address in interface_addresses: if is_global_unicast(address): self.section.link_address = address break if not self.section.link_address: # Use the unspecified address is we couldn't find anything self.section.link_address = IPv6Address('::') else: # Validate what the user supplied (we don't really care if it exists, it's just extra information for the # option handlers if not is_global_unicast(self.section.link_address): raise ValueError( "The link-address must be a global unicast address")
def _get_interfaceindex(self, service=None): """ interfaceIndex specifies the interface on which to register the sdRef. kDNSServiceInterfaceIndexAny (0) will register on all available interfaces. This function will return kDNSServiceInterfaceIndexAny if the service is not configured to bind on a particular interface. Otherwise it will return a list of interfaces on which to register mDNS. """ iindex = [] bind_ip = [] if service is None: service = self.service if service in ['AFP', 'NFS', 'SMB']: bind_ip = self.middleware.call_sync( f'{service.lower()}.config')['bindip'] if service in ['HTTP', 'HTTPS']: ui_address = self.middleware.call_sync( 'system.general.config')['ui_address'] if ui_address[0] != "0.0.0.0": bind_ip = ui_address if service in ['SSH', 'SFTP_SSH']: for iface in self.middleware.call_sync('ssh.config')['bindiface']: try: iindex.append(socket.if_nametoindex(iface)) except OSError: self.logger.debug( 'Failed to determine interface index for [%s], service [%s]', iface, service, exc_info=True) return iindex if iindex else [kDNSServiceInterfaceIndexAny] if bind_ip is None: return [kDNSServiceInterfaceIndexAny] for ip in bind_ip: for intobj in self.middleware.call_sync('interface.query'): if any(filter(lambda x: ip in x['address'], intobj['aliases'])): try: iindex.append(socket.if_nametoindex(intobj['name'])) except OSError: self.logger.debug( 'Failed to determine interface index for [%s], service [%s]', iface, service, exc_info=True) break return iindex if iindex else [kDNSServiceInterfaceIndexAny]
def join_leave_multicast_group(s, interface_name, multicast_address, action, ospf_version): if ospf_version == conf.VERSION_IPV4: group_address_bits = socket.inet_aton(multicast_address) interface_index = socket.if_nametoindex(interface_name) membership_parameters = struct.pack(MULTICAST_STRING_FORMAT_IPV4, group_address_bits, interface_index) s.setsockopt(socket.IPPROTO_IP, action, membership_parameters) else: group_address_bits = socket.inet_pton(socket.AF_INET6, multicast_address) interface_index = socket.if_nametoindex(interface_name) membership_parameters = group_address_bits + struct.pack(MULTICAST_STRING_FORMAT_IPV6, interface_index) s.setsockopt(socket.IPPROTO_IPV6, action, membership_parameters)
def test_ping_interface(self): try: route_cmd = os.popen("ip -o -4 route show to default") default_route = route_cmd.read() finally: route_cmd.close() my_interface = default_route.split()[4] try: socket.if_nametoindex( my_interface) # test if the interface exists. except OSError: self.fail("Interface Name Error: {}".format(my_interface)) delay = ping3.ping(DEST_DOMAIN, interface=my_interface) self.assertIsInstance(delay, float)
def validate_config_section(self): """ Validate the interface information """ try: socket.if_nametoindex(self.name) except OSError: raise ValueError("Interface {} not found".format(self.name)) interface_addresses = [IPv6Address(addr_info['addr'].split('%')[0]) for addr_info in netifaces.ifaddresses(self.name).get(netifaces.AF_INET6, [])] # Pick the first link-local address as reply-from if none is specified in the configuration if not self.section.reply_from: for address in interface_addresses: if address.is_link_local: self.section.reply_from = address break if not self.section.reply_from: raise ValueError("No link-local address found on interface {}".format(self.name)) else: # Validate what the user supplied if not self.section.reply_from.is_link_local: raise ValueError("The reply-from address must be a link-local address") if self.section.reply_from not in interface_addresses: raise ValueError("Cannot find reply-from address {} on interface {}".format(self.section.reply_from, self.name)) # Pick the first global unicast address as link-address if none is specified in the configuration if not self.section.link_address: for address in interface_addresses: if is_global_unicast(address): self.section.link_address = address break if not self.section.link_address: # Use the unspecified address is we couldn't find anything self.section.link_address = IPv6Address('::') else: # Validate what the user supplied (we don't really care if it exists, it's just extra information for the # option handlers if not is_global_unicast(self.section.link_address): raise ValueError("The link-address must be a global unicast address")
def test_interface(self): with patch("sys.stdout", new=io.StringIO()) as fake_out: try: route_cmd = os.popen("ip -o -4 route show to default") default_route = route_cmd.read() finally: route_cmd.close() my_interface = default_route.split()[4] try: socket.if_nametoindex( my_interface) # test if the interface exists. except OSError: self.fail("Interface Name Error: {}".format(my_interface)) command_line.main(["-I", my_interface, DEST_DOMAIN]) self.assertRegex(fake_out.getvalue(), r".*[0-9]+ms.*")
def task2_xdp_start(): device = "lo" print(socket.if_nametoindex("eth1")) mode = BPF.XDP print(socket.if_nameindex()) ret = "XDP_TX" ctxtype = "xdp_md" flags = 0 b = BPF(src_file="xdp.c", cflags=["-w", "-DRETURNCODE=%s" % ret, "-DCTXTYPE=%s" % ctxtype]) fn = b.load_func("xdp_prog1", mode) b.attach_xdp(device, fn, flags) dropcnt = b.get_table("dropcnt") prev = [0] * 256 print("Printing drops per IP protocol-number, hit CTRL+C to stop") while 1: try: for k in dropcnt.keys(): val = dropcnt.sum(k).value i = k.value if val: delta = val - prev[i] prev[i] = val print("{}: {} pkt/s".format(i, delta)) time.sleep(1) except KeyboardInterrupt: print("Removing filter from device") break b.remove_xdp(device, flags)
def open(self): family = { 'udp': socket.AF_UNSPEC, 'udp4': socket.AF_INET, 'udp6': socket.AF_INET6 }[self.url.scheme] addrinfo = protocon.utilities.getaddrinfos(self.url.host, self.url.port, family, type=socket.SOCK_DGRAM, proto=socket.IPPROTO_UDP) if not addrinfo: raise protocon.ProtoconDriverError( 'getaddrinfo failed for the specified URL') self._addrinfo = addrinfo[0] if self._addrinfo.family == socket.AF_INET6 and self.settings[ 'ip6-scope-id'] is not None: scope_id = self.settings['ip6-scope-id'] scope_id = int(scope_id) if scope_id.isdigit( ) else socket.if_nametoindex(scope_id) self._addrinfo = self._addrinfo._replace( sockaddr=self._addrinfo.sockaddr[:3] + (scope_id, )) self._connection = socket.socket(self._addrinfo.family, self._addrinfo.type) if self._addrinfo.family == socket.AF_INET and self._addrinfo.sockaddr.address == '255.255.255.255': self._connection.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) source = self.settings['src'] if source: source = protocon.utilities.NetworkLocation.from_string(source) self._connection.bind(source.to_address()) self.connected = True
def send_rs ( self, pvdId = None, iface = None, src = None, dest = None ): '''Send Router-Solicitation message''' _iface = iface or self.iface if not _iface: # error, or should RS be sent to all interfaces by default? LOG.error("Interface must be provided for RS!") return None _src = src or self.__lla if not _src: # get ip address from interface with pyroute2 ip = pyroute2.IPDB() if _iface in ip.interfaces and 'ipaddr' in ip.interfaces[_iface]: for i in range(len(ip.interfaces[_iface]['ipaddr'])): a = ip.interfaces[_iface]['ipaddr'][i] if 'address' in a: ipaddr = ipaddress.ip_address ( a['address'] ) if ipaddr.is_link_local and ipaddr.version == 6: _src = a['address'] break if not _src: LOG.error("Source address must be provided!") return None msg = NdpMsg.create_rs ( src = _src, dest = dest, pvdId = pvdId, iface = _iface ) addr = ( msg.dest, 0, 0, socket.if_nametoindex(_iface) ) self.__sock.sendto ( msg.packet, addr ) return msg
def __init__(self, interface_name, local_port, ipv4, multicast_address, remote_address, receive_function, log, log_id): self._interface_name = interface_name self._local_port = local_port self._ipv4 = ipv4 # IPv4 if True, IPv6 if False self._remote_address = remote_address self._multicast_address = multicast_address # Unicast socket if None self._receive_function = receive_function self._log = log self._log_id = log_id self._local_ipv4_address = utils.interface_ipv4_address(interface_name) self._local_ipv6_address = utils.interface_ipv6_address(interface_name) try: self._interface_index = socket.if_nametoindex(interface_name) except (IOError, OSError) as err: self.warning("Could determine index of interface %s: %s", interface_name, err) self._interface_index = None if ipv4: if self._multicast_address: self.sock = self.create_socket_ipv4_rx_mcast() else: self.sock = self.create_socket_ipv4_rx_ucast() else: if self._multicast_address: self.sock = self.create_socket_ipv6_rx_mcast() else: self.sock = self.create_socket_ipv6_rx_ucast() if self.sock: scheduler.SCHEDULER.register_handler(self)
def addr_for_socket(addr, port=None, ifhint=None, af=None): """Process an address for a socket. Returns a tuple containing: address family, like socket.AF_INET tuple to pass to bind(), connect()""" addr = str(addr) if port is None: port = 0 port = int(port) if af is None: if addr.find(":") < 0: af = socket.AF_INET else: af = socket.AF_INET6 if af == socket.AF_INET: # IPv4 return ((socket.AF_INET, (addr, port))) elif not socket.has_ipv6: raise Exception("IPv6 addresses not supported in this Python") elif af == socket.AF_INET6: parts = [addr, port] ifindex = None pct = addr.find("%") if ifhint is not None and len(ifhint) > 3: ifindex = ifhint[3] if pct >= 0: ifindex = socket.if_nametoindex(addr[pct + 1:]) if ifindex is not None: ifindex = int(ifindex) parts.append(0) # flow id, not used parts.append(ifindex) # interface index number return (socket.AF_INET6, tuple(parts)) else: raise Exception("Unsupported address family " + repr(af))
def setup_socket(self): if self._ipversion == 4: self._mcast_addr = (str(self._mcast_ip4), 5355) self._soc = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) self._soc.setblocking( False) #SUPER IMPORTANT TO SET THIS FOR ASYNCIO!!!! self._soc.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self._soc.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 255) self._soc.bind(('', 5355)) mreq = struct.pack("=4sl", self._mcast_ip4.packed, socket.INADDR_ANY) self._soc.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq) else: interface_index = socket.if_nametoindex(self._ifname) self._soc = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM, socket.IPPROTO_UDP) self._soc.bind(('::', 5355, 0, interface_index)) self._soc.setsockopt( socket.IPPROTO_IPV6, socket.IPV6_JOIN_GROUP, struct.pack('16sI', self._mcast_ip6.packed, interface_index)) self._soc.setblocking( False) #SUPER IMPORTANT TO SET THIS FOR ASYNCIO!!!! self._mcast_addr = (str(self._mcast_ip6), 5355, 0, interface_index)
def create_virtual_interface(self, ip_interface, interface_name: str, index, flags=0x0): physical_if_index = if_nametoindex(interface_name) os.system("ip -6 mrule del iif {}".format(interface_name)) os.system("ip -6 mrule del oif {}".format(interface_name)) if hpim_globals.MULTICAST_TABLE_ID != 0: os.system("ip -6 mrule add iif {} lookup {}".format( interface_name, hpim_globals.MULTICAST_TABLE_ID)) os.system("ip -6 mrule add oif {} lookup {}".format( interface_name, hpim_globals.MULTICAST_TABLE_ID)) struct_mrt_add_vif = struct.pack("HBBHI", index, flags, 1, physical_if_index, 0) self.socket.setsockopt(socket.IPPROTO_IPV6, Kernel6.MRT6_ADD_MIF, struct_mrt_add_vif) self.vif_index_to_name_dic[index] = interface_name self.vif_name_to_index_dic[interface_name] = index for source_dict in list(self.routing.values()): for kernel_entry in list(source_dict.values()): kernel_entry.new_interface(index) self.interface_logger.debug('Create virtual interface: %s -> %d', interface_name, index) return index
def __init__(self, options): self.options = options self.if_index = socket.if_nametoindex(self.options.interface) self.socket = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM, socket.IPPROTO_UDP) self.socket.bind(('::', CLIENT_PORT, 0, self.if_index))
def init_v4(self): idx = socket.if_nametoindex(self.interface) self.multicast_address = (WSD_MCAST_GRP_V4, WSD_UDP_PORT) # v4: member_request (ip_mreqn) = { multicast_addr, intf_addr, idx } mreq = ( socket.inet_pton(self.family, WSD_MCAST_GRP_V4) + socket.inet_pton(self.family, self.address) + struct.pack('@I', idx)) self.recv_socket.setsockopt( socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq) try: self.recv_socket.bind((WSD_MCAST_GRP_V4, WSD_UDP_PORT)) except OSError: self.recv_socket.bind(('', WSD_UDP_PORT)) self.send_socket.setsockopt( socket.IPPROTO_IP, socket.IP_MULTICAST_IF, mreq) self.send_socket.setsockopt( socket.IPPROTO_IP, socket.IP_MULTICAST_LOOP, 0) self.send_socket.setsockopt( socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, args.hoplimit) self.listen_address = (self.address, WSD_HTTP_PORT)
def make_device_list(includes=set(), excludes=set()): log_debug("Making device list. Includes: {}, Excludes: {}".format( includes, excludes)) non_interfaces = set() devs = set([ dev.name for dev in pcap_devices() if not dev.isloop or dev.name in includes ]) includes = set(includes) # may have been given as a list includes.intersection_update(devs) # only include devs that actually exist for d in devs: try: ifnum = if_nametoindex(d) except: non_interfaces.add(d) devs.difference_update(non_interfaces) log_debug("Devices found: {}".format(devs)) # remove devs from excludelist devs.difference_update(set(excludes)) # if includelist is non-empty, perform # intersection with devs found and includelist if includes: devs.intersection_update(includes) log_debug("Using these devices: {}".format(devs)) return devs
def open(self): family = { 'udp': socket.AF_UNSPEC, 'udp4': socket.AF_INET, 'udp6': socket.AF_INET6 }[self.url.scheme] addrinfo = protocon.utilities.getaddrinfos(self.url.host, self.url.port, family, type=socket.SOCK_DGRAM, proto=socket.IPPROTO_UDP) if not addrinfo: raise protocon.ProtoconDriverError( 'getaddrinfo failed for the specified URL') self._addrinfo = addrinfo[0] if self._addrinfo.family == socket.AF_INET6 and self.settings[ 'ip6-scope-id'] is not None: scope_id = self.settings['ip6-scope-id'] scope_id = int(scope_id) if scope_id.isdigit( ) else socket.if_nametoindex(scope_id) self._addrinfo = self._addrinfo._replace( sockaddr=self._addrinfo.sockaddr[:3] + (scope_id, )) self._connection = socket.socket(self._addrinfo.family, self._addrinfo.type) self.connected = True
def server_bind(self): """ multicast & python: http://code.activestate.com/recipes/442490/ """ self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # multicast parameters # hop is one because it is all about the same subnet self.socket.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_LOOP, 0) self.socket.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_HOPS, 1) for i in cfg.INTERFACE: IF_NAME[i] = socket.if_nametoindex(i) IF_NUMBER[IF_NAME[i]] = i if_number = struct.pack('I', IF_NAME[i]) #mgroup = socket.inet_pton(socket.AF_INET6, cfg.MCAST) + if_number # no need vor variable.... the DHCPv6 multicast address is predefined mgroup = socket.inet_pton(socket.AF_INET6, 'ff02::1:2') + if_number # join multicast group - should work definitively if not ignoring interface at startup if cfg.IGNORE_INTERFACE: try: self.socket.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_JOIN_GROUP, mgroup) except Exception as err: print(err) else: self.socket.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_JOIN_GROUP, mgroup) # bind socket to server address self.socket.bind(self.server_address) # attempt to avoid blocking self.socket.setblocking(False) # some more requests? self.request_queue_size = 100
def make_device_list(includes=set(), excludes=set()): log_debug("Making device list. Includes: {}, Excludes: {}".format(includes, excludes)) non_interfaces = set() devs = set([ dev.name for dev in pcap_devices() if not dev.isloop or dev.name in includes]) includes = set(includes) # may have been given as a list includes.intersection_update(devs) # only include devs that actually exist for d in devs: try: ifnum = if_nametoindex(d) except: non_interfaces.add(d) devs.difference_update(non_interfaces) log_debug("Devices found: {}".format(devs)) # remove devs from excludelist devs.difference_update(set(excludes)) # if includelist is non-empty, perform # intersection with devs found and includelist if includes: devs.intersection_update(includes) log_debug("Using these devices: {}".format(devs)) return devs
def get_interface_index(cls): for iface in netifaces.interfaces(): addrs = netifaces.ifaddresses(iface).get(netifaces.AF_INET6, []) for addr in addrs: if addr['addr'] != '::1': return if_nametoindex(iface) raise SkipTest('could not find suitable interface for test')
def test_verbose_ping_interface(self): with patch("sys.stdout", new=io.StringIO()) as fake_out: try: route_cmd = os.popen("ip -o -4 route show to default") default_route = route_cmd.read() finally: route_cmd.close() my_interface = default_route.split()[4] try: socket.if_nametoindex( my_interface) # test if the interface exists. except OSError: self.fail('Interface Name Error: {}'.format(my_interface)) dest_addr = "example.com" ping3.verbose_ping(dest_addr, interface=my_interface) self.assertRegex(fake_out.getvalue(), r".*[0-9]+ms.*")
def setup_multicasting(self): # Subscribe to multicast address if self.proto == "ipv4": mreq = socket.inet_aton(self.broadcast_ip) if self.address is not None: mreq += socket.inet_aton(self.address) else: mreq += struct.pack(b"@I", socket.INADDR_ANY) self.sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq) # Allow multicasts on loopback devices (necessary for testing) self.sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_LOOP, 1) elif self.proto == "ipv6": # In IPv6 we use the interface index, not the address when subscribing to the group mreq = socket.inet_pton(socket.AF_INET6, self.broadcast_ip) if self.iface is not None: iface_index = socket.if_nametoindex(self.iface) # Send outgoing packets from the same interface self.sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_IF, iface_index) mreq += struct.pack(b"@I", iface_index) else: mreq += socket.inet_pton(socket.AF_INET6, "::") self.sock.setsockopt( socket.IPPROTO_IPV6, socket.IPV6_JOIN_GROUP, mreq, ) self.sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_LOOP, 1)
def low_level_address_tuple(high_tuple, af=None): """Given a "high-level" address tuple, i.e. an (address, port) return the appropriate "low-level" address tuple suitable for use in socket calls. If an *af* other than ``None`` is provided, it is assumed the address in the high-level tuple is valid and has that af. If af is ``None``, then af_for_address will be called. """ address, port = high_tuple if af is None: af = af_for_address(address) if af == AF_INET: return (address, port) elif af == AF_INET6: i = address.find('%') if i < 0: # no scope, shortcut! return (address, port, 0, 0) # try to avoid getaddrinfo() addrpart = address[:i] scope = address[i + 1:] if scope.isdigit(): return (addrpart, port, 0, int(scope)) try: return (addrpart, port, 0, socket.if_nametoindex(scope)) except AttributeError: # pragma: no cover (we can't really test this) ai_flags = socket.AI_NUMERICHOST ((*_, tup), *_) = socket.getaddrinfo(address, port, flags=ai_flags) return tup else: raise NotImplementedError(f'unknown address family {af}')
def init_v6(self): idx = socket.if_nametoindex(self.interface) self.multicast_address = (WSD_MCAST_GRP_V6, WSD_UDP_PORT, 0x575C, idx) # v6: member_request = { multicast_addr, intf_idx } mreq = (socket.inet_pton(self.family, WSD_MCAST_GRP_V6) + struct.pack('@I', idx)) self.recv_socket.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_JOIN_GROUP, mreq) self.recv_socket.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, 1) # bind to network interface, i.e. scope and handle OS differences, # see Stevens: Unix Network Programming, Section 21.6, last paragraph try: self.recv_socket.bind((WSD_MCAST_GRP_V6, WSD_UDP_PORT, 0, idx)) except OSError: self.recv_socket.bind(('::', 0, 0, idx)) self.send_socket.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_LOOP, 0) self.send_socket.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_HOPS, args.hoplimit) self.send_socket.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_IF, idx) self.transport_address = '[{0}]'.format(self.address) self.listen_address = (self.address, WSD_HTTP_PORT, 0, idx)
async def _create_transport_endpoint(cls, sock, ctx: interfaces.MessageManager, log, loop, multicast=[]): try: sock.setsockopt(socket.IPPROTO_IPV6, socknumbers.IPV6_RECVPKTINFO, 1) except NameError: raise RuntimeError( "RFC3542 PKTINFO flags are unavailable, unable to create a udp6 transport." ) if socknumbers.HAS_RECVERR: sock.setsockopt(socket.IPPROTO_IPV6, socknumbers.IPV6_RECVERR, 1) # i'm curious why this is required; didn't IPV6_V6ONLY=0 already make # it clear that i don't care about the ip version as long as everything looks the same? sock.setsockopt(socket.IPPROTO_IP, socknumbers.IP_RECVERR, 1) else: log.warning( "Transport udp6 set up on platform without RECVERR capability. ICMP errors will be ignored." ) for (address, interface) in sum( map( # Expand shortcut of "interface name means default CoAP all-nodes addresses" lambda i: [(a, i) for a in constants.MCAST_ALL] if isinstance(i, str) else [i], multicast), []): address = ipaddress.ip_address(address) interface = socket.if_nametoindex(interface) if isinstance(address, ipaddress.IPv4Address): s = struct.pack('4s4si', address.packed, socket.inet_aton("0.0.0.0"), interface) try: sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, s) except OSError: log.warning("Could not join IPv4 multicast group") elif isinstance(address, ipaddress.IPv6Address): s = struct.pack('16si', address.packed, interface) try: sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_JOIN_GROUP, s) except OSError: log.warning("Could not join IPv6 multicast group") else: raise RuntimeError("Unknown address format") transport, protocol = await create_recvmsg_datagram_endpoint( loop, lambda: cls(ctx, log=log, loop=loop), sock=sock) await protocol.ready return protocol
def send_unicast(self, ifname, ip, b): if isinstance(ip, ipaddress.IPv6Address): ip = ip.compressed if isinstance(ip, ipaddress.IPv4Address): return # no v4! _debug('send_unicast %s%%%s %d bytes' % (ip, ifname, len(b))) ifindex = socket.if_nametoindex(ifname) babel.interface(ifname).s.sendto(b, (ip, BABEL_PORT, 0, ifindex))
def if_nametoindex2(name): if settings.Config.PY2OR3 == "PY2": import ctypes import ctypes.util libc = ctypes.CDLL(ctypes.util.find_library('c')) ret = libc.if_nametoindex(name) return ret else: return socket.if_nametoindex(settings.Config.Interface)
def __init__(self, interface_name: str, vif_index: int): # SEND SOCKET s = socket.socket(socket.AF_INET6, socket.SOCK_RAW, socket.IPPROTO_ICMPV6) # set socket output interface if_index = if_nametoindex(interface_name) s.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_IF, struct.pack('@I', if_index)) """ # set ICMP6 filter to only receive MLD packets icmp6_filter = ICMP6_FILTER_SETBLOCKALL() icmp6_filter = ICMP6_FILTER_SETPASS(MULTICAST_LISTENER_QUERY_TYPE, icmp6_filter) icmp6_filter = ICMP6_FILTER_SETPASS(MULTICAST_LISTENER_REPORT_TYPE, icmp6_filter) icmp6_filter = ICMP6_FILTER_SETPASS(MULTICAST_LISTENER_DONE_TYPE, icmp6_filter) s.setsockopt(socket.IPPROTO_ICMPV6, ICMP6_FILTER, icmp6_filter) s.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_RECVPKTINFO, True) s.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_LOOP, False) s.setsockopt(socket.IPPROTO_IPV6, self.IPV6_ROUTER_ALERT, 0) rcv_s = s """ ip_interface = "::" for if_addr in netifaces.ifaddresses(interface_name)[ netifaces.AF_INET6]: ip_interface = if_addr["addr"] if ipaddress.IPv6Address(ip_interface.split("%")[0]).is_link_local: # bind to interface s.bind( socket.getaddrinfo(ip_interface, None, 0, socket.SOCK_RAW, 0, socket.AI_PASSIVE)[0][4]) ip_interface = ip_interface.split("%")[0] break self.ip_interface = ip_interface # RECEIVE SOCKET rcv_s = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(ETH_P_IPV6)) # receive only MLD packets by setting a BPF filter bpf_filter = b''.join(InterfaceMLD.FILTER_MLD) b = create_string_buffer(bpf_filter) mem_addr_of_filters = addressof(b) fprog = struct.pack('HL', len(InterfaceMLD.FILTER_MLD), mem_addr_of_filters) rcv_s.setsockopt(socket.SOL_SOCKET, SO_ATTACH_FILTER, fprog) # bind to interface rcv_s.bind((interface_name, ETH_P_IPV6)) super().__init__(interface_name=interface_name, recv_socket=rcv_s, send_socket=s, vif_index=vif_index) self.interface_enabled = True from .mld.RouterState import RouterState self.interface_state = RouterState(self)
def main(): logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(levelname)-8s %(message)s', datefmt='%m-%d %H:%M') logging.info("START") ddhcp = DDHCP(config) loop = asyncio.get_event_loop() # DHCP Socket def dhcp_factory(): return DHCPProtocol(loop, ddhcp) dhcplisten = loop.create_datagram_endpoint(dhcp_factory, family=socket.AF_INET, local_addr=("0.0.0.0", 67)) dhcptransport, dhcpprotocol = loop.run_until_complete(dhcplisten) sock = dhcptransport.get_extra_info("socket") sock.setsockopt(socket.SOL_SOCKET, IN.SO_BINDTODEVICE, bytes(config["clientif"] + '\0', "UTF-8")) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) # DDHCP Socket def ddhcp_factory(): return DDHCPProtocol(loop, (config["mcgroup"], config["mcport"]), ddhcp, config) listen = loop.create_datagram_endpoint(ddhcp_factory, family=socket.AF_INET6, local_addr=('::', config["mcport"])) transport, protocol = loop.run_until_complete(listen) sock = transport.get_extra_info("socket") ifn = socket.if_nametoindex(config["mcif"]) ifn = struct.pack("I", ifn) sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_IF, ifn) # Join group group_bin = socket.inet_pton(socket.AF_INET6, config["mcgroup"]) mreq = group_bin + ifn sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_JOIN_GROUP, mreq) # Do not loopback multicast packets sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_LOOP, 0) try: loop.run_forever() except KeyboardInterrupt: pass dhcptransport.close() transport.close() loop.close()
def create(self, old_listeners: Iterable[Listener] = None) -> UDPListener: """ Create a listener of this class based on the configuration in the config section. :param old_listeners: A list of existing listeners in case we can recycle them :return: A listener object """ mc_address = IPv6Address(All_DHCP_Relay_Agents_and_Servers) interface_index = socket.if_nametoindex(self.name) # Try recycling old_listeners = list(old_listeners or []) for old_listener in old_listeners: if not isinstance(old_listener, UDPListener): continue if self.match_socket(sock=old_listener.listen_socket, address=mc_address, interface=interface_index): logger.debug("Recycling existing multicast socket on {}".format(self.name)) mc_sock = old_listener.listen_socket break else: logger.debug("Listening for multicast requests on {}".format(self.name)) mc_sock = socket.socket(socket.AF_INET6, self.sock_type, self.sock_proto) mc_sock.bind((str(mc_address), self.listen_port, 0, interface_index)) mc_sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_JOIN_GROUP, pack('16sI', mc_address.packed, interface_index)) # Set the socket options mc_sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_LOOP, self.listen_to_self and 1 or 0) for old_listener in old_listeners: if not isinstance(old_listener, UDPListener): continue if self.match_socket(sock=old_listener.listen_socket, address=self.reply_from, interface=interface_index): logger.debug(" - Recycling existing reply socket for {} on {}".format(self.reply_from, self.name)) ll_sock = old_listener.listen_socket break if self.match_socket(sock=old_listener.reply_socket, address=self.reply_from, interface=interface_index): logger.debug(" - Recycling existing reply socket for {} on {}".format(self.reply_from, self.name)) ll_sock = old_listener.reply_socket break else: logger.debug(" - Sending replies from {}".format(self.reply_from)) ll_sock = socket.socket(socket.AF_INET6, self.sock_type, self.sock_proto) ll_sock.bind((str(self.reply_from), self.listen_port, 0, interface_index)) return UDPListener(interface_name=self.name, listen_socket=mc_sock, reply_socket=ll_sock, global_address=self.link_address, marks=self.marks)
def send_reply(self, outgoing_message: RelayReplyMessage) -> bool: """ Send a reply to the client :param outgoing_message: The message to send, including a wrapping RelayReplyMessage :return: Whether sending was successful """ # Determine network addresses and bytes reply = outgoing_message.relayed_message port = isinstance(reply, RelayReplyMessage) and SERVER_PORT or CLIENT_PORT destination_address = str(outgoing_message.peer_address) data = reply.save() # Try to determine the interface index from the outgoing relay options interface_index = 0 interface_name = "unknown" interface_id_option = outgoing_message.get_option_of_type(InterfaceIdOption) if interface_id_option: try: interface_name = interface_id_option.interface_id.decode(encoding="utf-8", errors="replace") interface_index = socket.if_nametoindex(interface_id_option.interface_id) except OSError: pass destination = (destination_address, port, 0, interface_index) sent_length = self.reply_socket.sendto(data, destination) success = len(data) == sent_length if success: logger.log( DEBUG_PACKETS, "Sent {message_type} to {client_addr} port {port} on {interface}".format( message_type=outgoing_message.inner_message.__class__.__name__, client_addr=destination_address, port=port, interface=interface_name, ), ) else: logger.error( "Could not send {message_type} to {client_addr} port {port} on {interface}".format( message_type=outgoing_message.inner_message.__class__.__name__, client_addr=destination_address, port=port, interface=interface_name, ) ) return success
def _assemble_devinfo(self): ''' Internal method. Assemble information on each interface/ device that we know about, i.e., its MAC address and configured IP address and prefix. ''' devtype = {} for p in pcap_devices(): if p.isloop: devtype[p.name] = InterfaceType.Loopback else: if sys.platform == 'linux': st,output = subprocess.getstatusoutput(["iwconfig", p.name]) if "no wireless extensions" in output: devtype[p.name] = InterfaceType.Wired else: devtype[p.name] = InterfaceType.Wireless elif sys.platform == 'darwin': devtype[p.name] = InterfaceType.Unknown else: devtype[p.name] = InterfaceType.Unknown devinfo = {} ifinfo = net_if_addrs() for devname in self._devs: ifaddrs = ifinfo.get(devname, None) if ifaddrs is None: log_warn("Address info for interface {} not found! (skipping)".format(devname)) if sys.platform == 'darwin': layer2addrfam = socket.AddressFamily.AF_LINK elif sys.platform == 'linux': layer2addrfam = socket.AddressFamily.AF_PACKET else: raise RuntimeException("Platform not supported") macaddr = "00:00:00:00:00:00" ipaddr = mask = "0.0.0.0" for addrinfo in ifaddrs: if addrinfo.family == socket.AddressFamily.AF_INET: ipaddr = IPv4Address(addrinfo.address) mask = IPv4Address(addrinfo.netmask) elif addrinfo.family == layer2addrfam: macaddr = EthAddr(addrinfo.address) ifnum = socket.if_nametoindex(devname) devinfo[devname] = Interface(devname, macaddr, ipaddr, netmask=mask, ifnum=ifnum, iftype=devtype[devname]) return devinfo
def setup_babel(iflist): addrinfo = socket.getaddrinfo(BABEL_GROUP, None)[0] group_bin = socket.inet_pton(addrinfo[0], addrinfo[4][0]) s = socket.socket(family=socket.AF_INET6, type=socket.SOCK_DGRAM) s.bind(('', BABEL_PORT)) s.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_LOOP, False) def _f(): data, addr = s.recvfrom(2**16) ads, ifname = addr[0].split('%') a = ipaddress.ip_address(ads) babel.process_inbound(ifname, a, data) sys.add_reader(s, _f) for ifname in iflist: ifo = babel.interface(ifname) ifo.s = s ifindex = socket.if_nametoindex(ifname) mreq = group_bin + struct.pack('@I', ifindex) s.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_JOIN_GROUP, mreq)
def interface_exists(config, name, value): try: socket.if_nametoindex(value) except OSError: raise ConfigError(name, "Interface {} not found".format(value))
def get_sockets(config: configparser.ConfigParser) -> [ListeningSocket]: """ Set up the network sockets. :param config: The configuration :return: The list of sockets """ logger.debug("Creating sockets") mc_address = dhcpkit.ipv6.All_DHCP_Relay_Agents_and_Servers port = dhcpkit.ipv6.SERVER_PORT # Placeholders for exception message interface_name = 'unknown' address = 'unknown' try: sockets = [] interface_names = [section_name.split(' ')[1] for section_name in config.sections() if section_name.split(' ')[0] == 'interface'] for interface_name in interface_names: section_name = 'interface {}'.format(interface_name) section = config[section_name] interface_index = socket.if_nametoindex(interface_name) first_global = None for address_str in section['global-unicast-addresses'].split(' '): if not address_str: continue address = IPv6Address(address_str) logger.debug("- Creating socket for {} on {}".format(address, interface_name)) sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM, socket.IPPROTO_UDP) sock.bind((str(address), port)) sockets.append(ListeningSocket(interface_name, sock)) if not first_global: first_global = address if not first_global and (section['link-local-addresses'] or section.getboolean('multicast')): # Get all global addresses because we would like one for link identification available_addresses_info = netifaces.ifaddresses(interface_name).get(netifaces.AF_INET6, []) available_address_strings = [address_info['addr'] for address_info in available_addresses_info] available_addresses = [IPv6Address(address.split('%')[0]) for address in available_address_strings] global_addresses = [address for address in available_addresses if not address.is_link_local] global_addresses.sort() if global_addresses: first_global = global_addresses[0] else: # No address known first_global = IPv6Address('::') link_local_sockets = [] for address_str in section['link-local-addresses'].split(' '): if not address_str: continue address = IPv6Address(address_str) logger.debug("- Creating socket for {} on {}".format(address, interface_name)) sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM, socket.IPPROTO_UDP) sock.bind((str(address), port, 0, interface_index)) link_local_sockets.append((address, sock)) sockets.append(ListeningSocket(interface_name, sock, global_address=first_global)) if section.getboolean('multicast'): address = mc_address reply_from = link_local_sockets[0] logger.debug("- Creating socket for {} with {} " "as reply-from address on {} ".format(address, reply_from[0], interface_name)) sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM, socket.IPPROTO_UDP) sock.bind((address, port, 0, interface_index)) if section.getboolean('listen-to-self'): sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_LOOP, 1) sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_JOIN_GROUP, pack('16sI', IPv6Address('ff02::1:2').packed, interface_index)) sockets.append(ListeningSocket(interface_name, sock, reply_from[1], global_address=first_global)) except OSError as e: logger.critical("Cannot create socket for address {} on interface {}: {}".format(address, interface_name, e.strerror)) sys.exit(1) except ListeningSocketError as e: logger.critical(str(e)) sys.exit(1) return sockets
def joinMCAST(sock, addr, ifname): group = socket.inet_pton(socket.AF_INET6, addr) if_idx = socket.if_nametoindex(ifname) sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_JOIN_GROUP, group + struct.pack('I', if_idx))
print("received packet") tlv.dumptlv(tdec) if tlv.hastag(tdec, tlv.T_DISCO_RESPONSE): hsc_parse_discovery_response(tdec, addr[0]) UDP_PORT = config.get('hsc', 'udpport', fallback=19691) MCAST_GROUP = config.get('hsc', 'multicastgroup', fallback="224.0.0.91") MCAST_IFACE = config.get('hsc', 'interface', fallback="br0") addrinfo = socket.getaddrinfo(MCAST_GROUP, None)[0] hsc_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # UDP hsc_sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) hsc_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) hsc_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1) hsc_sock.bind(("0.0.0.0", UDP_PORT)) group_bin = socket.inet_pton(addrinfo[0], MCAST_GROUP) mreq = struct.pack('4sL', group_bin, socket.if_nametoindex(MCAST_IFACE)) hsc_sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq) addrinfo = socket.getaddrinfo("0.0.0.0", None)[0] bcast_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # UDP bcast_sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) bcast_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) bcast_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1) bcast_sock.bind(("0.0.0.0", UDP_PORT)) receive_thread = Thread(target=hsc_receive_thread_fn, args=(hsc_sock,)) receive_thread.setDaemon(True) receive_thread.start()
def interface_exists(option, config, value): try: socket.if_nametoindex(value) except OSError: raise OptionCheckError("Interface {} not found".format(value), option=option.__name__)