From 626aca0691b63203d4ab0c2d4a7f6b713375a2fa Mon Sep 17 00:00:00 2001 From: Jarrod Johnson Date: Mon, 21 Nov 2022 13:26:37 -0500 Subject: [PATCH] Implement proxyDHCP remote operation Provide means to function if we are only the proxyDHCP service, delegated from DHCP server. --- confluent_server/confluent/credserver.py | 2 +- .../confluent/discovery/protocols/pxe.py | 43 +++++++++++++------ 2 files changed, 32 insertions(+), 13 deletions(-) diff --git a/confluent_server/confluent/credserver.py b/confluent_server/confluent/credserver.py index 3fd50446..56bda2c4 100644 --- a/confluent_server/confluent/credserver.py +++ b/confluent_server/confluent/credserver.py @@ -52,7 +52,7 @@ def address_is_somewhat_trusted(address, nodename, cfm): for anet in authnet.split(): na, plen = anet.split('/') plen = int(plen) - if netutil.ip_on_same_subnet(address, no, plen): + if netutil.ip_on_same_subnet(address, na, plen): return True return False diff --git a/confluent_server/confluent/discovery/protocols/pxe.py b/confluent_server/confluent/discovery/protocols/pxe.py index d3efa1e0..839ea706 100644 --- a/confluent_server/confluent/discovery/protocols/pxe.py +++ b/confluent_server/confluent/discovery/protocols/pxe.py @@ -278,25 +278,45 @@ def proxydhcp(): net4011.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) net4011.setsockopt(socket.IPPROTO_IP, IP_PKTINFO, 1) net4011.bind(('', 4011)) + rp = bytearray(300) + rpv = memoryview(rp) + rq = bytearray(2048) + data = pkttype.from_buffer(rq) + msg = msghdr() + cmsgarr = bytearray(cmsgsize) + cmsg = cmsgtype.from_buffer(cmsgarr) + iov = iovec() + iov.iov_base = ctypes.addressof(data) + iov.iov_len = 2048 + msg.msg_iov = ctypes.pointer(iov) + msg.msg_iovlen = 1 + msg.msg_control = ctypes.addressof(cmsg) + msg.msg_controllen = ctypes.sizeof(cmsg) + clientaddr = sockaddr_in() + msg.msg_name = ctypes.addressof(clientaddr) + msg.msg_namelen = ctypes.sizeof(clientaddr) cfg = cfm.ConfigManager(None) while True: ready = select.select([net4011], [], [], None) if not ready or not ready[0]: continue - rq = bytearray(1024) - rqv = memoryview(rq) - nb, client = net4011.recvfrom_into(rq) - if nb < 240: + i = recvmsg(net4011.fileno(), ctypes.pointer(msg), 0) + #nb, client = net4011.recvfrom_into(rq) + if i < 240: continue - rp = bytearray(1024) - rpv = memoryview(rp) + rqv = memoryview(rq)[:i] + client = (ipfromint(clientaddr.sin_addr.s_addr), socket.htons(clientaddr.sin_port)) + _, level, typ = struct.unpack('QII', cmsgarr[:16]) + if level == socket.IPPROTO_IP and typ == IP_PKTINFO: + idx, recv = struct.unpack('II', cmsgarr[16:24]) + recv = ipfromint(recv) try: - optidx = rq.index(b'\x63\x82\x53\x63') + 4 + optidx = rqv.tobytes().index(b'\x63\x82\x53\x63') + 4 except ValueError: continue - hwlen = rq[2] - opts, disco = opts_to_dict(rq, optidx, 3) - disco['hwaddr'] = ':'.join(['{0:02x}'.format(x) for x in rq[28:28+hwlen]]) + hwlen = rqv[2] + opts, disco = opts_to_dict(rqv, optidx, 3) + disco['hwaddr'] = ':'.join(['{0:02x}'.format(x) for x in rqv[28:28+hwlen]]) node = None if disco.get('hwaddr', None) in macmap: node = macmap[disco['hwaddr']] @@ -304,10 +324,9 @@ def proxydhcp(): node = uuidmap[disco['uuid']] if not node: continue - myipn = myipbypeer.get(rqv[28:28+hwlen].tobytes(), None) if not myipn: - continue + myipn = socket.inet_aton(recv) if opts.get(77, None) == b'iPXE': profile = get_deployment_profile(node, cfg) if not profile: