/** @see java.net.DatagramSocketImpl#receive(java.net.DatagramPacket) */ protected void onReceive(DatagramPacket p, SocketBuffer skbuf) throws IOException { final IPv4Header ipHdr = (IPv4Header) skbuf.getNetworkLayerHeader(); final UDPHeader udpHdr = (UDPHeader) skbuf.getTransportLayerHeader(); p.setData(skbuf.toByteArray(), 0, skbuf.getSize()); p.setAddress(ipHdr.getSource().toInetAddress()); p.setPort(udpHdr.getSrcPort()); }
/** * Process a segment whose destination port is unreachable * * @param hdr */ private void processPortUnreachable(IPv4Header ipHdr, TCPHeader hdr) throws SocketException { final TCPHeader replyHdr = new TCPHeader(hdr.getDstPort(), hdr.getSrcPort(), 0, 0, hdr.getSequenceNr() + 1, 0, 0); replyHdr.setFlags(TCPF_ACK | TCPF_RST); final IPv4Header replyIpHdr = new IPv4Header(ipHdr); replyIpHdr.swapAddresses(); send(replyIpHdr, replyHdr, new SocketBuffer()); }
/** * Deliver a packet to the corresponding protocol * * @param hdr * @param skbuf */ private void deliver(IPv4Header hdr, SocketBuffer skbuf) throws SocketException { final IPv4Protocol protocol; try { protocol = getProtocol(hdr.getProtocol()); protocol.receive(skbuf); } catch (NoSuchProtocolException ex) { log.debug( "Found unknown IP src=" + hdr.getSource() + ", dst=" + hdr.getDestination() + ", prot=0x" + NumberUtils.hex(hdr.getProtocol(), 2)); } }
/** @see java.net.DatagramSocketImpl#send(java.net.DatagramPacket) */ protected void send(DatagramPacket p) throws IOException { final IPv4Address dstAddress = new IPv4Address(p.getAddress()); final IPv4Header ipHdr; ipHdr = new IPv4Header( getTos(), getTimeToLive(), IPPROTO_UDP, dstAddress, p.getLength() + UDP_HLEN); if (!getLocalAddress().isAnyLocalAddress() || (getDevice() != null)) { ipHdr.setSource(new IPv4Address(getLocalAddress())); } final UDPHeader udpHdr; final int srcPort = getLocalPort(); // final int srcPort = p.getPort(); // or getLocalPort???? TODO Fix // srcPort issue udpHdr = new UDPHeader(srcPort, p.getPort(), p.getLength()); final SocketBuffer skbuf = new SocketBuffer(p.getData(), p.getOffset(), p.getLength()); skbuf.setDevice(getDevice()); protocol.send(ipHdr, udpHdr, skbuf); }
/** * Send an TCP packet * * @param skbuf */ protected void send(IPv4Header ipHdr, TCPHeader tcpHdr, SocketBuffer skbuf) throws SocketException { if (DEBUG) { if (log.isDebugEnabled()) { log.debug("send(ipHdr, " + tcpHdr + ')'); } } skbuf.setTransportLayerHeader(tcpHdr); tcpHdr.prefixTo(skbuf); ipHdr.setDataLength(skbuf.getSize()); ipService.transmit(ipHdr, skbuf); stat.opackets.inc(); }
/** * Process the delivery of a fragment * * @param hdr * @param skbuf * @throws NetworkException */ private void deliverFragment(IPv4Header hdr, SocketBuffer skbuf) throws SocketException { final Object key = hdr.getFragmentListKey(); final IPv4FragmentList flist = (IPv4FragmentList) fragments.get(key); if (flist == null) { // This is a fragment for a new list fragments.put(key, new IPv4FragmentList(skbuf)); } else { if (flist.isAlive()) { flist.add(skbuf); if (flist.isComplete()) { // The fragmentlist is now complete, deliver it final SocketBuffer pbuf = flist.getPacket(); final IPv4Header phdr = (IPv4Header) pbuf.getNetworkLayerHeader(); stat.reassembled.inc(); deliver(phdr, pbuf); } } else { // Timeout of fragmentlist, destroy it fragments.remove(key); } } }
/** * 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); } } }