if (ss->numqueries_ideal < 1.0) ss->numqueries_ideal = 1.0;
if (o.debugging)
{
log_write(LOG_STDOUT, "Lost a packet, decreasing window to %d\n", (int) ss->numqueries_ideal);
}
}
}
if (current->state == PORT_TESTING)
ss->numqueries_outstanding--;
if (ntohl(rpc_pack->accept_stat) == PROG_UNAVAIL) {
current->state = PORT_CLOSED;
if (o.debugging > 1) {
error("Port %hu/%s claims that it is not RPC service %li", rsi->rpc_current_port->portno, (rsi->rpc_current_port->proto == IPPROTO_TCP)? "TCP" : "UDP", current->portno);
}
rsi->valid_responses_this_port++;
return 0;
} else if (ntohl(rpc_pack->accept_stat) == PROG_MISMATCH) {
if (o.debugging > 1) {
error("Port %hu/%s claims IT IS RPC service %li", rsi->rpc_current_port->portno, (rsi->rpc_current_port->proto == IPPROTO_TCP)? "TCP" : "UDP", current->portno);
}
current->state = PORT_OPEN;
rsi->rpc_status = RPC_STATUS_GOOD_PROG;
rsi->rpc_program = current->portno;
rsi->rpc_lowver = ntohl(rpc_pack->low_version);
rsi->rpc_highver = ntohl(rpc_pack->high_version);
rsi->valid_responses_this_port++;
ss->numqueries_outstanding = 0;
return 1;
} else if (ntohl(rpc_pack->accept_stat) == SUCCESS) {
error("Umm -- RPC returned success for bogus version -- thats OK I guess");
printf("Received UDP packet from %d.%d.%d.%d/%hu when expecting packet from %d.%d.%d.%d/%hu\n", NIPQUAD(from.sin_addr.s_addr), ntohs(from.sin_port), NIPQUAD(target->host.s_addr), rsi->rpc_current_port->portno);
} else if (tcp_rpc_socket >= 0 && FD_ISSET(tcp_rpc_socket, &fds_r)) {
do {
res = read(tcp_rpc_socket, readbuf + tcp_readlen, sizeof(readbuf) - tcp_readlen);
} while(res == -1 && errno == EINTR);
if (res <= 0) {
if (o.debugging) {
if (res == -1)
gh_perror("Failed to read() from tcp rpc socket in get_rpc_results");
else {
error("Lamer on port %li closed RPC socket on me in get_rpc_results", rsi->rpc_current_port->portno);
}
}
ss->numqueries_outstanding = 0;
rsi->rpc_status = RPC_STATUS_NOT_RPC;
return;
}
tcp_readlen += res;
if (tcp_readlen < 28) {
/* This is suspiciously small -- I'm assuming this is not the first
part of a valid RPC packet */
if (o.debugging > 1) {
printf("Port %hu/%s labelled NON_RPC because tcp_readlen is %d (should be at least 28)\n", rsi->rpc_current_port->portno, (rsi->rpc_current_port->proto == IPPROTO_TCP)? "TCP" : "UDP", tcp_readlen);
}
ss->numqueries_outstanding = 0;
rsi->rpc_status = RPC_STATUS_NOT_RPC;
return;
}
/* I'm ignoring the multiple msg fragment possibility for now */
current_msg_len = ntohl((*(unsigned long *)readbuf)) & 0x7FFFFFFF;
if (current_msg_len > tcp_readlen - 4) {
if (o.debugging > 1) {
printf("Port %hu/%s labelled NON_RPC because current_msg_len is %li while tcp_readlen is %d\n", rsi->rpc_current_port->portno, (rsi->rpc_current_port->proto == IPPROTO_TCP)? "TCP" : "UDP", current_msg_len, tcp_readlen);
}
ss->numqueries_outstanding = 0;
rsi->rpc_status = RPC_STATUS_NOT_RPC;
return;
}
current_msg = readbuf + 4;
do {
if (rpc_are_we_done(current_msg, current_msg_len, target, scan, ss,
pil, rsi) != 0)
return;
current_msg += current_msg_len;
if ((current_msg - readbuf) + 4UL < tcp_readlen) {
current_msg_len = ntohl(*(unsigned long *) current_msg) & 0x7FFFFFFF;
current_msg += 4;
} else {
if ((unsigned long) (current_msg - readbuf) < tcp_readlen) {
tcp_readlen -= current_msg - readbuf;
memmove(readbuf, current_msg, tcp_readlen);
} else tcp_readlen = 0;
break;
}
if (current_msg_len < 24 || current_msg_len > 32) {
ss->numqueries_outstanding = 0;
if (o.debugging > 1) {
printf("Port %hu/%s labelled NON_RPC because current_msg_len is %li\n", rsi->rpc_current_port->portno, (rsi->rpc_current_port->proto == IPPROTO_TCP)? "TCP" : "UDP", current_msg_len);
}
rsi->rpc_status = RPC_STATUS_NOT_RPC;
return;
}
if ((current_msg - readbuf) + current_msg_len > tcp_readlen) {
tcp_readlen -= current_msg - readbuf;
memmove(readbuf +4 , current_msg, tcp_readlen);
*(unsigned long *)&readbuf = htonl(current_msg_len);