home *** CD-ROM | disk | FTP | other *** search
/ Steganos Hacker Tools / SHT151.iso / programme / scanner / nmapNTsp1 / Win_2000.exe / nmapNT-src / portlist.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-07-06  |  7.2 KB  |  236 lines

  1.  
  2.  
  3. #include "portlist.h"
  4. #include "error.h"
  5. #include "nmap.h"
  6. #ifndef WIN32
  7. #include <strings.h>
  8. #endif
  9. struct ops o;  /* option structure */
  10. static struct port *freeportlist = NULL;
  11.  
  12. /* gawd, my next project will be in c++ so I don't have to deal with
  13.    this crap ... simple linked list implementation */
  14. int addport(portlist *plist, unsigned short portno, unsigned short protocol,
  15.         char *owner, int state) {
  16.   struct port *current = NULL;
  17.   struct port **portarray = NULL;
  18.  
  19.   if (o.debugging > 1) {
  20.     error("addport: Adding port %hi/%s (owner: %s) in state %s",
  21.       portno, (protocol == IPPROTO_TCP)? "tcp" : "udp", (owner)? owner : "none", statenum2str(state));
  22.   }
  23.  
  24. /* Make sure state is OK */
  25.   if (state != PORT_OPEN && state != PORT_CLOSED && state != PORT_FIREWALLED &&
  26.       state != PORT_UNFIREWALLED)
  27.     fatal("addport: attempt to add port number %d with illegal state %d\n", portno, state);
  28.  
  29.   if (protocol == IPPROTO_TCP) {
  30.     if (!plist->tcp_ports) {
  31.       plist->tcp_ports = safe_malloc(65536 * sizeof(struct port *));
  32.       bzero(plist->tcp_ports, 65536 * sizeof(struct port *));
  33.     }
  34.     portarray = plist->tcp_ports;
  35.   } else if (protocol == IPPROTO_UDP) {
  36.     if (!plist->udp_ports) {
  37.       plist->udp_ports = safe_malloc(65536 * sizeof(struct port *));
  38.       bzero(plist->udp_ports, 65536 * sizeof(struct port *));
  39.     }
  40.     portarray = plist->udp_ports;
  41.   } else fatal("addport: attempted port insertion with invalid protocol");
  42.  
  43.   if (portarray[portno]) {
  44.     /* We must discount our statistics from the old values.  Also warn
  45.        if a complete duplicate */
  46.     current = portarray[portno];    
  47.     if (o.debugging && current->state == state && (!owner || !*owner)) {
  48.       error("Duplicate port (%hu/%s)\n", portno ,
  49.         (protocol == IPPROTO_TCP)? "tcp": "udp");
  50.     } 
  51.     plist->state_counts[current->state]--;
  52.     if (current->proto == IPPROTO_TCP) {
  53.       plist->state_counts_tcp[current->state]--;
  54.     } else {
  55.       plist->state_counts_udp[current->state]--;
  56.     }  
  57.   } else {
  58.     portarray[portno] = make_empty_port();
  59.     current = portarray[portno];
  60.     plist->numports++;
  61.     current->rpc_status = RPC_STATUS_UNTESTED;
  62.     current->confidence = CONF_HIGH;
  63.     current->portno = portno;
  64.   }
  65.   
  66.   plist->state_counts[state]++;
  67.   current->state = state;
  68.   if (protocol == IPPROTO_TCP) {
  69.     plist->state_counts_tcp[state]++;
  70.   } else {
  71.     plist->state_counts_udp[state]++;
  72.   }
  73.   current->proto = protocol;
  74.  
  75.   if (owner && *owner) {
  76.     if (current->owner)
  77.       free(current->owner);
  78.     current->owner = strdup(owner);
  79.   }
  80.  
  81.   return 0; /*success */
  82. }
  83.  
  84. int deleteport(portlist *plist, unsigned short portno,
  85.            unsigned short protocol) {
  86.   struct port *answer = NULL;
  87.  
  88.   if (protocol == IPPROTO_TCP && plist->tcp_ports) {
  89.    answer = plist->tcp_ports[portno];
  90.    plist->tcp_ports[portno] = NULL;
  91.   }
  92.  
  93.   if (protocol == IPPROTO_UDP && plist->udp_ports) {  
  94.     answer = plist->udp_ports[portno];
  95.     plist->udp_ports[portno] = NULL;
  96.   }
  97.  
  98.   if (!answer)
  99.     return -1;
  100.  
  101.   free_port(answer);
  102.   return 0;
  103. }
  104.  
  105.  
  106. struct port *lookupport(portlist *ports, unsigned short portno, unsigned short protocol) {
  107.  
  108.   if (protocol == IPPROTO_TCP && ports->tcp_ports)
  109.     return ports->tcp_ports[portno];
  110.  
  111.   if (protocol == IPPROTO_UDP && ports->udp_ports)
  112.     return ports->udp_ports[portno];
  113.   
  114.   return NULL;
  115. }
  116.  
  117.  
  118. /* RECYCLES the port so that it can later be obtained again using 
  119.    make_port_structure */
  120. void free_port(struct port *pt) {
  121.   struct port *tmp;
  122.   if (pt->owner)
  123.     free(pt->owner);
  124.   tmp = freeportlist;
  125.   freeportlist = pt;
  126.   pt->next = tmp;
  127. }
  128.  
  129. struct port *make_empty_port() {
  130. int i;
  131. struct port *newpt;
  132.  
  133.  if (!freeportlist) {
  134.    freeportlist = safe_malloc(sizeof(struct port) * 1024);
  135.    for(i=0; i < 1023; i++)
  136.      freeportlist[i].next = &freeportlist[i+1];
  137.    freeportlist[1023].next = NULL;
  138.  }
  139.  
  140.  newpt = freeportlist;
  141.  freeportlist = freeportlist->next;
  142.  bzero(newpt, sizeof(struct port));
  143.  return newpt;
  144. }
  145.  
  146. /* Empties out a portlist so that it can be reused (or freed).  All the 
  147.    internal structures that must be freed are done so here. */
  148. void resetportlist(portlist *plist) {
  149.   int i;
  150.   if (plist->tcp_ports) {  
  151.     for(i=0; i < 65536; i++) {
  152.       if (plist->tcp_ports[i])
  153.     free_port(plist->tcp_ports[i]);
  154.     }
  155.     free(plist->tcp_ports);
  156.   }
  157.  
  158.   if (plist->udp_ports) {  
  159.     for(i=0; i < 65536; i++) {
  160.       if (plist->udp_ports[i])
  161.     free_port(plist->udp_ports[i]);
  162.     }
  163.     free(plist->udp_ports);
  164.   }
  165.   bzero(plist, sizeof(portlist));
  166. }
  167.  
  168.  
  169. /* Decide which port we want to ignore in output (for example, we don't want
  170.  to show closed ports if there are 40,000 of them.) */
  171. void assignignoredportstate(portlist *plist) {
  172.  
  173.   if (plist->state_counts[PORT_FIREWALLED] > 10 + 
  174.       MAX(plist->state_counts[PORT_UNFIREWALLED], 
  175.       plist->state_counts[PORT_CLOSED])) {
  176.     plist->ignored_port_state = PORT_FIREWALLED;
  177.   } else if (plist->state_counts[PORT_UNFIREWALLED] > 
  178.          plist->state_counts[PORT_CLOSED]) {
  179.     plist->ignored_port_state = PORT_UNFIREWALLED;
  180.   } else plist->ignored_port_state = PORT_CLOSED;
  181. }
  182.  
  183.  
  184.  
  185. /* A function for iterating through the ports.  Give NULL for the
  186.    first "afterthisport".  Then supply the most recent returned port
  187.    for each subsequent call.  When no more matching ports remain, NULL
  188.    will be returned.  To restrict returned ports to just one protocol,
  189.    specify IPPROTO_TCP or IPPROTO_UDP for allowed_protocol.  A 0 for
  190.    allowed_protocol matches either.  allowed_state works in the same
  191.    fashion as allowed_protocol. This function returns ports in numeric
  192.    order from lowest to highest, except that if you ask for both TCP &
  193.    UDP, every TCP port will be returned before we start returning UDP
  194.    ports */
  195.  
  196. struct port *nextport(portlist *plist, struct port *afterthisport, 
  197.               int allowed_protocol, int allowed_state) {
  198.  
  199.   /* These two are chosen because they come right "before" port 1/tcp */
  200. unsigned int current_portno = 0;
  201. unsigned int current_proto = IPPROTO_TCP;
  202.  
  203. if (afterthisport) {
  204.   current_portno = afterthisport->portno;
  205.   current_proto = afterthisport->proto;  /* (afterthisport->proto == IPPROTO_TCP)? IPPROTO_TCP : IPPROTO_UDP; */
  206.  
  207.  current_portno++; /* Start on the port after the one we were given */
  208.  
  209. /* First we look for TCP ports ... */
  210. if ((allowed_protocol == 0 || allowed_protocol == IPPROTO_TCP) && 
  211.     current_proto == IPPROTO_TCP && plist->tcp_ports) {
  212.   for(; current_portno < 65536; current_portno++) {
  213.     if (plist->tcp_ports[current_portno] &&
  214.     (!allowed_state || plist->tcp_ports[current_portno]->state == allowed_state))
  215.       return plist->tcp_ports[current_portno];
  216.   }
  217.   /*  Uh-oh.  We have tried all tcp ports, lets move to udp */
  218.   current_portno = 0;
  219.   current_proto = IPPROTO_UDP;
  220. }
  221.  
  222. if ((allowed_protocol == 0 || allowed_protocol == IPPROTO_UDP) && 
  223.     current_proto == IPPROTO_UDP && plist->udp_ports) {
  224.   for(; current_portno < 65536; current_portno++) {
  225.     if (plist->udp_ports[current_portno] &&
  226.     (!allowed_state || plist->udp_ports[current_portno]->state == allowed_state))
  227.       return plist->udp_ports[current_portno];
  228.   }
  229. }
  230.  
  231. /*  No more ports */
  232. return NULL;
  233. }
  234.  
  235.