Пример #1
0
def _ReadFromTap():  
    try:    
        
        recvBytesNum = _tapFD_read.readinto(_TAPpacketBuffer[ARCHANET_HEADER_MAX_SIZE:])
        
        ethernetPkt = _TAPpacketBuffer[ARCHANET_HEADER_MAX_SIZE:ARCHANET_HEADER_MAX_SIZE+recvBytesNum]
        #MacDst = EUI(int.from_bytes(ethernetPkt[0:6].tobytes(), "big"))
        MacSrc = EUI(int.from_bytes(ethernetPkt[6:12].tobytes(), "big"))
        EthType = ethernetPkt[12:14]
            
        ethernetPayload = ethernetPkt[14:recvBytesNum]
        ethernetPayload_len = len(ethernetPayload)
                   
        #if EthType == 0x0806: # ARP Protocol
        if EthType ==  b'\x08\x06': # ARP Protocol
            # struct.unpack("!HHBBH", ethernetPayload[0:8])            
            #HardwareType = ethernetPayload[0:2] 
            ARPProtocolType = ethernetPayload[2:4].tobytes() 
            #HardwareAddressLength = ethernetPayload[4] 
            #ProtocolAddressLength = ethernetPayload[5]
            #Operation = int.from_bytes(ethernetPayload[6:8], 'big') 
            Operation = ethernetPayload[6:8].tobytes() 
                            
            if Operation == b'\x00\x01':                
                if ARPProtocolType == b'\x08\x00': # 0x0800: #IPv4
                    #strFormat = str.format("!6s4s6s4s", HardwareAddressLength, ProtocolAddressLength, HardwareAddressLength, ProtocolAddressLength)                    
                    SenderHardwareAddress = ethernetPayload[8:14] 
                    #SenderProtocolAddress = ethernetPayload[14:18] 
                    #TargetHardwareAddress = ethernetPayload[18:24] 
                    TargetProtocolAddress = ethernetPayload[24:28]                    
                                        
                    targetIPv4 = IPv4Address(TargetProtocolAddress.tobytes())
                    if not (targetIPv4 in _tapIPv4Network):                        
                        _TapLogger.debug(str.format("IPv4 {:s} does not belong to this network ({:s}).", str(targetIPv4), _tapIPv4Network))
                        return
                    
                    peer_client = _DB.QueryReverseDNSTranslation(IPv4Address(TargetProtocolAddress.tobytes()))
                    if not peer_client:
                        _TapLogger.debug(str.format("No ARP Solution for IPv4 {:s}.", str(targetIPv4)))
                        return
                    (client_mac, _, _) = _DB.QueryDNSTranslation(*peer_client)
                    
                    
                    ethernetPkt[0:6] = SenderHardwareAddress
                    ethernetPkt[6:12] = _tapMAC_bytes
                    ethernetPayload[6:8] = b'\x00\x02' #int(2).to_bytes(2, 'big')                    
                    ethernetPayload[18:24] = ethernetPayload[8:14]
                    ethernetPayload[8:14] = client_mac.packed  
                    tmp = ethernetPayload[14:18].tobytes()
                    ethernetPayload[14:18] = ethernetPayload[24:28]
                    ethernetPayload[24:28] = tmp
                    
                    _tapFD_write.write(ethernetPkt[0:42])
                    return
