#!/usr/bin/env python # Pytella, a Gnutella servant written in Python, Copyright (C) 2000 Tom Goulet # This program is protected under the terms of the GNU General Public # License version 2, see the file COPYING in this directory. # Stuff we need. import sys # For argv[] and exit() from socket import * # Socket stuff import time # for sleeping import whrandom # Random stuff def sendping(): # Send a ping out guid = '' # random identifier flag = '\000' # ping ttl = '\004' # default ttl of 4 hops = '\000' # default hops of 0 payloadsize = '\000\000\000\000' # pings have precisely 0 payload for i in range(16): guid = guid + chr(whrandom.randint(0, 255)) # Generated random GUID. sendstring = guid + flag + ttl + hops + payloadsize # make a sendstring s.send(sendstring) # send it print "Sent ping:", `sendstring` return() # Done, now. def processpong(payload): # Process a pong port = 0 # port is an integer ipaddress = '' # ipaddress is a string port = ord(payload[0]) + ord(payload[1]) * 256 # sucking the port out of the payload ipaddress = str(ord(payload[2])) + "." + str(ord(payload[3])) + "." + str(ord(payload[4])) + "." + str(ord(payload[5])) # sucking the ip address out of the payload # print "Pong processed." return(ipaddress, port) # bring home the bacon def connect(HOST, PORT): # connect to a gnutellanet node s.connect(HOST, PORT) # connect socket s.send('GNUTELLA CONNECT/0.4\n\n') # handshake string if s.recv(64) != 'GNUTELLA OK\n\n': # countersign print "Connection failed, exiting." sys.exit(1)# barf if countersign bad print "Connected to "+HOST+':'+str(PORT)+"." return() # done, go home def processheader(header): ipaddress = '' port = 0 payload = '' payloadlength = processheaderpayload(header[19:23]) if header[16] == '\001': # header signifies pong print "Pong header: ", `header` payload = s.recv(payloadlength) # try to receive what the header says ipaddress, port = processpong(payload) # Process the pong. # print "Got Pong", `payload`, "Pong shows host at "+ipaddress+":"+str(port)+"." elif header[16] == '\000': # print "Got a ping. Don't care." payload = s.recv(payloadlength) # print "Ping payload: "+`payload` else: # print "Got some packet. Don't care." payload = s.recv(payloadlength) # print "Unkown payload: "+`payload` return() # return happily def processheaderpayload(headerpayload): #takes bytes 19 to 22 from the header # print "Header length bytes: "+`headerpayload` pll = 0 # I've broken this up into a bunch of lines so it'll look nicer pll = pll + ord(headerpayload[0]) # least significant pll = pll + ord(headerpayload[1]) * 256 pll = pll + ord(headerpayload[2]) * 65536 pll = pll + ord(headerpayload[3]) * 16777216 # most significant # print "payloadlength is: "+`pll` return(pll) # returns payload length according to header def main(): # s = socket(AF_INET, SOCK_STREAM)# Make a socket # This should move to command line parameters, and then to reading from a file. HOST = '192.168.0.254' # Host to connect to PORT = 6346 # Port to connect to connect(HOST, PORT) # Connect to a gnutellanet node. sendping() # Send a ping out. while 1: # main loop header = s.recv(23) # The first 23 bytes are always header # print "got: "+`header`# diagnostic processheader(header) # process the header # time.sleep(1) # sleep *snore* s.close() # Close it up s = socket(AF_INET, SOCK_STREAM)# Make a socket main() # Run the program # EOF