001: /*
002: * Copyright (c) 2000 by Matt Welsh and The Regents of the University of
003: * California. All rights reserved.
004: *
005: * Permission to use, copy, modify, and distribute this software and its
006: * documentation for any purpose, without fee, and without written agreement is
007: * hereby granted, provided that the above copyright notice and the following
008: * two paragraphs appear in all copies of this software.
009: *
010: * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
011: * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
012: * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
013: * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
014: *
015: * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
016: * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
017: * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
018: * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
019: * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
020: *
021: * Author: Matt Welsh <mdw@cs.berkeley.edu>
022: *
023: */
024:
025: package seda.sandStorm.lib.Gnutella;
026:
027: import java.util.*;
028: import java.io.*;
029: import java.net.*;
030:
031: /**
032: * A Gnutella query packet.
033: */
034: public class GnutellaQueryPacket extends GnutellaPacket {
035:
036: private static final boolean DEBUG = false;
037:
038: int minspeed;
039: String searchterm;
040:
041: /**
042: * Create a query packet with the given payload. The payload should
043: * conform to the format specified by the Gnutella protocol.
044: */
045: public GnutellaQueryPacket(byte[] payload) {
046: super (GNUTELLA_FN_QUERY, payload);
047: parsePayload();
048: }
049:
050: /**
051: * Create a query packet with the given GUID, TTL, hops, and payload.
052: */
053: public GnutellaQueryPacket(GnutellaGUID guid, int ttl, int hops,
054: byte[] payload) {
055: super (guid, GNUTELLA_FN_QUERY, ttl, hops, payload);
056: parsePayload();
057: }
058:
059: /**
060: * Create a query packet with the given search term and minspeed.
061: */
062: public GnutellaQueryPacket(String searchterm, int minspeed) {
063: super (GNUTELLA_FN_QUERY, null);
064: this .minspeed = minspeed;
065: this .searchterm = searchterm;
066: }
067:
068: private void parsePayload() {
069: if ((payload == null) || (payload.length < 3)) {
070: // Technically this doesn't make sense, but lots of bogus packets
071: // are flying around out there
072: return;
073: }
074:
075: minspeed = readLEShort(payload, 0);
076: // Ignore null byte at end
077: // Strip off non-ASCII characters
078: if (payload.length > 3) {
079: for (int i = 2; i < payload.length - 3; i++) {
080: if ((payload[i] < 32) || (payload[i] > 126))
081: payload[i] = (byte) '?';
082: }
083: searchterm = new String(payload, 2, payload.length - 3);
084: } else {
085: searchterm = null;
086: }
087: }
088:
089: protected void prepareForSend() {
090: if (searchterm != null) {
091: byte barr[] = searchterm.getBytes();
092: // Extra null at end
093: int payload_len = 2 + barr.length + 1;
094: payload = new byte[payload_len];
095: writeLEShort((short) minspeed & 0xffff, payload, 0);
096: System.arraycopy(barr, 0, payload, 2, barr.length);
097: payload[payload_len - 1] = 0;
098: } else {
099: // Just null char for search term
100: payload = new byte[3];
101: writeLEShort((short) minspeed & 0xffff, payload, 0);
102: payload[2] = 0;
103: }
104: }
105:
106: public String toString() {
107: return "GnutellaQueryPacket " + guid + " [" + searchterm + "]";
108: }
109:
110: public void debug(PrintStream out) {
111: out.println("GnutellaQueryPacket: " + searchterm + " (min "
112: + minspeed + " KB/sec)");
113: }
114:
115: /**
116: * Return the search term contained in this query packet.
117: */
118: public String getSearchTerm() {
119: return searchterm;
120: }
121:
122: /**
123: * Return the minimum speed requested by this query packet.
124: */
125: public int getMinSpeed() {
126: return minspeed;
127: }
128:
129: }
|