/** * Process a packet that has been received and matches getType() * * @param skbuf * @param deviceAPI * @throws SocketException */ public void receive(SocketBuffer skbuf, NetDeviceAPI deviceAPI) throws SocketException { // Update statistics stat.ipackets.inc(); // Get IP header final IPv4Header hdr = new IPv4Header(skbuf); if (!hdr.isChecksumOk()) { stat.badsum.inc(); return; } // Set the header object in the buffer-field skbuf.setNetworkLayerHeader(hdr); // Remove header from skbuf-data skbuf.pull(hdr.getLength()); // Trim the end of the message, to we have a valid length skbuf.trim(hdr.getDataLength()); // Now test if the size of the buffer equals the datalength in the // header, if now ignore the packet if (skbuf.getSize() < hdr.getDataLength()) { stat.badlen.inc(); return; } // Update the ARP cache for the source address updateARPCache(skbuf.getLinkLayerHeader().getSourceAddress(), hdr.getSourceAddress()); // Get my IP address final IPv4ProtocolAddressInfo myAddrInfo = (IPv4ProtocolAddressInfo) deviceAPI.getProtocolAddressInfo(getProtocolID()); if (myAddrInfo == null) { stat.nodevaddr.inc(); } // Should I process this packet, or is it for somebody else? final IPv4Address dstAddr = hdr.getDestination(); final boolean shouldProcess; if (myAddrInfo != null) { shouldProcess = myAddrInfo.contains(dstAddr); } else { // I don't have an IP address yet, if the linklayer says // it is for me, we'll process it, otherwise we'll drop it. shouldProcess = !skbuf.getLinkLayerHeader().getDestinationAddress().isBroadcast(); } if (!shouldProcess) { // log.debug("IPPacket not for me, ignoring (dst=" + dstAddr + ")"); return; } // Is it a fragment? if (hdr.isFragment()) { // Yes it is a fragment stat.fragments.inc(); deliverFragment(hdr, skbuf); } else { // It is a complete packet, find the protocol handler // and let it do the rest deliver(hdr, skbuf); } // Do a cleanup of the fragmentlist from time to time final long now = System.currentTimeMillis(); if ((now - lastFragmentCleanup) >= (IP_FRAGTIMEOUT * 2)) { removeDeadFragments(); } }
/** @see org.jnode.net.TransportLayer#receive(org.jnode.net.SocketBuffer) */ public void receive(SocketBuffer skbuf) throws SocketException { // Increment stats stat.ipackets.inc(); // Get the IP header final IPv4Header ipHdr = (IPv4Header) skbuf.getNetworkLayerHeader(); // Read the TCP header final TCPHeader hdr = new TCPHeader(skbuf); // Set the TCP header in the buffer-field skbuf.setTransportLayerHeader(hdr); // Remove the TCP header from the head of the buffer skbuf.pull(hdr.getLength()); // Trim the buffer up to the length in the TCP header skbuf.trim(hdr.getDataLength()); if (!hdr.isChecksumOk()) { if (DEBUG) { if (log.isDebugEnabled()) { log.debug("Receive: badsum: " + hdr); } } stat.badsum.inc(); } else { if (DEBUG) { if (log.isDebugEnabled()) { log.debug("Receive: " + hdr); } } // Find the corresponding control block final TCPControlBlock cb = (TCPControlBlock) controlBlocks.lookup( ipHdr.getSource(), hdr.getSrcPort(), ipHdr.getDestination(), hdr.getDstPort(), true); if (cb == null) { final boolean ack = hdr.isFlagAcknowledgeSet(); final boolean rst = hdr.isFlagResetSet(); stat.noport.inc(); // Port unreachable if (ack && rst) { // the source is also unreachable log.debug( "Dropping segment due to: connection refused as the source is also unreachable"); } else { processPortUnreachable(ipHdr, hdr); } } else { // Let the cb handle the receive cb.receive(hdr, skbuf); } } }