#!/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 import pickle # For pickling data def addhost(host): # We check for the validity of a host. if host[1] == 0: return(1)# Port is 0 if host[0][0:3] == '10.': return(1)# Private IP if host[0][0:3] == '192': return(1)# Private IP if host[0][0:2] == '0.': return(1)# Reserved IP if host[0][0:2] == '1.': return(1)# Reserved IP if host[0][0:2] == '2.': return(1)# Reserved IP if string.split(host[0], '.')[3] == '0': return(1)# Invalid IP if string.find(host[0], '255') != -1: return(1)# Broadcast IP if string.find(hosts, host[0]) == -1: hosts.append(host) 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` # diagnostic 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."#diagnostic 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."#diagnostic sys.exit(1)# barf if countersign bad print "Connected to "+HOST+':'+str(PORT)+"."# diagnostic return() # done, go home def processheader(header): ipaddress = '' port = 0 payload = '' payloadlength = processheaderpayload(header[19:23]) if header[16] == '\001': # header signifies pong 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)+"." # Diagnostic hosts.append([ipaddress, 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`# diagnostic 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. for i in range(4): sendping() # Send a ping out. packets = 0 for j in range(256): # main loop header = s.recv(23)#The first 23 bytes are always header print "got: "+`header`# diagnostic processheader(header) # process the header packets = packets + 1 #time.sleep(1)# sleep *snore* f = open("hosts", "w") pickle.dump(hosts, f) f.close() s.close() # Close it up s = socket(AF_INET, SOCK_STREAM)# Make a socket hosts = [] main() # Run the program # EOF