#                     _tapFD_write.write(struct.pack("!6s6sH HHBBH 6s4s6s4s",
#                                               SenderHardwareAddress, _tapMAC_bytes, 0x0806, 
#                                               HardwareType, ARPProtocolType, HardwareAddressLength, ProtocolAddressLength, 2, 
#                                               client_mac, TargetProtocolAddress, SenderHardwareAddress, SenderProtocolAddress)                            
#                                              )
                    
                if ARPProtocolType == b'\x86\xDD': #0x86DD: #IPv6
                    _TapLogger.debug("ARP IPv6 not Implemented - Discarding Packet")    
                    return                                     
                #Other ARP Type -> Ignore               
                _TapLogger.debug(str.format("Ignoring ARP Packet: Type {:d}", int.from_bytes(ARPProtocolType, 'big')))
                return
            #Other ARP Operation Type -> Ignore
            _TapLogger.debug(str.format("Ignoring ARP Operation: {:d}", int.from_bytes(Operation, 'big')))
            return
        
        #######################################################################################################################
        #0x0800: # IPv4 Protocol Ingress
        if EthType == b'\x08\x00': 
            IPv4_pkt = ethernetPayload
            IPv4Hdr_len = (IPv4_pkt[0] & 0x0F) * 4
            srcIpAddr = IPv4_pkt[12:16]
            dstIpAddr = IPv4_pkt[16:20] 
                        
            srcIPv4obj = IPv4Address(srcIpAddr.tobytes())
            dstIPv4obj = IPv4Address(dstIpAddr.tobytes())
            if dstIPv4obj == _tapIPv4Network.broadcast_address:
                _TapLogger.debug("Broadcast IPv4 was detected. Ignoring Packet since Broadcast IPv4 is not Implemented.")         
                return           
            
            if dstIPv4obj.is_multicast:
                _TapLogger.debug("Multicast IPv4 was detected. Ignoring Packet since Multicast IPv4 is not Implemented.")
                return
                
            src_peerUUID_clientID = _DB.QueryReverseDNSTranslation(srcIPv4obj)
            if not src_peerUUID_clientID: ## Local Client is not registered. Sends an event to cognition to register the local client. 
                _eventQueue.put_nowait((SYS_CONTROL_EVENT_FOUND_LAN_CLIENT, MacSrc, srcIPv4obj))
                return
            
            (_, srcClientID) = src_peerUUID_clientID
            dst_peerUUID_clientID = _DB.QueryReverseDNSTranslation(dstIPv4obj)
            pathID = None     
            if dst_peerUUID_clientID:
                (dstAgentUUID, dstClientID) = dst_peerUUID_clientID
                pathID = _PM.QueryBestPathToPeer(dstAgentUUID)
            
            #### If there is no translation available or no pathID available, return to sender an ICMP Host Unreachable
            if not (dst_peerUUID_clientID and pathID):
                # http://www.firewall.cx/networking-topics/protocols/icmp-protocol/153-icmp-destination-unreachable.html
                #Ethernet Header (14) + IPv4 (20) ICMP (12) + Original IPv4 Header + 8 bytes of Original data                                         
                icmpBuf = memoryview(bytearray(IPv4Hdr_len + 54))  

                # MacHdr+IPHdr+ICMPHdr                
                icmpBuf[0:6] = ethernetPkt[6:12]
                icmpBuf[6:12] = _tapMAC_bytes
                icmpBuf[12] = 0x08 #; icmpBuf[13] = (0x00) - unecessary. Bytearray already initialized with zero values                
                
                #IPv4Hdr = struct.pack("!BBHHBBBBH4s4s", (0x04<<4)| 0x05, 0, len(icmpBuf)-14 , 0, (0x1<<6),0,0,1, 0 , dstIpAddr.tobytes(), _tapIPv4_bytes)                     
                IPv4Hdr = struct.pack("!BBHHBBBBH4s4s", (0x04<<4)| 0x05, 0, len(icmpBuf)-14 , 0, (0x1<<6),0,0,1, 0 , _tapIPv4_bytes, srcIpAddr.tobytes())
                cs16Value = _checksum16(IPv4Hdr)                
                icmpBuf[14:24] = IPv4Hdr[0:10]
                icmpBuf[24:26] = cs16Value.to_bytes(2, 'big')
                icmpBuf[26:34] = IPv4Hdr[12:20]
                
                strFrmt = str.format("!BBHHH{:d}s", IPv4Hdr_len+8)
                icmpBytes =  struct.pack(strFrmt, 3, 1, 0, 0, 0, IPv4_pkt[0:IPv4Hdr_len+8].tobytes())                 
                ICMPChecksum = _checksum16(icmpBytes)
                icmpBuf[34:34 + len(icmpBytes)] = icmpBytes
                icmpBuf[36:38] = ICMPChecksum.to_bytes(2, 'big')
                
                _tapFD_write.write(icmpBuf)
                   
                if not dst_peerUUID_clientID:
                    _TapLogger.debug(str.format("No Translation available for IPv4 {:s}. Dropping Packet and returning ICMP Host Unreachable.", str(dstIPv4obj)))                                 
                else:
                    _TapLogger.debug(str.format("No path available to peer {:s}. Dropping Packet and returning ICMP Host Unreachable.", str(dstAgentUUID)))
                return 
            
            ########
            ## TODO: Fragmentation needs to be implemented for variable MTU. Here it is the place
            ##         Check Don't Fragment bit in the IPv4 header. If active, return the ICMP 
            #//  Check if the path max MTU can receive de packet. If not, send an ICMP with type 3 code 4
            #//  PathMTU already contemplates the minimum Archanet Header size.
            #//  If the path requires to use a next path id, then it will require an archanet header with a minimum size of 52 bytes.
            #//   http://tools.ietf.org/html/rfc1191
            #//   http://en.wikipedia.org/wiki/Internet_Control_Message_Protocol - Destination Unreachable next hop mtu
            #//   http://en.wikipedia.org/wiki/IPv4#Fragmentation_and_reassembly 
            #
            #  REMEMBER - The Path MTU needs to be compared with the size of the future archanet packet length. It includes Archa header size and switch list size
            
            if not _DB.isPathIDRegistered(pathID):
                _TapLogger.debug(str.format("No Translation available for PathID {:s}. Dropping Packet.", byteStr2HexStr(pathID)))
                
                return
            
            (nextpathID, _, switchIDlist, _, pathMTU) = _DB.QueryPathID(pathID)
            (isActive, interfaceName, interfaceMAC, dstPeerMAC, _) = _DB.QuerySwitchIDInfo(switchIDlist[0])
            if not isActive:
                _TapLogger.debug(str.format("Switch ID ({:d}) is not Active. Dropping Packet during Ingress.", switchIDlist[0]))
                return            

            pktSwitchList = list(switchIDlist[1:])
            pktSwitchList.reverse()
                        
            archaNetFlags = 0
            if nextpathID:
                archaNetPkt = _TAPpacketBuffer[0:]              
                archaNetPkt[14] = archaNetFlags | ARCHA_FLAG_PATHID
                archaNetPkt[16:16+PATHID_HASH_WSIZE] = nextpathID
                pp_pivot = 16+PATHID_HASH_WSIZE
            else:                                
                archaNetPkt = _TAPpacketBuffer[16:]
                archaNetPkt[14] = archaNetFlags
                pp_pivot = 16            
                        
            archaNetPkt[0:6] = dstPeerMAC.packed
            archaNetPkt[6:12] = interfaceMAC.packed
            archaNetPkt[12] = 0xAA; archaNetPkt[13] = 0xAA                           
            archaNetPkt[15] = len(pktSwitchList)
            
            archaNetPkt[pp_pivot:pp_pivot+16] = _systemUUID.bytes            
            archaNetPkt[pp_pivot+16:pp_pivot+18] = ethernetPayload_len.to_bytes(2, 'big')
            archaNetPkt[pp_pivot+18] = 0x08
            archaNetPkt[pp_pivot+19] = 0x00
            archaNet_pkt_end = pp_pivot+20+ethernetPayload_len+len(pktSwitchList)                      
            archaNetPkt[pp_pivot+20+ethernetPayload_len:archaNet_pkt_end] = bytes(pktSwitchList)

            newIPv4_bytes = struct.pack("!II",srcClientID,dstClientID)
            #newSum = (IPv4_pkt[10] << 8) + IPv4_pkt[11] # The newSum here initialized, is actually the oldSum (C)
            newSum = int.from_bytes(IPv4_pkt[10:12], 'big')
            ### We get the old values
            oldStuff = sum((int.from_bytes(IPv4_pkt[12:14], 'big'),
                           int.from_bytes(IPv4_pkt[14:16], 'big'),
                           int.from_bytes(IPv4_pkt[16:18], 'big'),
                           int.from_bytes(IPv4_pkt[18:20], 'big'),
                           ))

            ### Prepare the new ones
            newStuff = srcClientID + dstClientID
            
            ### Calculating the new Checksum via incremental update                
            newSum = _incr_check_s(newSum, oldStuff, newStuff)
             
            IPv4_pkt[12:20] = newIPv4_bytes            
            IPv4_pkt[10] = (newSum >> 8) & 0xFF
            IPv4_pkt[11] = newSum & 0xFF                
            
            
            if IPv4_pkt[9] == 0x6: #TCP Packet - Must recalculate checksum, otherwise the kernel will discard it
                ## Calculating new TCP Checksum through incremental Update - just because it uses a pseudo header...
                #tcpStartIndex = IPv4Hdr_len
                newSum = int.from_bytes(IPv4_pkt[IPv4Hdr_len+16:IPv4Hdr_len+18], 'big')
                newSum = _incr_check_s(newSum, oldStuff, newStuff)                    
                IPv4_pkt[IPv4Hdr_len+16] = (newSum >> 8) & 0xFF
                IPv4_pkt[IPv4Hdr_len+17] = newSum & 0xFF
            
            elif IPv4_pkt[9] == 0x11: 
                # UDP Packet -  Must recalculate checksum if different than zero. THIS IS NOT WORKING WELL!!!
                #  Since I'm unable to understand why the incremental update works for the IP and TCP header but fails for the UDP header, 
                # the checksum field will just be zeroed. # UDP checksum can be discarded
                IPv4_pkt[IPv4Hdr_len+6] = 0
                IPv4_pkt[IPv4Hdr_len+7] = 0
