portlist.cc

来自「Ubuntu packages of security software。 相」· CC 代码 · 共 779 行 · 第 1/2 页

CC
779
字号
      free(port_list[proto]);    }  }}int PortList::addPort(u16 portno, u8 protocol, char *owner, int state) {  Port *current;  char msg[128];  int proto = INPROTO2PORTLISTPROTO(protocol);  assert(state < PORT_HIGHEST_STATE);  if ((state == PORT_OPEN && o.verbose) || (o.debugging > 1)) {    if (owner && *owner) {      Snprintf(msg, sizeof(msg), " (owner: %s)", owner);    } else msg[0] = '\0';        log_write(LOG_STDOUT, "Discovered %s port %hu/%s%s%s\n",	      statenum2str(state), portno, 	      proto2ascii(protocol), msg, idstr? idstr : "");    log_flush(LOG_STDOUT);  }  /* Make sure state is OK */  if (state != PORT_OPEN && state != PORT_CLOSED && state != PORT_FILTERED &&      state != PORT_UNFILTERED && state != PORT_OPENFILTERED &&       state != PORT_CLOSEDFILTERED)    fatal("%s: attempt to add port number %d with illegal state %d\n", __func__, portno, state);  assert(protocol!=IPPROTO_IP || portno<256);  current = getPortEntry(portno, protocol);  if (current) {    /* We must discount our statistics from the old values.  Also warn       if a complete duplicate */    if (o.debugging && current->state == state && (!owner || !*owner)) {      error("Duplicate port (%hu/%s)", portno, proto2ascii(protocol));    }     state_counts_proto[proto][current->state]--;  } else {    current = new Port();    current->portno = portno;    current->proto = protocol;    numports++;        setPortEntry(portno, protocol, current);  }    current->state = state;  state_counts_proto[proto][state]++;  if (owner && *owner) {    if (current->owner)      free(current->owner);    current->owner = strdup(owner);  }   if(state == PORT_FILTERED || state == PORT_OPENFILTERED)  	setStateReason(portno, protocol, ER_NORESPONSE, 0, 0);   return 0; /*success */}int PortList::removePort(u16 portno, u8 protocol) {  Port *answer = NULL;  log_write(LOG_PLAIN, "Removed %d\n", portno);  answer = getPortEntry(portno, protocol);  if (!answer)    return -1;  setPortEntry(portno, protocol, NULL);  if (o.verbose) {      log_write(LOG_STDOUT, "Deleting port %hu/%s, which we thought was %s\n",	      portno, proto2ascii(answer->proto),	      statenum2str(answer->state));    log_flush(LOG_STDOUT);  }      /* Discount statistics */  state_counts_proto[INPROTO2PORTLISTPROTO(protocol)][answer->state]--;  numports--;  delete answer;  return 0;}  /* Saves an identification string for the target containing these     ports (an IP address might be a good example, but set what you     want).  Only used when printing new port updates.  Optional.  A     copy is made. */void PortList::setIdStr(const char *id) {  int len = 0;  if (idstr) free(idstr);  if (!id) { idstr = NULL; return; }  len = strlen(id);  len += 5; // " on " + \0  idstr = (char *) safe_malloc(len);  Snprintf(idstr, len, " on %s", id);}int PortList::getStateCounts(int protocol, int state){  return(state_counts_proto[INPROTO2PORTLISTPROTO(protocol)][state]);}int PortList::getStateCounts(int state){  int sum=0, proto;  for(proto=0; proto < PORTLIST_PROTO_MAX; proto++)    sum += state_counts_proto[proto][state];  return(sum);}  /* A function for iterating through the ports.  Give NULL for the   first "afterthisport".  Then supply the most recent returned port   for each subsequent call.  When no more matching ports remain, NULL   will be returned.  To restrict returned ports to just one protocol,   specify IPPROTO_TCP or IPPROTO_UDP for allowed_protocol. A TCPANDUDP   for allowed_protocol matches either. A 0 for allowed_state matches    all possible states. This function returns ports in numeric   order from lowest to highest, except that if you ask for both TCP &   UDP, every TCP port will be returned before we start returning UDP   ports */Port *PortList::nextPort(Port *afterthisport, 			 int allowed_protocol, int allowed_state) {  int proto;  int mapped_pno;  Port *port;    if(afterthisport) {    proto = INPROTO2PORTLISTPROTO(afterthisport->proto);    assert(port_map[proto]!=NULL); // Hmm, it's not posible to handle port that doesn't have anything in map    assert(afterthisport->proto!=IPPROTO_IP || afterthisport->portno<256);    mapped_pno = port_map[proto][afterthisport->portno];    mapped_pno++; //  we're interested in next port after current  }else { // running for the first time    if(allowed_protocol == TCPANDUDP)	// if both protocols, then first search TCP      proto = INPROTO2PORTLISTPROTO(IPPROTO_TCP);    else      proto = INPROTO2PORTLISTPROTO(allowed_protocol);    mapped_pno = 0;  }    if(port_list[proto] != NULL) {    for(;mapped_pno < port_list_count[proto]; mapped_pno++) {      port = port_list[proto][mapped_pno];      if(port && (allowed_state==0 || port->state==allowed_state))        return(port);    }  }    /* if all protocols, than after TCP search UDP */  if(allowed_protocol == TCPANDUDP && proto == INPROTO2PORTLISTPROTO(IPPROTO_TCP))    return(nextPort(NULL, IPPROTO_UDP, allowed_state));    return(NULL); }      Port *PortList::getPortEntry(u16 portno, u8 protocol) {  int proto = INPROTO2PORTLISTPROTO(protocol);  int mapped_pno;  assert(protocol!=IPPROTO_IP || portno<256);  if(port_map[proto]==NULL || port_list[proto]==NULL)    fatal("%s(%i,%i): you're trying to access uninitialized protocol", __func__, portno, protocol);  mapped_pno = port_map[proto][portno];  assert(mapped_pno < port_list_count[proto]);  assert(mapped_pno >= 0);    /* The ugly hack: we allow only port 0 to be mapped to 0 position */  if(mapped_pno==0 && portno!=0) {    error("WARNING: %s(%i,%i): this port was not mapped", __func__, portno, protocol);    return(NULL);  }else    return(port_list[proto][mapped_pno]);}void PortList::setPortEntry(u16 portno, u8 protocol, Port *port) {  int proto = INPROTO2PORTLISTPROTO(protocol);  int mapped_pno;  assert(protocol!=IPPROTO_IP || portno<256);  if(port_map[proto]==NULL || port_list[proto]==NULL)    fatal("%s(%i,%i): you're trying to access uninitialized protocol", __func__, portno, protocol);  mapped_pno = port_map[proto][portno];  assert(mapped_pno < port_list_count[proto]);  assert(mapped_pno >= 0);    /* The ugly hack: we allow only port 0 to be mapped to 0 position */  if(mapped_pno==0 && portno!=0) {    error("WARNING: %s(%i,%i): this port was not mapped", __func__, portno, protocol);    return;  }    port_list[proto][mapped_pno] = port;}/* Just free memory used by PortList::port_map[]. Should be done somewhere  * before closing nmap. */void PortList::freePortMap(){  int proto;  for(proto=0; proto < PORTLIST_PROTO_MAX; proto++)    if(port_map[proto]){      free(port_map[proto]);      port_map[proto] = NULL;  }}  u16 *PortList::port_map[PORTLIST_PROTO_MAX];int PortList::port_list_count[PORTLIST_PROTO_MAX];/* This function must be runned before any PortList object is created. * It must be runned for every used protocol. The data in "ports"  * should be sorted. */void PortList::initializePortMap(int protocol, u16 *ports, int portcount) {  int i;  int unused_zero;	// aren't we using 0 port?  int ports_max = (protocol == IPPROTO_IP) ? 256 : 65536;  int proto = INPROTO2PORTLISTPROTO(protocol);    if(port_map[proto]!=NULL)    fatal("%s: portmap for protocol %i already initialized", __func__, protocol);  assert(port_list_count[proto]==0);    /* this memory will never be freed, but this is the way it has to be. */  port_map[proto] = (u16*) safe_zalloc(sizeof(u16)*ports_max);  /* Is zero port to be unused? */  if(portcount==0 || ports[0]!=0)    unused_zero = 1;  else    unused_zero = 0;    /* The ugly hack: if we don't use 0 port, than we need one more extra element. */  port_list_count[proto] = portcount + unused_zero;    for(i=0; i < portcount; i++) {    /* The ugly hack: if we don't use 0 port, than we must start counting from 1 */    port_map[proto][ports[i]] = i + unused_zero; // yes, this is the key line  }  /* So now port_map should have such structure (lets scan 2nd,4th and 6th port):   * 	port_map[0,0,1,0,2,0,3,...]	        <- indexes to port_list structure   * 	port_list[0,port_2,port_4,port_6]   * But if we scan 0, 2, and 4 port:   * 	port_map[0,0,1,0,2,...]		// yes, this 0 in first place isn't mistake   * 	port_list[port_0,port_2,port_4]    * And in both cases we scan three ports. Ugly, isn't it? :) */}  /* Cycles through the 0 or more "ignored" ports which should be   consolidated for Nmap output.  They are returned sorted by the   number of prots in the state, starting with the most common.  It   should first be called with PORT_UNKNOWN to obtain the most popular   ignored state (if any).  Then call with that state to get the next   most popular one.  Returns the state if there is one, but returns   PORT_UNKNOWN if there are no (more) states which qualify for   consolidation */int PortList::nextIgnoredState(int prevstate) {  int beststate = PORT_UNKNOWN;    for(int state=0; state < PORT_HIGHEST_STATE; state++) {    /* The state must be ignored */    if (!isIgnoredState(state))       continue;    /* We can't give the same state again ... */    if (state == prevstate) continue;    /* If a previous state was given, we must have fewer ports than       that one, or be tied but be a larger state number */    if (prevstate != PORT_UNKNOWN && 	(getStateCounts(state) > getStateCounts(prevstate) ||	 (getStateCounts(state) == getStateCounts(prevstate) && state <= prevstate)))      continue;    /* We only qualify if we have more ports than the current best */    if (beststate != PORT_UNKNOWN && getStateCounts(beststate) >= getStateCounts(state))      continue;    /* Yay!  We found the best state so far ... */    beststate = state;  }  return beststate;}/* Returns true if a state should be ignored (consolidated), false otherwise */bool PortList::isIgnoredState(int state) {  if (o.debugging > 2)    return false;  if (state == PORT_OPEN || state == PORT_UNKNOWN || state == PORT_TESTING ||      state == PORT_FRESH)    return false; /* Cannot be ignored */  /* If openonly, we always ignore states that don't at least have open     as a possibility. */  if (o.openOnly() && state != PORT_OPENFILTERED && state != PORT_UNFILTERED       && getStateCounts(state) > 0)    return true;  int max_per_state = 25; // Ignore states with more ports than this  /* We will show more ports when verbosity is requested */  if (o.verbose || o.debugging) {    if (o.ipprotscan)      max_per_state *= (o.verbose + 3 * o.debugging);    else      max_per_state *= (o.verbose + 20 * o.debugging);  }    if (getStateCounts(state) > max_per_state)    return true;  return false;}int PortList::numIgnoredStates() {  int numstates = 0;  for(int state=0; state < PORT_HIGHEST_STATE; state++) {    if (isIgnoredState(state))      numstates++;  }  return numstates;}int PortList::numIgnoredPorts() {  int numports = 0;  for(int state=0; state < PORT_HIGHEST_STATE; state++) {    if (isIgnoredState(state))      numports += getStateCounts(state);  }  return numports;}int PortList::setStateReason(u16 portno, u8 proto, reason_t reason, u8 ttl, u32 ip_addr) {    Port *answer = NULL;    if(!(answer = getPortEntry(portno, proto)))        	return -1;    if(reason > ER_MAX)        return -1;    /* set new reason and increment its count */    answer->reason.reason_id = reason;    answer->reason.ip_addr.s_addr = ip_addr;	answer->reason.ttl = ttl;    answer->reason.state = answer->state;    setPortEntry(portno, proto, answer);    return 0;}// Move some popular TCP ports to the beginning of the portlist, because// that can speed up certain scans.  You should have already done any port// randomization, this should prevent the ports from always coming out in the// same order.void random_port_cheat(u16 *ports, int portcount) {  int allportidx = 0;  int popportidx = 0;  int earlyreplidx = 0;  u16 pop_ports[] = { 21, 22, 23, 25, 53, 80, 113, 256, 389, 443, 554, 636, 1723, 3389 };  int num_pop_ports = sizeof(pop_ports) / sizeof(u16);  for(allportidx = 0; allportidx < portcount; allportidx++) {    // see if the currentport is a popular port    for(popportidx = 0; popportidx < num_pop_ports; popportidx++) {      if (ports[allportidx] == pop_ports[popportidx]) {	// This one is popular!  Swap it near to the beginning.	if (allportidx != earlyreplidx) {	  ports[allportidx] = ports[earlyreplidx];	  ports[earlyreplidx] = pop_ports[popportidx];	}	earlyreplidx++;	break;      }    }  }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?