/** @see org.jnode.driver.net.spi.AbstractNetDriver#doTransmit(SocketBuffer, HardwareAddress) */ protected void doTransmitEthernet(SocketBuffer skbuf, HardwareAddress destination) throws NetworkException { try { // Pad if (skbuf.getSize() < ETH_ZLEN) { skbuf.append(ETH_ZLEN - skbuf.getSize()); } abstractDeviceCore.transmit(skbuf, destination, TRANSMIT_TIMEOUT); } catch (InterruptedException ex) { throw new NetworkException("Interrupted", ex); } catch (TimeoutException ex) { throw new NetworkException("Timeout", ex); } }
/** @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()); }
/** Initialize this ring to its default (empty) state */ public void initialize(SocketBuffer src) { // Setup the DPD // Copy the data from the buffer final int len = src.getSize(); if (len > EthernetConstants.ETH_FRAME_LEN) { throw new IllegalArgumentException("Length must be <= ETH_FRAME_LEN"); } src.get(data, firstDPDOffset, 0, len); }
/** * 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 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(); } }