#                 udpStartIndex = IPv4Hdr_len
#                 udpCS = IPv4_pkt[udpStartIndex+6:udpStartIndex+8]
#                 if udpCS != b'\x00\x00':                                   
#                     ## Calculating new UDP Checksum through incremental Update - checksum field is != 0                                            
#                     newSum = _incr_check_s(int.from_bytes(udpCS, 'big'), oldStuff, newStuff)                    
#                     if newSum == 0:
#                         newSum = 0xFFFF                    
#                     IPv4_pkt[udpStartIndex+6] = (newSum >> 8) & 0xFF
#                     IPv4_pkt[udpStartIndex+7] = newSum & 0xFF                        
            
            
            _nameToInterfaceProp[interfaceName][0].send(archaNetPkt[0:archaNet_pkt_end]) 
            
            #pktBytes = archaNetPkt[0:archaNet_pkt_end].tobytes()
            #_nameToInterfaceQueue[interfaceName].put_nowait((10, id(pktBytes), pktBytes))                       
            return
        
        if EthType == b'\x86\xdd': #0x86DD: # IPv6 Protocol - Not Yet Implemented...            
            _TapLogger.debug("IPv6 not Implemented - Discarding Packet")   
            return                          
    
        _TapLogger.debug(str.format("Cannot Parse packet with type: {:d}", int.from_bytes(EthType, "big")))
        return                    
                
    except Exception:        
        LogCustomTraceBack(_TapLogger, logging.ERROR, *sys.exc_info())   
