# -*- Fundamental -*-
#
# (C) 2002 Michel Arboi <arboi@bigfoot.com>
# $Revision: 1.3.2.3 $

function register_service(port, proto)
{
  __k = string("Known/tcp/", port);
  set_kb_item(name: __k, value: proto);
  __k = string("Services/", proto);
  set_kb_item(name: __k, value: port);
  #display("register_service: port=", port, ", proto=", proto, "\n");
}

function known_service(port)
{
  __k = string("Known/tcp/", port);
  __p = get_kb_item(__k);
  #if (__p) { display("Known service on port ", port, "\n"); }
  #else { display("Unknown service on port ", port, "\n"); }
  return (__p);
}

function get_unknown_banner(port)
{
  __sb = string("unknown/banner/", port);
  __banner = get_kb_item(__sb);
  if (__banner) return(__banner);

  if (! get_port_state(port)) return (0);
  __soc = open_sock_tcp(port);
  if(!__soc) return (0);
  # I don't think that it makes sense to send an HTTP request
  #__req = http_head(item:"/", port:port);
  #send(socket:__soc, data:__req);
  __banner = recv(socket:__soc, length:2048);
  close(__soc);
  set_kb_item(name: __sb, value: __banner);
  return(__banner);
}


#
# Fast replacement for getrpcport()
#
function get_rpc_port(program, protocol)
{ 
 __a = rand() % 255;
 __b = rand() % 255;
 __c = rand() % 255;
 __d = rand() % 255;
 
 __p_a = program / 16777216; 	__p_a = __p_a % 256;
 __p_b = program / 65356; 	__p_b = __p_b % 256;

 __broken = get_kb_item("/tmp/rpc/noportmap");
 if(__broken)return(0);
 
 __p_c = program / 256;   	__p_c = __p_c % 256;
 __p_d = program % 256;

 __pt_a = protocol / 16777216; __pt_a = __pt_a % 256;
 __pt_b = protocol / 65535   ; __pt_b = __pt_b % 256;
 __pt_c = protocol / 256;    ; __pt_c = __pt_c % 256;
 __pt_d = protocol % 256;
 
 
 __req = raw_string(__a, 	__b, 	__c, 	__d, 	# XID
 		  0x00, 0x00, 0x00, 0x00,	# Msg type: call
		  0x00, 0x00, 0x00, 0x02,	# RPC Version
		  0x00, 0x01, 0x86, 0xA0,	# Program
		  0x00, 0x00, 0x00, 0x02,	# Program version
		  0x00, 0x00, 0x00, 0x03,	# Procedure
		  0x00, 0x00, 0x00, 0x00,	# Credentials - flavor
		  0x00, 0x00, 0x00, 0x00, 	# Credentials - length
		  0x00, 0x00, 0x00, 0x00,	# Verifier - Flavor
		  0x00, 0x00, 0x00, 0x00,	# Verifier - Length
		  
		  __p_a,  __p_b,  __p_c,  __p_d,	# Program
		  0xFF, 0xFF, 0xFF, 0xFF,	# Version (any)
		  __pt_a, __pt_b, __pt_c, __pt_d,	# Proto (udp)
		  0x00, 0x00, 0x00, 0x00	# Port
 		  );
	
	  
 __soc = open_sock_udp(111);
 send(socket:__soc, data:__req);
 __r = recv(socket:__soc, min:24, length:28);
 close(__soc);
  if(!__r)
 {
  set_kb_item(name:"/tmp/rpc/noportmap", value:TRUE);
  return(0);
 }
 if(strlen(__r) < 28)
  return(0);
 else
  {
   __p_d = ord(__r[27]);
   __p_c = ord(__r[26]);
 
   __p_b = ord(__r[25]);

 
   __p_a = ord(__r[24]);
   __port = __p_a;
   __port = __port * 256;
   __port = __port +__ p_b; __port = __port * 256;
   __port = __port + __p_c; __port = __port * 256;
   __port = __port + __p_d;
   return(__port);
  }
}

