1 /***************************************************************************
2  * portlist.cc -- Functions for manipulating various lists of ports        *
3  * maintained internally by Nmap.                                          *
4  *                                                                         *
5  ***********************IMPORTANT NMAP LICENSE TERMS************************
6  *                                                                         *
7  * The Nmap Security Scanner is (C) 1996-2020 Insecure.Com LLC ("The Nmap  *
8  * Project"). Nmap is also a registered trademark of the Nmap Project.     *
9  *                                                                         *
10  * This program is distributed under the terms of the Nmap Public Source   *
11  * License (NPSL). The exact license text applying to a particular Nmap    *
12  * release or source code control revision is contained in the LICENSE     *
13  * file distributed with that version of Nmap or source code control       *
14  * revision. More Nmap copyright/legal information is available from       *
15  * https://nmap.org/book/man-legal.html, and further information on the    *
16  * NPSL license itself can be found at https://nmap.org/npsl. This header  *
17  * summarizes some key points from the Nmap license, but is no substitute  *
18  * for the actual license text.                                            *
19  *                                                                         *
20  * Nmap is generally free for end users to download and use themselves,    *
21  * including commercial use. It is available from https://nmap.org.        *
22  *                                                                         *
23  * The Nmap license generally prohibits companies from using and           *
24  * redistributing Nmap in commercial products, but we sell a special Nmap  *
25  * OEM Edition with a more permissive license and special features for     *
26  * this purpose. See https://nmap.org/oem                                  *
27  *                                                                         *
28  * If you have received a written Nmap license agreement or contract       *
29  * stating terms other than these (such as an Nmap OEM license), you may   *
30  * choose to use and redistribute Nmap under those terms instead.          *
31  *                                                                         *
32  * The official Nmap Windows builds include the Npcap software             *
33  * (https://npcap.org) for packet capture and transmission. It is under    *
34  * separate license terms which forbid redistribution without special      *
35  * permission. So the official Nmap Windows builds may not be              *
36  * redistributed without special permission (such as an Nmap OEM           *
37  * license).                                                               *
38  *                                                                         *
39  * Source is provided to this software because we believe users have a     *
40  * right to know exactly what a program is going to do before they run it. *
41  * This also allows you to audit the software for security holes.          *
42  *                                                                         *
43  * Source code also allows you to port Nmap to new platforms, fix bugs,    *
44  * and add new features.  You are highly encouraged to submit your         *
45  * changes as a Github PR or by email to the dev@nmap.org mailing list     *
46  * for possible incorporation into the main distribution. Unless you       *
47  * specify otherwise, it is understood that you are offering us very       *
48  * broad rights to use your submissions as described in the Nmap Public    *
49  * Source License Contributor Agreement. This is important because we      *
50  * fund the project by selling licenses with various terms, and also       *
51  * because the inability to relicense code has caused devastating          *
52  * problems for other Free Software projects (such as KDE and NASM).       *
53  *                                                                         *
54  * The free version of Nmap is distributed in the hope that it will be     *
55  * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of  *
56  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Warranties,        *
57  * indemnification and commercial support are all available through the    *
58  * Npcap OEM program--see https://nmap.org/oem.                            *
59  *                                                                         *
60  ***************************************************************************/
61 
62 /* $Id: portlist.cc 38078 2020-10-02 16:12:22Z dmiller $ */
63 
64 
65 #include "nmap.h"
66 #include "portlist.h"
67 #include "nmap_error.h"
68 #include "NmapOps.h"
69 #include "services.h"
70 #include "protocols.h"
71 #include "tcpip.h"
72 #include "libnetutil/netutil.h"
73 
74 #if HAVE_STRINGS_H
75 #include <strings.h>
76 #endif /* HAVE_STRINGS_H */
77 
78 extern NmapOps o;  /* option structure */
79 
Port()80 Port::Port() {
81   portno = proto = 0;
82   state = 0;
83   service = NULL;
84   state_reason_init(&reason);
85 }
86 
freeService(bool del_service)87 void Port::freeService(bool del_service) {
88   if (service != NULL) {
89     std::vector<char *>::iterator it;
90 
91     if (service->name)
92       free(service->name);
93     if (service->product)
94       free(service->product);
95     if (service->version)
96       free(service->version);
97     if (service->extrainfo)
98       free(service->extrainfo);
99     if (service->hostname)
100       free(service->hostname);
101     if (service->ostype)
102       free(service->ostype);
103     if (service->devicetype)
104       free(service->devicetype);
105     if (service->service_fp)
106       free(service->service_fp);
107     for (it = service->cpe.begin(); it != service->cpe.end(); it++)
108       free(*it);
109     service->cpe.clear();
110 
111     if (del_service)
112       delete service;
113   }
114 }
115 
freeScriptResults(void)116 void Port::freeScriptResults(void)
117 {
118 #ifndef NOLUA
119   while (!scriptResults.empty()) {
120     scriptResults.front().clear();
121     scriptResults.pop_front();
122   }
123 #endif
124 }
125 
126 /* Fills in namebuf (as long as there is space in buflen) with the
127    Name nmap normal output will use to describe the port.  This takes
128    into account to confidence level, any SSL tunneling, etc.  Truncates
129    namebuf to 0 length if there is no room.*/
getNmapServiceName(char * namebuf,int buflen) const130 void Port::getNmapServiceName(char *namebuf, int buflen) const {
131   const char *tunnel_prefix;
132   const char *service_name;
133   int len;
134 
135   if (service != NULL && service->service_tunnel == SERVICE_TUNNEL_SSL)
136     tunnel_prefix = "ssl/";
137   else
138     tunnel_prefix = "";
139 
140   if (service != NULL && service->name != NULL) {
141     service_name = service->name;
142   } else {
143     struct servent *service;
144 
145     service = nmap_getservbyport(portno, IPPROTO2STR(proto));
146     if (service != NULL)
147       service_name = service->s_name;
148     else
149       service_name = NULL;
150   }
151 
152   if (service_name != NULL && strcmp(service_name, "unknown") != 0) {
153     /* The port has a name and the name is not "unknown". How confident are we? */
154     if (o.servicescan && state == PORT_OPEN && (service == NULL || service->name_confidence <= 5))
155       len = Snprintf(namebuf, buflen, "%s%s?", tunnel_prefix, service_name);
156     else
157       len = Snprintf(namebuf, buflen, "%s%s", tunnel_prefix, service_name);
158   } else {
159     len = Snprintf(namebuf, buflen, "%sunknown", tunnel_prefix);
160   }
161   if (len >= buflen || len < 0) {
162     namebuf[0] = '\0';
163     return;
164   }
165 
166 }
167 
serviceDeductions()168 serviceDeductions::serviceDeductions() {
169   name = NULL;
170   name_confidence = 0;
171   product = NULL;
172   version = NULL;
173   extrainfo = NULL;
174   hostname = NULL;
175   ostype = NULL;
176   devicetype = NULL;
177   service_tunnel = SERVICE_TUNNEL_NONE;
178   service_fp = NULL;
179   dtype = SERVICE_DETECTION_TABLE;
180 }
181 
182 // Uses the sd->{product,version,extrainfo} if available to fill
183 // out sd->fullversion.  If unavailable, it will be set to zero length.
populateFullVersionString(char * buf,size_t n) const184 void serviceDeductions::populateFullVersionString(char *buf, size_t n) const {
185   char *dst = buf;
186   unsigned int spaceleft = n - 1; // Leave room for \0
187   int needpad = 0;  // Do we need to pad a space between the next template?
188 
189   dst[0] = '\0';
190 
191   /* Sometimes there is really great product/version/extra information
192    * available that won't quite fit.  Rather than just drop that information
193    * this routine will truncate the string that is too long with "...".
194    * If there are fewer than 8 characters left don't bother and just skip
195    * that bit of information.
196    */
197 
198   if (product && spaceleft >= 8) {
199     if (spaceleft < strlen(product)) {
200       strncat(dst, product, spaceleft - 3);  // Leave room for "..."
201       strncat(dst, "...", spaceleft);
202       spaceleft = 0;
203     }
204     else {
205       strncat(dst, product, spaceleft);
206       spaceleft -= strlen(product);
207     }
208     needpad = 1;
209   }
210 
211   if (version && spaceleft >= 8) {
212     if (needpad) {
213       strncat(dst, " ", spaceleft);
214       spaceleft--;
215     }
216 
217     if (spaceleft < strlen(version)) {
218       strncat(dst, version, spaceleft - 3);
219       strncat(dst, "...", spaceleft);
220       spaceleft = 0;
221     }
222     else {
223       strncat(dst, version, spaceleft);
224       spaceleft -= strlen(version);
225     }
226     needpad = 1;
227   }
228 
229   if (extrainfo && spaceleft >= 8) {
230     if (needpad) {
231       strncat(dst, " ", spaceleft);
232       spaceleft--;
233     }
234     // This time we need to truncate inside of the () so we have spaceleft - 2
235     strncat(dst, "(", spaceleft);
236     if (spaceleft - 2 < strlen(extrainfo)) {
237       strncat(dst, extrainfo, spaceleft - 5);
238       strncat(dst, "...", spaceleft - 2);
239       spaceleft = 1;  // Fit the paren
240     }
241     else {
242       strncat(dst, extrainfo, spaceleft);
243       spaceleft -= (strlen(extrainfo) + 2);
244     }
245     strncat(dst, ")", spaceleft);
246     spaceleft--;
247   }
248 
249 }
250 
251 
252 // pass in an allocated struct serviceDeductions (don't worry about
253 // initializing, and you don't have to free any internal ptrs.  See the
254 // serviceDeductions definition for the fields that are populated.
255 // Returns 0 if at least a name is available.
getServiceDeductions(u16 portno,int protocol,struct serviceDeductions * sd) const256 void PortList::getServiceDeductions(u16 portno, int protocol, struct serviceDeductions *sd) const {
257   const Port *port;
258 
259   port = lookupPort(portno, protocol);
260   if (port == NULL || port->service == NULL) {
261     struct servent *service;
262 
263     /* Look up the service name. */
264     *sd = serviceDeductions();
265     service = nmap_getservbyport(portno, IPPROTO2STR(protocol));
266     if (service != NULL)
267       sd->name = service->s_name;
268     else
269       sd->name = NULL;
270     sd->name_confidence = 3;
271   } else {
272     *sd = *port->service;
273   }
274 }
275 
276 
277 // sname should be NULL if sres is not
278 // PROBESTATE_FINISHED_MATCHED. product,version, and/or extrainfo
279 // will be NULL if unavailable. Note that this function makes its
280 // own copy of sname and product/version/extrainfo.  This function
281 // also takes care of truncating the version strings to a
282 // 'reasonable' length if necessary, and cleaning up any unprintable
283 // chars. (these tests are to avoid annoying DOS (or other) attacks
284 // by malicious services).  The fingerprint should be NULL unless
285 // one is available and the user should submit it.  tunnel must be
286 // SERVICE_TUNNEL_NULL (normal) or SERVICE_TUNNEL_SSL (means ssl was
287 // detected and we tried to tunnel through it ).
cstringSanityCheck(const char * string,int len)288 static char *cstringSanityCheck(const char* string, int len) {
289   char *result;
290   int slen;
291 
292   if(!string)
293           return NULL;
294 
295   slen = strlen(string);
296   if (slen > len) slen = len;
297   result = (char *) safe_malloc(slen + 1);
298   memcpy(result, string, slen);
299   result[slen] = '\0';
300   replacenonprintable(result, slen, '.');
301   return result;
302 }
303 
setServiceProbeResults(u16 portno,int protocol,enum serviceprobestate sres,const char * sname,enum service_tunnel_type tunnel,const char * product,const char * version,const char * extrainfo,const char * hostname,const char * ostype,const char * devicetype,const std::vector<const char * > * cpe,const char * fingerprint)304 void PortList::setServiceProbeResults(u16 portno, int protocol,
305   enum serviceprobestate sres, const char *sname,
306   enum service_tunnel_type tunnel, const char *product, const char *version,
307   const char *extrainfo, const char *hostname, const char *ostype,
308   const char *devicetype, const std::vector<const char *> *cpe,
309   const char *fingerprint) {
310   std::vector<char *>::iterator it;
311   Port *port;
312   char *p;
313 
314   port = createPort(portno, protocol);
315   if (port->service == NULL)
316     port->service = new serviceDeductions;
317 
318   if (sres == PROBESTATE_FINISHED_HARDMATCHED
319       || sres == PROBESTATE_FINISHED_SOFTMATCHED) {
320     port->service->dtype = SERVICE_DETECTION_PROBED;
321     port->service->name_confidence = 10;
322   } else if (sres == PROBESTATE_FINISHED_TCPWRAPPED) {
323     port->service->dtype = SERVICE_DETECTION_PROBED;
324     if (sname == NULL)
325       sname = "tcpwrapped";
326     port->service->name_confidence = 8;
327   } else {
328     /* PROBESTATE_FINISHED_NOMATCH, PROBESTATE_EXCLUDED, PROBESTATE_INCOMPLETE.
329        Just look up the service name if none is provided. */
330     if (sname == NULL) {
331       struct servent *service;
332       service = nmap_getservbyport(portno, IPPROTO2STR(protocol));
333       if (service != NULL)
334         sname = service->s_name;
335     }
336     port->service->dtype = SERVICE_DETECTION_TABLE;
337     port->service->name_confidence = 3;  // Since we didn't even check it, we aren't very confident
338   }
339 
340   // port->serviceprobe_results = sres;
341   port->service->service_tunnel = tunnel;
342 
343   port->freeService(false);
344 
345   if (sname)
346     port->service->name = strdup(sname);
347   else
348     port->service->name = NULL;
349 
350   if (fingerprint)
351     port->service->service_fp = strdup(fingerprint);
352   else
353     port->service->service_fp = NULL;
354 
355   port->service->product = cstringSanityCheck(product, 80);
356   port->service->version = cstringSanityCheck(version, 80);
357   port->service->extrainfo = cstringSanityCheck(extrainfo, 256);
358   port->service->hostname = cstringSanityCheck(hostname, 80);
359   port->service->ostype = cstringSanityCheck(ostype, 32);
360   port->service->devicetype = cstringSanityCheck(devicetype, 32);
361 
362   if (cpe) {
363     std::vector<const char *>::const_iterator cit;
364 
365     for (cit = cpe->begin(); cit != cpe->end(); cit++) {
366       p = cstringSanityCheck(*cit, 80);
367       if (p != NULL)
368         port->service->cpe.push_back(p);
369     }
370   }
371 }
372 
373 
374 #ifndef NOLUA
addScriptResult(u16 portno,int protocol,const ScriptResult & sr)375 void PortList::addScriptResult(u16 portno, int protocol, const ScriptResult& sr) {
376   Port *port;
377 
378   port = createPort(portno, protocol);
379 
380   port->scriptResults.push_back(sr);
381 }
382 #endif
383 
384 /*****************************************************************************/
385 /* Convert protocol name from in.h to enum portlist_proto.
386  * So IPPROTO_TCP will be changed to PORTLIST_PROTO_TCP and so on. */
387 #define INPROTO2PORTLISTPROTO(p)		\
388   ((p)==IPPROTO_TCP ? PORTLIST_PROTO_TCP :	\
389    (p)==IPPROTO_UDP ? PORTLIST_PROTO_UDP :	\
390    (p)==IPPROTO_SCTP ? PORTLIST_PROTO_SCTP :	\
391    PORTLIST_PROTO_IP)
392 
393 #define PORTLISTPROTO2INPROTO(p)		\
394   ((p)==PORTLIST_PROTO_TCP ? IPPROTO_TCP :	\
395    (p)==PORTLIST_PROTO_UDP ? IPPROTO_UDP :	\
396    (p)==PORTLIST_PROTO_SCTP ? IPPROTO_SCTP :	\
397    IPPROTO_IP)
398 
399 
PortList()400 PortList::PortList() {
401   int proto;
402   memset(state_counts_proto, 0, sizeof(state_counts_proto));
403   memset(port_list, 0, sizeof(port_list));
404 
405   for(proto=0; proto < PORTLIST_PROTO_MAX; proto++) {
406     if(port_list_count[proto] > 0)
407       port_list[proto] = (Port**) safe_zalloc(sizeof(Port*)*port_list_count[proto]);
408     default_port_state[proto].proto = PORTLISTPROTO2INPROTO(proto);
409     default_port_state[proto].reason.reason_id = ER_NORESPONSE;
410     state_counts_proto[proto][default_port_state[proto].state] = port_list_count[proto];
411   }
412 
413   numscriptresults = 0;
414   idstr = NULL;
415 }
416 
~PortList()417 PortList::~PortList() {
418   int proto, i;
419 
420   if (idstr) {
421     free(idstr);
422     idstr = NULL;
423   }
424 
425   for(proto=0; proto < PORTLIST_PROTO_MAX; proto++) { // for every protocol
426     if(port_list[proto]) {
427       for(i=0; i < port_list_count[proto]; i++) { // free every Port
428         if(port_list[proto][i]) {
429           port_list[proto][i]->freeService(true);
430           port_list[proto][i]->freeScriptResults();
431           delete port_list[proto][i];
432         }
433       }
434       free(port_list[proto]);
435     }
436   }
437 }
438 
setDefaultPortState(u8 protocol,int state)439 void PortList::setDefaultPortState(u8 protocol, int state) {
440   int proto = INPROTO2PORTLISTPROTO(protocol);
441   int i;
442 
443   for (i = 0; i < port_list_count[proto]; i++) {
444     if (port_list[proto][i] == NULL) {
445       state_counts_proto[proto][default_port_state[proto].state]--;
446       state_counts_proto[proto][state]++;
447     }
448   }
449 
450   default_port_state[proto].state = state;
451 }
452 
setPortState(u16 portno,u8 protocol,int state)453 void PortList::setPortState(u16 portno, u8 protocol, int state) {
454   const Port *oldport;
455   Port *current;
456   int proto = INPROTO2PORTLISTPROTO(protocol);
457 
458   assert(state < PORT_HIGHEST_STATE);
459 
460   if ((state == PORT_OPEN && o.verbose) || (o.debugging > 1)) {
461     log_write(LOG_STDOUT, "Discovered %s port %hu/%s%s\n",
462               statenum2str(state), portno,
463               proto2ascii_lowercase(protocol), idstr? idstr : "");
464     log_flush(LOG_STDOUT);
465   }
466 
467 
468   /* Make sure state is OK */
469   if (state != PORT_OPEN && state != PORT_CLOSED && state != PORT_FILTERED &&
470       state != PORT_UNFILTERED && state != PORT_OPENFILTERED &&
471       state != PORT_CLOSEDFILTERED)
472     fatal("%s: attempt to add port number %d with illegal state %d\n", __func__, portno, state);
473 
474   assert(protocol!=IPPROTO_IP || portno<256);
475 
476   oldport = lookupPort(portno, protocol);
477   if (oldport != NULL) {
478     /* We must discount our statistics from the old values.  Also warn
479        if a complete duplicate */
480     if (o.debugging && oldport->state == state) {
481       error("Duplicate port (%hu/%s)", portno, proto2ascii_lowercase(protocol));
482     }
483     state_counts_proto[proto][oldport->state]--;
484   } else {
485     state_counts_proto[proto][default_port_state[proto].state]--;
486   }
487   current = createPort(portno, protocol);
488 
489   current->state = state;
490   state_counts_proto[proto][state]++;
491 
492   if(state == PORT_FILTERED || state == PORT_OPENFILTERED)
493     setStateReason(portno, protocol, ER_NORESPONSE, 0, NULL);
494   return;
495 }
496 
getPortState(u16 portno,u8 protocol)497 int PortList::getPortState(u16 portno, u8 protocol) {
498   const Port *port;
499 
500   port = lookupPort(portno, protocol);
501   if (port == NULL)
502     return default_port_state[INPROTO2PORTLISTPROTO(protocol)].state;
503 
504   return port->state;
505 }
506 
507 /* Return true if nothing special is known about this port; i.e., it's in the
508    default state as defined by setDefaultPortState and every other data field is
509    unset. */
portIsDefault(u16 portno,u8 protocol)510 bool PortList::portIsDefault(u16 portno, u8 protocol) {
511   return lookupPort(portno, protocol) == NULL;
512 }
513 
514   /* Saves an identification string for the target containing these
515      ports (an IP address might be a good example, but set what you
516      want).  Only used when printing new port updates.  Optional.  A
517      copy is made. */
setIdStr(const char * id)518 void PortList::setIdStr(const char *id) {
519   int len = 0;
520   if (idstr) free(idstr);
521   if (!id) { idstr = NULL; return; }
522   len = strlen(id);
523   len += 5; // " on " + \0
524   idstr = (char *) safe_malloc(len);
525   Snprintf(idstr, len, " on %s", id);
526 }
527 
528 
getStateCounts(int protocol,int state) const529 int PortList::getStateCounts(int protocol, int state) const {
530   return state_counts_proto[INPROTO2PORTLISTPROTO(protocol)][state];
531 }
532 
getStateCounts(int state) const533 int PortList::getStateCounts(int state) const {
534   int sum=0, proto;
535   for(proto=0; proto < PORTLIST_PROTO_MAX; proto++)
536     sum += getStateCounts(PORTLISTPROTO2INPROTO(proto), state);
537   return(sum);
538 }
539 
540   /* A function for iterating through the ports.  Give NULL for the
541    first "afterthisport".  Then supply the most recent returned port
542    for each subsequent call.  When no more matching ports remain, NULL
543    will be returned.  To restrict returned ports to just one protocol,
544    specify IPPROTO_TCP, IPPROTO_UDP or IPPROTO_SCTP for
545    allowed_protocol. A TCPANDUDPANDSCTP for allowed_protocol matches
546    either. A 0 for allowed_state matches all possible states. This
547    function returns ports in numeric order from lowest to highest,
548    except that if you ask for both TCP, UDP & SCTP, every TCP port
549    will be returned before we start returning UDP and SCTP ports */
nextPort(const Port * cur,Port * next,int allowed_protocol,int allowed_state)550 Port *PortList::nextPort(const Port *cur, Port *next,
551                          int allowed_protocol, int allowed_state) {
552   int proto;
553   int mapped_pno;
554   Port *port;
555 
556   if (cur) {
557     proto = INPROTO2PORTLISTPROTO(cur->proto);
558     assert(port_map[proto]!=NULL); // Hmm, it's not possible to handle port that doesn't have anything in map
559     assert(cur->proto!=IPPROTO_IP || cur->portno<256);
560     mapped_pno = port_map[proto][cur->portno];
561     mapped_pno++; //  we're interested in next port after current
562   } else { // running for the first time
563     if (allowed_protocol == TCPANDUDPANDSCTP)
564       proto = INPROTO2PORTLISTPROTO(IPPROTO_TCP);
565     else if (allowed_protocol == UDPANDSCTP)
566       proto = INPROTO2PORTLISTPROTO(IPPROTO_UDP);
567     else
568       proto = INPROTO2PORTLISTPROTO(allowed_protocol);
569     mapped_pno = 0;
570   }
571 
572   if(port_list[proto] != NULL) {
573     for(;mapped_pno < port_list_count[proto]; mapped_pno++) {
574       port = port_list[proto][mapped_pno];
575       if (port && (allowed_state==0 || port->state==allowed_state)) {
576         *next = *port;
577         return next;
578       }
579       if (!port && (allowed_state==0 || default_port_state[proto].state==allowed_state)) {
580         *next = default_port_state[proto];
581         next->portno = port_map_rev[proto][mapped_pno];
582         return next;
583       }
584     }
585   }
586 
587   /* if all protocols, than after TCP search UDP & SCTP */
588   if((!cur && allowed_protocol == TCPANDUDPANDSCTP) ||
589       (cur && proto == INPROTO2PORTLISTPROTO(IPPROTO_TCP)))
590     return(nextPort(NULL, next, UDPANDSCTP, allowed_state));
591 
592   /* if all protocols, than after UDP search SCTP */
593   if((!cur && allowed_protocol == UDPANDSCTP) ||
594       (cur && proto == INPROTO2PORTLISTPROTO(IPPROTO_UDP)))
595     return(nextPort(NULL, next, IPPROTO_SCTP, allowed_state));
596 
597   return(NULL);
598 }
599 
600 /* Convert portno and protocol into the internal indices used to index
601    port_list. */
mapPort(u16 * portno,u8 * protocol) const602 void PortList::mapPort(u16 *portno, u8 *protocol) const {
603   int mapped_portno, mapped_protocol;
604 
605   mapped_protocol = INPROTO2PORTLISTPROTO(*protocol);
606 
607   if (*protocol == IPPROTO_IP)
608     assert(*portno < 256);
609   if(port_map[mapped_protocol]==NULL || port_list[mapped_protocol]==NULL) {
610     fatal("%s(%i,%i): you're trying to access uninitialized protocol", __func__, *portno, *protocol);
611   }
612   mapped_portno = port_map[mapped_protocol][*portno];
613 
614   assert(mapped_portno < port_list_count[mapped_protocol]);
615   assert(mapped_portno >= 0);
616 
617   *portno = mapped_portno;
618   *protocol = mapped_protocol;
619 }
620 
lookupPort(u16 portno,u8 protocol) const621 const Port *PortList::lookupPort(u16 portno, u8 protocol) const {
622   mapPort(&portno, &protocol);
623   return port_list[protocol][portno];
624 }
625 
626 /* Create the port if it doesn't exist; otherwise this is like lookupPort. */
createPort(u16 portno,u8 protocol)627 Port *PortList::createPort(u16 portno, u8 protocol) {
628   Port *p;
629   u16 mapped_portno;
630   u8 mapped_protocol;
631 
632   mapped_portno = portno;
633   mapped_protocol = protocol;
634   mapPort(&mapped_portno, &mapped_protocol);
635 
636   p = port_list[mapped_protocol][mapped_portno];
637   if (p == NULL) {
638     p = new Port();
639     p->portno = portno;
640     p->proto = protocol;
641     p->state = default_port_state[mapped_protocol].state;
642     p->reason.reason_id = ER_NORESPONSE;
643     port_list[mapped_protocol][mapped_portno] = p;
644   }
645 
646   return port_list[mapped_protocol][mapped_portno];
647 }
648 
forgetPort(u16 portno,u8 protocol)649 int PortList::forgetPort(u16 portno, u8 protocol) {
650   Port *answer = NULL;
651 
652   log_write(LOG_PLAIN, "Removed %d\n", portno);
653 
654   mapPort(&portno, &protocol);
655 
656   answer = port_list[protocol][portno];
657   if (answer == NULL)
658     return -1;
659 
660   state_counts_proto[protocol][answer->state]--;
661   state_counts_proto[protocol][default_port_state[protocol].state]++;
662 
663   port_list[protocol][portno] = NULL;
664 
665   if (o.verbose) {
666     log_write(LOG_STDOUT, "Deleting port %hu/%s, which we thought was %s\n",
667               portno, proto2ascii_lowercase(answer->proto),
668               statenum2str(answer->state));
669     log_flush(LOG_STDOUT);
670   }
671 
672   delete answer;
673   return 0;
674 }
675 
676 /* Just free memory used by PortList::port_map[]. Should be done somewhere
677  * before closing nmap. */
freePortMap()678 void PortList::freePortMap() {
679   int proto;
680 
681   for (proto=0; proto < PORTLIST_PROTO_MAX; proto++) {
682     if (port_map[proto]) {
683       free(port_map[proto]);
684       port_map[proto] = NULL;
685     }
686     if (port_map_rev[proto]) {
687       free(port_map_rev[proto]);
688       port_map_rev[proto] = NULL;
689     }
690     port_list_count[proto] = 0;
691   }
692 }
693 
694 
695 u16 *PortList::port_map[PORTLIST_PROTO_MAX];
696 u16 *PortList::port_map_rev[PORTLIST_PROTO_MAX];
697 int PortList::port_list_count[PORTLIST_PROTO_MAX];
698 
699 /* This function must be run before any PortList object is created.
700  * It must be run for every used protocol. The data in "ports"
701  * should be sorted. */
initializePortMap(int protocol,u16 * ports,int portcount)702 void PortList::initializePortMap(int protocol, u16 *ports, int portcount) {
703   int i;
704   int ports_max = (protocol == IPPROTO_IP) ? 256 : 65536;
705   int proto = INPROTO2PORTLISTPROTO(protocol);
706 
707   if (port_map[proto] != NULL || port_map_rev[proto] != NULL)
708     fatal("%s: portmap for protocol %i already initialized", __func__, protocol);
709 
710   assert(port_list_count[proto]==0);
711 
712   /* this memory will never be freed, but this is the way it has to be. */
713   port_map[proto] = (u16 *) safe_zalloc(sizeof(u16) * ports_max);
714   port_map_rev[proto] = (u16 *) safe_zalloc(sizeof(u16) * portcount);
715 
716   port_list_count[proto] = portcount;
717 
718   for(i=0; i < portcount; i++) {
719     port_map[proto][ports[i]] = i;
720     port_map_rev[proto][i] = ports[i];
721   }
722   /* So now port_map should have such structure (lets scan 2nd,4th and 6th port):
723    * 	port_map[0,0,1,0,2,0,3,...]	        <- indexes to port_list structure
724    * 	port_list[port_2,port_4,port_6] */
725 }
726 
727   /* Cycles through the 0 or more "ignored" ports which should be
728    consolidated for Nmap output.  They are returned sorted by the
729    number of ports in the state, starting with the most common.  It
730    should first be called with PORT_UNKNOWN to obtain the most popular
731    ignored state (if any).  Then call with that state to get the next
732    most popular one.  Returns the state if there is one, but returns
733    PORT_UNKNOWN if there are no (more) states which qualify for
734    consolidation */
nextIgnoredState(int prevstate)735 int PortList::nextIgnoredState(int prevstate) {
736 
737   int beststate = PORT_UNKNOWN;
738 
739   for(int state=0; state < PORT_HIGHEST_STATE; state++) {
740     /* The state must be ignored */
741     if (!isIgnoredState(state))
742       continue;
743 
744     /* We can't give the same state again ... */
745     if (state == prevstate) continue;
746 
747     /* If a previous state was given, we must have fewer ports than
748        that one, or be tied but be a larger state number */
749     if (prevstate != PORT_UNKNOWN &&
750         (getStateCounts(state) > getStateCounts(prevstate) ||
751          (getStateCounts(state) == getStateCounts(prevstate) && state <= prevstate)))
752       continue;
753 
754     /* We only qualify if we have more ports than the current best */
755     if (beststate != PORT_UNKNOWN && getStateCounts(beststate) >= getStateCounts(state))
756       continue;
757 
758     /* Yay!  We found the best state so far ... */
759     beststate = state;
760   }
761 
762   return beststate;
763 }
764 
765 /* Returns true if a state should be ignored (consolidated), false otherwise */
isIgnoredState(int state)766 bool PortList::isIgnoredState(int state) {
767 
768   if (o.debugging > 2)
769     return false;
770 
771   if (state == PORT_OPEN || state == PORT_UNKNOWN || state == PORT_TESTING ||
772       state == PORT_FRESH)
773     return false; /* Cannot be ignored */
774 
775   if (state == PORT_OPENFILTERED && (o.verbose > 2 || o.debugging > 2))
776     return false;
777 
778   /* If openonly, we always ignore states that don't at least have open
779      as a possibility. */
780   if (o.openOnly() && state != PORT_OPENFILTERED && state != PORT_UNFILTERED
781       && getStateCounts(state) > 0)
782     return true;
783 
784   int max_per_state = 25; // Ignore states with more ports than this
785   /* We will show more ports when verbosity is requested */
786   if (o.verbose || o.debugging) {
787     if (o.ipprotscan)
788       max_per_state *= ((o.verbose + 1) + 3 * o.debugging);
789     else
790       max_per_state *= ((o.verbose + 1) + 20 * o.debugging);
791   }
792 
793   if (getStateCounts(state) > max_per_state)
794     return true;
795 
796   return false;
797 }
798 
numIgnoredStates()799 int PortList::numIgnoredStates() {
800   int numstates = 0;
801   for(int state=0; state < PORT_HIGHEST_STATE; state++) {
802     if (isIgnoredState(state))
803       numstates++;
804   }
805   return numstates;
806 }
807 
numIgnoredPorts()808 int PortList::numIgnoredPorts() {
809 
810   int numports = 0;
811   for(int state=0; state < PORT_HIGHEST_STATE; state++) {
812     if (isIgnoredState(state))
813       numports += getStateCounts(state);
814   }
815   return numports;
816 }
817 
numPorts() const818 int PortList::numPorts() const {
819   int proto, num = 0;
820 
821   for (proto = 0; proto < PORTLIST_PROTO_MAX; proto++)
822     num += port_list_count[proto];
823 
824   return num;
825 }
826 
827 /* Return true if any of the ports are potentially open. */
hasOpenPorts() const828 bool PortList::hasOpenPorts() const {
829   return getStateCounts(PORT_OPEN) != 0 ||
830     getStateCounts(PORT_OPENFILTERED) != 0 ||
831     getStateCounts(PORT_UNFILTERED) != 0;
832 }
833 
834 /* Returns true if service scan is done and portno is found to be tcpwrapped, false otherwise */
isTCPwrapped(u16 portno) const835 bool PortList::isTCPwrapped(u16 portno) const {
836   const Port *port = lookupPort(portno, IPPROTO_TCP);
837   if (port == NULL) {
838     if (o.debugging > 1) {
839       log_write(LOG_STDOUT, "PortList::isTCPwrapped(%d) requested but port not in list\n", portno);
840     }
841     return false;
842   } else if (!o.servicescan) {
843     if (o.debugging > 1) {
844       log_write(LOG_STDOUT, "PortList::isTCPwrapped(%d) requested but service scan was never asked to be done\n", portno);
845     }
846     return false;
847   } else if (port->service == NULL) {
848     if (o.debugging > 1) {
849       log_write(LOG_STDOUT, "PortList::isTCPwrapped(%d) requested but port has not been service scanned yet\n", portno);
850     }
851     return false;
852   } else if (port->service->name == NULL) {
853     // no service match and port not listed in services file
854     if (o.debugging > 1) {
855       log_write(LOG_STDOUT, "PortList::isTCPwrapped(%d) requested but service has no name\n", portno);
856     }
857     return false;
858   } else {
859     return (strcmp(port->service->name,"tcpwrapped")==0);
860   }
861 }
862 
setStateReason(u16 portno,u8 proto,reason_t reason,u8 ttl,const struct sockaddr_storage * ip_addr)863 int PortList::setStateReason(u16 portno, u8 proto, reason_t reason, u8 ttl,
864   const struct sockaddr_storage *ip_addr) {
865     Port *answer = NULL;
866 
867     answer = createPort(portno, proto);
868 
869     /* set new reason and increment its count */
870     answer->reason.reason_id = reason;
871     if (ip_addr == NULL)
872       answer->reason.ip_addr.sockaddr.sa_family = AF_UNSPEC;
873     else
874       answer->reason.set_ip_addr(ip_addr);
875     answer->reason.ttl = ttl;
876     return 0;
877 }
878 
879 // Move some popular TCP ports to the beginning of the portlist, because
880 // that can speed up certain scans.  You should have already done any port
881 // randomization, this should prevent the ports from always coming out in the
882 // same order.
random_port_cheat(u16 * ports,int portcount)883 void random_port_cheat(u16 *ports, int portcount) {
884   int allportidx = 0;
885   int popportidx = 0;
886   int earlyreplidx = 0;
887   /* Updated 2008-12-19 from nmap-services-all.
888      Top 25 open TCP ports plus 113, 554, and 256 */
889   u16 pop_ports[] = {
890     80, 23, 443, 21, 22, 25, 3389, 110, 445, 139,
891     143, 53, 135, 3306, 8080, 1723, 111, 995, 993, 5900,
892     1025, 587, 8888, 199, 1720,
893     113, 554, 256
894   };
895   int num_pop_ports = sizeof(pop_ports) / sizeof(u16);
896 
897   for(allportidx = 0; allportidx < portcount; allportidx++) {
898     // see if the currentport is a popular port
899     for(popportidx = 0; popportidx < num_pop_ports; popportidx++) {
900       if (ports[allportidx] == pop_ports[popportidx]) {
901         // This one is popular!  Swap it near to the beginning.
902         if (allportidx != earlyreplidx) {
903           ports[allportidx] = ports[earlyreplidx];
904           ports[earlyreplidx] = pop_ports[popportidx];
905         }
906         earlyreplidx++;
907         break;
908       }
909     }
910   }
911 }
912 
statenum2str(int state)913 const char *statenum2str(int state) {
914   switch (state) {
915   case PORT_OPEN:
916     return "open";
917     break;
918   case PORT_FILTERED:
919     return "filtered";
920     break;
921   case PORT_UNFILTERED:
922     return "unfiltered";
923     break;
924   case PORT_CLOSED:
925     return "closed";
926     break;
927   case PORT_OPENFILTERED:
928     return "open|filtered";
929     break;
930   case PORT_CLOSEDFILTERED:
931     return "closed|filtered";
932     break;
933   default:
934     return "unknown";
935     break;
936   }
937   return "unknown";
938 }
939 
940