Пример #2
0
def _ReadFromInterface(interfaceName):    
    assert type(interfaceName) is str and len(interfaceName) > 0 and len(interfaceName) <= 16, str.format("interfaceName expected to be str with  len > 0 and len <= 16. Got {:s}", repr(interfaceName))
     
    try:
        (_, sckFD, interfaceMAC, buf, InterfaceLogger, _) = _nameToInterfaceProp[interfaceName]
        #recvBytesNum = sckFD.readinto(buf)
        sckFD.readinto(buf)
        #MacDst = EUI(int.from_bytes(buf[0:6].tobytes(), "big"))
        MacSrc = EUI(int.from_bytes(buf[6:12].tobytes(), "big"))
        #EthType = buf[12:14] 
        hasPathID = buf[14] & ARCHA_FLAG_PATHID
        #switchIDs_num = buf[15]
         
 
        ### IF there are still switches in the list. Fast Packet Switch        
        if buf[15]:
            archaHdr_len = ARCHANET_HEADER_MAX_SIZE if hasPathID else ARCHANET_HEADER_MIN_SIZE
            archaData_len = int.from_bytes(buf[48:50], 'big') if hasPathID else int.from_bytes(buf[32:34], 'big') 
                  
            nextSwitchPos = 14 + archaHdr_len + archaData_len + buf[15]-1                
            switchID = buf[nextSwitchPos]
            (isActive, interfaceName, interfaceMAC, dstMACaddr, _) = _DB.QuerySwitchIDInfo(switchID)
            if not isActive:
                InterfaceLogger.debug(str.format("Packet cannot be switched. Next Switch ({:d}) at buf position {:d} in line is not Active. Dropping Pkt.", switchID, nextSwitchPos))
                return

            buf[0:6] = dstMACaddr.packed
            buf[6:12] = interfaceMAC.packed
            buf[15] = buf[15] - 1
            
            
            _nameToInterfaceProp[interfaceName][0].send(buf[0:nextSwitchPos])
            #pktBytes = buf.tobytes()
            #_nameToInterfaceQueue[interfaceName].put_nowait((10, id(pktBytes), pktBytes))
            return
         
        ### If there is a PathID but there aren't any switch IDs left in the list. Route the packet.
        if hasPathID:
            #archaHdr_len = ARCHANET_HEADER_MAX_SIZE
            archaData_len = int.from_bytes(buf[48:50], 'big')
            pathID = bytes(buf[16:16+PATHID_HASH_WSIZE])
             
            (nextpathID, _, switchIDlist, _, _) = _DB.QueryPathID(pathID) ### We can perform a double verification on the Path MTU... but this may be useless...
            switchID = switchIDlist[0]
            (isActive, interfaceName, interfaceMAC, dstMACaddr, _) = _DB.QuerySwitchIDInfo(switchID)
            if not isActive:
                InterfaceLogger.debug(str.format("Packet cannot be routed. Next Switch ({:d}) in line is not Active. Dropping Pkt.", switchID))
                return
            
                      
            pktSwitchList = list(switchIDlist[1:])
            pktSwitchList.reverse()
            pktSwitchList_len = len(pktSwitchList)
            startSwIDlist_pos = 14 + ARCHANET_HEADER_MAX_SIZE + archaData_len # Because the packet has a pathID.
            
            if nextpathID:            
                buf[0:6] = dstMACaddr.packed
                buf[6:12] = interfaceMAC.packed
                buf[15] = pktSwitchList_len
                buf[16:16+PATHID_HASH_WSIZE] = nextpathID
                buf[startSwIDlist_pos:startSwIDlist_pos+pktSwitchList_len] = bytes(pktSwitchList)
                _nameToInterfaceProp[interfaceName][0].send(buf[0:startSwIDlist_pos+pktSwitchList_len])
                
                #pktBytes = buf[0:startSwIDlist_pos+pktSwitchList_len].tobytes()
                #_nameToInterfaceQueue[interfaceName].put_nowait((10, id(pktBytes), pktBytes))
            else:                
                buf[16:22] = dstMACaddr.packed
                buf[22:28] = interfaceMAC.packed
                buf[28] = 0xAA; buf[29] = 0xAA                
                buf[30] = buf[14] & ((~ARCHA_FLAG_PATHID)&0xFF) # Remember... its buf[14] because we are moving the bitflag field, since this packet will not have a pathID                
                buf[31] = pktSwitchList_len
                buf[startSwIDlist_pos:startSwIDlist_pos+pktSwitchList_len] = bytes(pktSwitchList)
                _nameToInterfaceProp[interfaceName][0].send(buf[16:startSwIDlist_pos+pktSwitchList_len])
                
                #pktBytes = buf[16:startSwIDlist_pos+pktSwitchList_len].tobytes()
                #_nameToInterfaceQueue[interfaceName].put_nowait((10, id(pktBytes), pktBytes))
            return
        
        ### No Switch IDs left and no Path ID, can only mean that it is meant for this peer.
        srcPeerUUID = UUID(bytes=bytes(buf[16:16+PATHID_HASH_WSIZE]))
        archaData_pos = 14 + ARCHANET_HEADER_MIN_SIZE                         
        archaData_len = int.from_bytes(buf[archaData_pos-4:archaData_pos-2], 'big')        
        archaData = buf[archaData_pos:archaData_pos+archaData_len]
        
         
        if archaData_len < 6:
            InterfaceLogger.debug(str.format("Control Packet sent from {:s} has an invalid size (length {:d}). Discarding packet.", str(srcPeerUUID), archaData_len))
            return
         
        # If the Packet is a control packet, send it to Cognition         
        if buf[14] & ARCHA_FLAG_CONTROL:            
            # First thing to do is to validate the control data.
            eventType = int.from_bytes(archaData[0:2], 'big')            
            if eventType not in _acceptedControlTypes:
                InterfaceLogger.debug(str.format("Control Packet sent from {:s} contains an invalid Control Message Type ({:d}). Only {:s} can be accepted through Layer 2. Discarding packet.",  
                                                 str(srcPeerUUID), eventType, str(_acceptedControlTypes)))
                return
            
            control_crc32 = int.from_bytes(archaData[-4:], 'big')            
            current_crc32_val = zlib.crc32(archaData[0:-4], 0)            
            if control_crc32 != current_crc32_val:
                InterfaceLogger.debug(str.format("Control Packet sent from {:s} failed CRC32 check. Got {:s} when it should be {:s}. Discarding packet.", \
                                                 str(srcPeerUUID), byteStr2HexStr(current_crc32_val.to_bytes(4, 'big')), byteStr2HexStr(control_crc32.to_bytes(4, 'big'))))
                return 
            
            if eventType == L2_CONTROL_PONG:
                pingID = int.from_bytes(archaData[2:6].tobytes(), byteorder='big')
                if pingID in _pingPeerFutures:                      
                    if not _pingPeerFutures[pingID].done():  
                        _pingPeerFutures[pingID].set_result(True)
                    del _pingPeerFutures[pingID]
                return
            
            # If CRC checks out, send it to cognition.
            _eventQueue.put_nowait((eventType, interfaceName, srcPeerUUID, MacSrc, archaData[2:-4].tobytes()))
            return                    

 
        # If the Packet is a data packet, egress it to TAP Device        
        #archaData_type = buf[34:36].tobytes()
        if buf[34:36] == b'\x08\x00': ## IPv4 Packet
            newPkt = buf[ARCHANET_HEADER_MIN_SIZE:archaData_pos+archaData_len]
            IPv4PacketPayload = buf[archaData_pos:archaData_pos+archaData_len]            
            IPv4Hdr_len = (IPv4PacketPayload[0] & 0x0F) * 4
            
                         
            srcClientID = int.from_bytes(IPv4PacketPayload[12:16], 'big')  
            dstClientID = int.from_bytes(IPv4PacketPayload[16:20], 'big')             
             
            src_protocols = _DB.QueryDNSTranslation(srcPeerUUID, srcClientID)
            if not src_protocols:
                InterfaceLogger.debug(str.format("Received Packet from peer {:s} with client ID {:d} but no registration was found. Discarding Packet.", str(srcPeerUUID), srcClientID))
                return
             
            dst_protocols = _DB.QueryDNSTranslation(_systemUUID, dstClientID)
            if not dst_protocols:
                InterfaceLogger.debug(str.format("Received Packet to Local Client ID {:d} but no registration was found for the local client. Discarding Packet.", dstClientID))
                return
             
            (srcMAC, srcIPv4, _) = src_protocols
            (dstMAC, dstIPv4, _) = dst_protocols

            newPkt[0:6] = dstMAC.packed
            newPkt[6:12] = srcMAC.packed
             
            newIPv4_bytes = srcIPv4.packed + dstIPv4.packed
             
            #newSum = (IPv4PacketPayload[10] << 8) + IPv4PacketPayload[11] # The newSum here initialized, is actually the oldSum (C)
            newSum = int.from_bytes(IPv4PacketPayload[10:12], 'big')
            ### We get the old values
            oldStuff = sum((int.from_bytes(IPv4PacketPayload[12:14], 'big'),
                            int.from_bytes(IPv4PacketPayload[14:16], 'big'),
                            int.from_bytes(IPv4PacketPayload[16:18], 'big'),
                            int.from_bytes(IPv4PacketPayload[18:20], 'big'),
                           ))
            ### Prepare the new ones
            newStuff = int(srcIPv4) + int(dstIPv4)
            
            ### Calculating the new Checksum via incremental update
            newSum = _incr_check_s(newSum, oldStuff, newStuff)
              
            IPv4PacketPayload[12:20] = newIPv4_bytes            
            IPv4PacketPayload[10] = (newSum >> 8) & 0xFF
            IPv4PacketPayload[11] = newSum & 0xFF                
             
             
            if IPv4PacketPayload[9] == 0x6: #TCP Packet - Must recalculate checksum, otherwise the kernel will discard it
                #tcpStartIndex = IPv4Hdr_len                 
                ## Calculating new TCP Checksum through incremental Update - just because it uses a pseudo header...
                newSum = (IPv4PacketPayload[IPv4Hdr_len+16] << 8) + IPv4PacketPayload[IPv4Hdr_len+17]
                newSum = _incr_check_s(newSum, oldStuff, newStuff)                    
                IPv4PacketPayload[IPv4Hdr_len+16] = (newSum >> 8) & 0xFF
                IPv4PacketPayload[IPv4Hdr_len+17] = newSum & 0xFF
             
            elif IPv4PacketPayload[9] == 0x11: # UDP Packet -  Must recalculate checksum if different than zero. THIS IS NOT WORKING WELL!!!
                # UDP Packet -  Must recalculate checksum if different than zero. THIS IS NOT WORKING WELL!!!
                #  Since I'm unable to understand why the incremental update works for the IP and TCP header but fails for the UDP header, 
                # the checksum field will just be zeroed. # UDP checksum can be discarded
                IPv4PacketPayload[IPv4Hdr_len+6] = 0
                IPv4PacketPayload[IPv4Hdr_len+7] = 0
#                 udpStartIndex = IPv4Hdr_len
#                 udpCS = IPv4PacketPayload[udpStartIndex+6:udpStartIndex+8]
#                 if udpCS != b'\x00\x00':                                   
#                     ## Calculating new UDP Checksum through incremental Update - checksum field is != 0                                            
#                     newSum = _incr_check_s(int.from_bytes(udpCS, 'big'), oldStuff, newStuff)                    
#                     if newSum == 0:
#                         newSum = 0xFFFF                    
#                     IPv4PacketPayload[udpStartIndex+6] = (newSum >> 8) & 0xFF
#                     IPv4PacketPayload[udpStartIndex+7] = newSum & 0xFF                          
 
             
            _tapFD_write.write(newPkt)             
            return
         
        if buf[34:36] == b'\x86\xdd': # IPv6 Protocol - Not Yet Implemented...            
            InterfaceLogger.debug("IPv6 not Implemented - Discarding Packet")   
            return

    except Exception:
        LogCustomTraceBack(InterfaceLogger, logging.ERROR, *sys.exc_info())