/* * Made by Wannes 'W' De Smet * (c) 2011 Wannes De Smet * All rights reserved. * */ package org.apache.commons.net.tftp; import java.net.DatagramPacket; import java.net.InetAddress; import java.util.HashMap; import java.util.Map; /** * RFC 2347 / 2348 / 2349 * * Providing a more complete implementation for TFTPReadRequestPacket * * I make a huge effort not to shout at people abusing underscores. * I will however shout at people that do not make their libraries properly extendable. * If anything, this is way below the quality level an Apache Commons lib should have * * @created Oct 28, 2011 * @author double-u */ public final class TFTPOptionReadRequestPacket extends TFTPRequestPacket { protected HashMap<String, Integer> options; /*** * Creates a read request packet to be sent to a host at a * given port with a filename and transfer mode request. * <p> * @param destination The host to which the packet is going to be sent. * @param port The port to which the packet is going to be sent. * @param filename The requested filename. * @param mode The requested transfer mode. This should be on of the TFTP * class MODE constants (e.g., TFTP.NETASCII_MODE). ***/ public TFTPOptionReadRequestPacket(InetAddress destination, int port, String filename, int mode) { super(destination, port, TFTPPacket.READ_REQUEST, filename, mode); options = new HashMap<>(); } /*** * Creates a read request packet of based on a received * datagram and assumes the datagram has already been identified as a * read request. Assumes the datagram is at least length 4, else an * ArrayIndexOutOfBoundsException may be thrown. * <p> * @param datagram The datagram containing the received request. * @throws TFTPPacketException If the datagram isn't a valid TFTP * request packet. ***/ TFTPOptionReadRequestPacket(DatagramPacket datagram) throws TFTPPacketException { super(TFTPPacket.READ_REQUEST, datagram); options = new HashMap<>(); byte[] data = datagram.getData(); int index = 0, zeroCount = 0; boolean goAhead = false; for (int i = 0; i < data.length; i++) { if (data[i] == 0) { zeroCount++; } if (zeroCount == 2) { index = i + 2; } if (zeroCount == 3) { // We have ourselves a custom packet goAhead = true; break; } } if (!goAhead) { return; } while (index < data.length) { if (data[index + 1] == 0 && data[index + 2] == 0) { break; } // Check for option StringBuilder name = new StringBuilder(); for (int i = index; i < data.length; i++) { if (data[i] == 0) { index = i + 1; break; } name.append((char) data[i]); } if (options.containsKey(name.toString())) { break; } StringBuilder value = new StringBuilder(); for (int i = index; i < data.length; i++) { // Check if next byte isn't zero as well -- if it is, the current zero forms the value if (data[i] == 0) { index = i + 1; if (value.length() == 0) { value.append("0"); index++; } break; } value.append((char) data[i]); } try { options.put(name.toString(), Integer.parseInt(value.toString())); } catch (NumberFormatException ex) { // failz } } } public Map<String, Integer> getOptions() { return options; } }