Index: service_scan.cc =================================================================== --- service_scan.cc (revision 11639) +++ service_scan.cc (working copy) @@ -1630,7 +1630,7 @@ num_hosts_timedout++; continue; } - while((nxtport = Targets[targetno]->ports.nextPort(nxtport, TCPANDUDP, PORT_OPEN))) { + while((nxtport = Targets[targetno]->ports.nextPort(nxtport, TCPANDUDPANDSCTP, PORT_OPEN))) { svc = new ServiceNFO(AP); svc->target = Targets[targetno]; svc->portno = nxtport->portno; @@ -1648,7 +1648,7 @@ if (Targets[targetno]->timedOut(&now)) { continue; } - while((nxtport = Targets[targetno]->ports.nextPort(nxtport, TCPANDUDP, PORT_OPENFILTERED))) { + while((nxtport = Targets[targetno]->ports.nextPort(nxtport, TCPANDUDPANDSCTP, PORT_OPENFILTERED))) { svc = new ServiceNFO(AP); svc->target = Targets[targetno]; svc->portno = nxtport->portno; Index: global_structures.h =================================================================== --- global_structures.h (revision 11639) +++ global_structures.h (working copy) @@ -106,9 +106,9 @@ class TargetGroup; class Target; -/* Stores "port info" which is TCP/UDP ports or RPC program ids */ +/* Stores "port info" which is TCP/UDP/SCTP ports or RPC program ids */ struct portinfo { - unsigned long portno; /* TCP/UDP port or RPC program id or IP protocool */ + unsigned long portno; /* TCP/UDP/SCTP port or RPC program id or IP protocool */ short trynum; int sd[3]; /* Socket descriptors for connect_scan */ struct timeval sent[3]; @@ -237,10 +237,12 @@ int tcp_count; unsigned short *udp_ports; int udp_count; + unsigned short *sctp_ports; + int sctp_count; unsigned short *prots; int prot_count; }; -typedef enum { STYPE_UNKNOWN, HOST_DISCOVERY, ACK_SCAN, SYN_SCAN, FIN_SCAN, XMAS_SCAN, UDP_SCAN, CONNECT_SCAN, NULL_SCAN, WINDOW_SCAN, RPC_SCAN, MAIMON_SCAN, IPPROT_SCAN, PING_SCAN, PING_SCAN_ARP, IDLE_SCAN, BOUNCE_SCAN, SERVICE_SCAN, OS_SCAN, SCRIPT_SCAN, TRACEROUTE, REF_TRACEROUTE}stype; +typedef enum { STYPE_UNKNOWN, HOST_DISCOVERY, ACK_SCAN, SYN_SCAN, FIN_SCAN, XMAS_SCAN, UDP_SCAN, CONNECT_SCAN, NULL_SCAN, WINDOW_SCAN, SCTP_INIT_SCAN, RPC_SCAN, MAIMON_SCAN, IPPROT_SCAN, PING_SCAN, PING_SCAN_ARP, IDLE_SCAN, BOUNCE_SCAN, SERVICE_SCAN, OS_SCAN, SCRIPT_SCAN, TRACEROUTE, REF_TRACEROUTE}stype; #endif /*GLOBAL_STRUCTURES_H */ Index: services.cc =================================================================== --- services.cc (revision 11639) +++ services.cc (working copy) @@ -140,6 +140,7 @@ extern NmapOps o; static int numtcpports = 0; static int numudpports = 0; +static int numsctpports = 0; static std::map service_table; static std::list services_by_ratio; static int services_initialized = 0; @@ -250,6 +251,8 @@ numtcpports++; } else if (strncasecmp(proto, "udp", 3) == 0) { numudpports++; + } else if (strncasecmp(proto, "sctp", 4) == 0) { + numsctpports++; } else if (strncasecmp(proto, "ddp", 3) == 0) { /* ddp is some apple thing...we don't "do" that */ } else if (strncasecmp(proto, "divert", 6) == 0) { @@ -309,6 +312,10 @@ porttbl[ntohs(current.s_port)] |= SCAN_UDP_PORT; t++; } + if ((range_type & SCAN_SCTP_PORT) && strcmp(current.s_proto, "sctp") == 0) { + porttbl[ntohs(current.s_port)] |= SCAN_SCTP_PORT; + t++; + } } } @@ -361,6 +368,10 @@ for (i=0; iudp_count; i++) if (ntohs(serv->s_port) == ptsdata->udp_ports[i]) return true; + } else if (strcmp(serv->s_proto, "sctp") == 0) { + for (i=0; isctp_count; i++) + if (ntohs(serv->s_port) == ptsdata->sctp_ports[i]) + return true; } return false; @@ -377,10 +388,10 @@ // and return the N highest ratio ports (where N==level). // // This function doesn't support IP protocol scan so only call this -// function if o.TCPScan() || o.UDPScan() +// function if o.TCPScan() || o.UDPScan() || o.SCTPScan() void gettoppts(double level, char *portlist, struct scan_lists * ports) { - int ti=0, ui=0; + int ti=0, ui=0, si=0; struct scan_lists ptsdata = { 0 }; bool ptsdata_initialized = false; const struct service_node *current; @@ -429,6 +440,8 @@ ports->tcp_count++; else if (o.UDPScan() && strcmp(current->s_proto, "udp") == 0) ports->udp_count++; + else if (o.SCTPScan() && strcmp(current->s_proto, "sctp") == 0) + ports->sctp_count++; } else { break; } @@ -440,6 +453,9 @@ if (ports->udp_count) ports->udp_ports = (unsigned short *)safe_zalloc(ports->udp_count * sizeof(unsigned short)); + if (ports->sctp_count) + ports->sctp_ports = (unsigned short *)safe_zalloc(ports->sctp_count * sizeof(unsigned short)); + ports->prots = NULL; for (i = services_by_ratio.begin(); i != services_by_ratio.end(); i++) { @@ -451,6 +467,8 @@ ports->tcp_ports[ti++] = ntohs(current->s_port); else if (o.UDPScan() && strcmp(current->s_proto, "udp") == 0) ports->udp_ports[ui++] = ntohs(current->s_port); + else if (o.SCTPScan() && strcmp(current->s_proto, "sctp") == 0) + ports->sctp_ports[si++] = ntohs(current->s_port); } else { break; } @@ -467,6 +485,10 @@ ports->udp_count = MIN((int) level, numudpports); ports->udp_ports = (unsigned short *)safe_zalloc(ports->udp_count * sizeof(unsigned short)); } + if (o.SCTPScan()) { + ports->sctp_count = MIN((int) level, numsctpports); + ports->sctp_ports = (unsigned short *)safe_zalloc(ports->sctp_count * sizeof(unsigned short)); + } ports->prots = NULL; @@ -478,10 +500,13 @@ ports->tcp_ports[ti++] = ntohs(current->s_port); else if (o.UDPScan() && strcmp(current->s_proto, "udp") == 0 && ui < ports->udp_count) ports->udp_ports[ui++] = ntohs(current->s_port); + else if (o.SCTPScan() && strcmp(current->s_proto, "sctp") == 0 && si < ports->sctp_count) + ports->sctp_ports[si++] = ntohs(current->s_port); } if (ti < ports->tcp_count) ports->tcp_count = ti; if (ui < ports->udp_count) ports->udp_count = ui; + if (si < ports->sctp_count) ports->sctp_count = si; } else fatal("Argument to gettoppts (%g) should be a positive ratio below 1 or an integer of 1 or higher", level); @@ -496,9 +521,12 @@ if (ports->udp_count > 1) qsort(ports->udp_ports, ports->udp_count, sizeof(unsigned short), &port_compare); + if (ports->sctp_count > 1) + qsort(ports->sctp_ports, ports->sctp_count, sizeof(unsigned short), &port_compare); + if (o.debugging && level < 1) - log_write(LOG_STDOUT, "PORTS: Using ports open on %g%% or more average hosts (TCP:%d, UDP:%d)\n", level*100, ports->tcp_count, ports->udp_count); + log_write(LOG_STDOUT, "PORTS: Using ports open on %g%% or more average hosts (TCP:%d, UDP:%d, SCTP:%d)\n", level*100, ports->tcp_count, ports->udp_count, ports->sctp_count); else if (o.debugging && level >= 1) - log_write(LOG_STDOUT, "PORTS: Using top %d ports found open (TCP:%d, UDP:%d)\n", (int) level, ports->tcp_count, ports->udp_count); + log_write(LOG_STDOUT, "PORTS: Using top %d ports found open (TCP:%d, UDP:%d, SCTP:%d)\n", (int) level, ports->tcp_count, ports->udp_count, ports->sctp_count); } Index: services.h =================================================================== --- services.h (revision 11639) +++ services.h (working copy) @@ -120,7 +120,8 @@ */ #define SCAN_TCP_PORT (1 << 0) #define SCAN_UDP_PORT (1 << 1) -#define SCAN_PROTOCOLS (1 << 2) +#define SCAN_SCTP_PORT (1 << 2) +#define SCAN_PROTOCOLS (1 << 3) int addportsfromservmask(char *mask, u8 *porttbl, int range_type); struct servent *nmap_getservbyport(int port, const char *proto); Index: nse_nmaplib.cc =================================================================== --- nse_nmaplib.cc (revision 11639) +++ nse_nmaplib.cc (working copy) @@ -8,6 +8,7 @@ #include "nmap_rpc.h" #include "nmap_dns.h" #include "osscan.h" +#include "protocols.h" /* #include "output.h" UNNECESSARY?? */ @@ -109,7 +110,7 @@ lua_pushstring(L, sd.name); lua_setfield(L, -2, "service"); - lua_pushstring(L, (port->proto == IPPROTO_TCP)? "tcp": "udp"); + lua_pushstring(L, IPPROTO2STR(port->proto)); lua_setfield(L, -2, "protocol"); lua_newtable(L); @@ -306,7 +307,8 @@ portno = (int) lua_tointeger(L, -2); protocol = strcmp(lua_tostring(L, -1), "tcp") == 0 ? IPPROTO_TCP : strcmp(lua_tostring(L, -1), "udp") == 0 ? IPPROTO_UDP : - luaL_error(L, "port 'protocol' field must be \"udp\" or \"tcp\""); + strcmp(lua_tostring(L, -1), "sctp") == 0 ? IPPROTO_SCTP : + luaL_error(L, "port 'protocol' field must be \"udp\", \"sctp\" or \"tcp\""); while ((port = target->ports.nextPort(port, protocol, PORT_UNKNOWN)) != NULL) if (port->portno == portno) break; Index: nmap.cc =================================================================== --- nmap.cc (revision 11639) +++ nmap.cc (working copy) @@ -238,6 +238,7 @@ " -sN/sF/sX: TCP Null, FIN, and Xmas scans\n" " --scanflags : Customize TCP scan flags\n" " -sI : Idle scan\n" + " -sY: SCTP INIT Scan\n" " -sO: IP protocol scan\n" " -b : FTP bounce scan\n" "PORT SPECIFICATION AND SCAN ORDER:\n" @@ -289,7 +290,8 @@ " --ip-options : Send packets with specified ip options\n" " --ttl : Set IP time-to-live field\n" " --spoof-mac : Spoof your MAC address\n" - " --badsum: Send packets with a bogus TCP/UDP checksum\n" + " --badsum: Send packets with a bogus TCP/UDP/SCTP checksum\n" + " --adler32: Use deprecated Adler32 instead of CRC32C for SCTP checksums\n" "OUTPUT:\n" " -oN/-oX/-oS/-oG : Output scan in normal, XML, s| o.maxTCPScanDelay()) o.setMaxTCPScanDelay(o.scan_delay); if (o.scan_delay > o.maxUDPScanDelay()) o.setMaxUDPScanDelay(o.scan_delay); + if (o.scan_delay > o.maxSCTPScanDelay()) o.setMaxSCTPScanDelay(o.scan_delay); o.max_parallelism = 1; if(pre_max_parallelism != -1) fatal("You can't use --max-parallelism with --scan-delay."); @@ -1260,6 +1268,7 @@ if (pre_max_scan_delay != -1) { o.setMaxTCPScanDelay(pre_max_scan_delay); o.setMaxUDPScanDelay(pre_max_scan_delay); + o.setMaxSCTPScanDelay(pre_max_scan_delay); } if (pre_init_rtt_timeout != -1) o.setInitialRttTimeout(pre_init_rtt_timeout); if (pre_min_rtt_timeout != -1) o.setMinRttTimeout(pre_min_rtt_timeout); @@ -1348,7 +1357,7 @@ } // Uncomment the following line to use the common lisp port spec test suite - //printf("port spec: (%d %d %d)\n", ports.tcp_count, ports.udp_count, ports.prot_count); exit(0); + //printf("port spec: (%d %d %d %d)\n", ports.tcp_count, ports.udp_count, ports.stcp_count, ports.prot_count); exit(0); #ifdef WIN32 if (o.sendpref & PACKET_SEND_IP) { @@ -1409,6 +1418,8 @@ */ if ((o.TCPScan()) && ports.tcp_count == 0) error("WARNING: a TCP scan type was requested, but no tcp ports were specified. Skipping this scan type."); + if (o.SCTPScan() && ports.sctp_count == 0) + error("WARNING: a SCTP scan type was requested, but no sctp ports were specified. Skipping this scan type."); if (o.UDPScan() && ports.udp_count == 0) error("WARNING: UDP scan was requested, but no udp ports were specified. Skipping this scan type."); if (o.ipprotscan && ports.prot_count == 0) @@ -1505,7 +1516,7 @@ /* Before we randomize the ports scanned, lets output them to machine parseable output */ if (o.verbose) - output_ports_to_machine_parseable_output(&ports, o.TCPScan(), o.udpscan, o.ipprotscan); + output_ports_to_machine_parseable_output(&ports, o.TCPScan(), o.UDPScan(), o.SCTPScan(), o.ipprotscan); /* more fakeargv junk, BTW malloc'ing extra space in argv[0] doesn't work */ if (quashargv) { @@ -1535,7 +1546,7 @@ log_write(LOG_PLAIN, "--------------- Timing report ---------------\n"); log_write(LOG_PLAIN, " hostgroups: min %d, max %d\n", o.minHostGroupSz(), o.maxHostGroupSz()); log_write(LOG_PLAIN, " rtt-timeouts: init %d, min %d, max %d\n", o.initialRttTimeout(), o.minRttTimeout(), o.maxRttTimeout()); - log_write(LOG_PLAIN, " max-scan-delay: TCP %d, UDP %d\n", o.maxTCPScanDelay(), o.maxUDPScanDelay()); + log_write(LOG_PLAIN, " max-scan-delay: TCP %d, UDP %d, SCTP %d\n", o.maxTCPScanDelay(), o.maxUDPScanDelay(), o.maxSCTPScanDelay()); log_write(LOG_PLAIN, " parallelism: min %d, max %d\n", o.min_parallelism, o.max_parallelism); log_write(LOG_PLAIN, " max-retries: %d, host-timeout: %ld\n", o.getMaxRetransmissions(), o.host_timeout); log_write(LOG_PLAIN, " min-rate: %g, max-rate: %g\n", o.min_packet_send_rate, o.max_packet_send_rate); @@ -1549,6 +1560,8 @@ PortList::initializePortMap(IPPROTO_TCP, ports.tcp_ports, ports.tcp_count); if (o.UDPScan()) PortList::initializePortMap(IPPROTO_UDP, ports.udp_ports, ports.udp_count); + if (o.SCTPScan()) + PortList::initializePortMap(IPPROTO_SCTP, ports.sctp_ports, ports.sctp_count); if (randomize) { if (ports.tcp_count) { @@ -1558,6 +1571,8 @@ } if (ports.udp_count) shortfry(ports.udp_ports, ports.udp_count); + if (ports.sctp_count) + shortfry(ports.sctp_ports, ports.sctp_count); if (ports.prot_count) shortfry(ports.prots, ports.prot_count); } @@ -1760,6 +1775,9 @@ if (o.connectscan) ultra_scan(Targets, &ports, CONNECT_SCAN); + if (o.sctpinitscan) + ultra_scan(Targets, &ports, SCTP_INIT_SCAN); + if (o.ipprotscan) ultra_scan(Targets, &ports, IPPROT_SCAN); @@ -2121,12 +2139,14 @@ u8 *porttbl; int range_type = 0; int portwarning = 0; - int i, tcpi, udpi, proti; + int i, tcpi, udpi, sctpi, proti; if (o.TCPScan()) range_type |= SCAN_TCP_PORT; if (o.UDPScan()) range_type |= SCAN_UDP_PORT; + if (o.SCTPScan()) + range_type |= SCAN_SCTP_PORT; if (o.ipprotscan) range_type |= SCAN_PROTOCOLS; @@ -2135,22 +2155,25 @@ getpts_aux(origexpr, // Pass on the expression 0, // Don't start off nested porttbl, // Our allocated port table - range_type, // Defaults to TCP/UDP/Protos + range_type, // Defaults to TCP/UDP/SCTP/Protos &portwarning); // No, we haven't warned them about dup ports yet ports->tcp_count = 0; ports->udp_count = 0; + ports->sctp_count = 0; ports->prot_count = 0; for(i = 0; i <= 65535; i++) { if (porttbl[i] & SCAN_TCP_PORT) ports->tcp_count++; if (porttbl[i] & SCAN_UDP_PORT) ports->udp_count++; + if (porttbl[i] & SCAN_SCTP_PORT) + ports->sctp_count++; if (porttbl[i] & SCAN_PROTOCOLS && i < 256) ports->prot_count++; } - if (range_type != 0 && 0 == (ports->tcp_count + ports->udp_count + ports->prot_count)) + if (range_type != 0 && 0 == (ports->tcp_count + ports->udp_count + ports->sctp_count + ports->prot_count)) fatal("No ports specified -- If you really don't want to scan any ports use ping scan..."); if (ports->tcp_count) { @@ -2159,15 +2182,20 @@ if (ports->udp_count) { ports->udp_ports = (unsigned short *)safe_zalloc(ports->udp_count * sizeof(unsigned short)); } + if (ports->sctp_count) { + ports->sctp_ports = (unsigned short *)safe_zalloc(ports->sctp_count * sizeof(unsigned short)); + } if (ports->prot_count) { ports->prots = (unsigned short *)safe_zalloc(ports->prot_count * sizeof(unsigned short)); } - for(i=tcpi=udpi=proti=0; i <= 65535; i++) { + for(i=tcpi=udpi=sctpi=proti=0; i <= 65535; i++) { if (porttbl[i] & SCAN_TCP_PORT) ports->tcp_ports[tcpi++] = i; if (porttbl[i] & SCAN_UDP_PORT) ports->udp_ports[udpi++] = i; + if (porttbl[i] & SCAN_SCTP_PORT) + ports->sctp_ports[sctpi++] = i; if (porttbl[i] & SCAN_PROTOCOLS && i < 256) ports->prots[proti++] = i; } @@ -2177,7 +2205,7 @@ /* This function is like getpts except it only allocates space for and stores values into one unsigned short array, instead of an entire scan_lists struct - For that reason, T:, U:, and P: restrictions are not allowed and only one + For that reason, T:, U:, S: and P: restrictions are not allowed and only one bit in range_type may be set. */ void getpts_simple(const char *origexpr, int range_type, unsigned short **list, int *count) { @@ -2249,6 +2277,11 @@ range_type = SCAN_UDP_PORT; continue; } + if (*current_range == 'S' && *++current_range == ':') { + current_range++; + range_type = SCAN_SCTP_PORT; + continue; + } if (*current_range == 'P' && *++current_range == ':') { current_range++; range_type = SCAN_PROTOCOLS; @@ -2366,6 +2399,10 @@ nmap_getservbyport(htons(rangestart), "udp")) { porttbl[rangestart] |= SCAN_UDP_PORT; } + if ((range_type & SCAN_SCTP_PORT) && + nmap_getservbyport(htons(rangestart), "sctp")) { + porttbl[rangestart] |= SCAN_SCTP_PORT; + } if ((range_type & SCAN_PROTOCOLS) && nmap_getprotbynum(htons(rangestart))) { porttbl[rangestart] |= SCAN_PROTOCOLS; @@ -2397,6 +2434,7 @@ void free_scan_lists(struct scan_lists *ports) { if (ports->tcp_ports) free(ports->tcp_ports); if (ports->udp_ports) free(ports->udp_ports); + if (ports->sctp_ports) free(ports->sctp_ports); if (ports->prots) free(ports->prots); if (ports->syn_ping_ports) free(ports->syn_ping_ports); if (ports->ack_ping_ports) free(ports->ack_ping_ports); @@ -2498,6 +2536,7 @@ case CONNECT_SCAN: return "Connect Scan"; break; case NULL_SCAN: return "NULL Scan"; break; case WINDOW_SCAN: return "Window Scan"; break; + case SCTP_INIT_SCAN: return "SCTP INIT Scan"; break; case RPC_SCAN: return "RPCGrind Scan"; break; case MAIMON_SCAN: return "Maimon Scan"; break; case IPPROT_SCAN: return "IPProto Scan"; break; Index: nmap.h =================================================================== --- nmap.h (revision 11639) +++ nmap.h (working copy) @@ -297,6 +297,10 @@ #define MAX_UDP_SCAN_DELAY 1000 #endif +#ifndef MAX_SCTP_SCAN_DELAY +#define MAX_SCTP_SCAN_DELAY 1000 +#endif + /* Maximum number of extra hostnames, OSs, and devices, we consider when outputing the extra service info fields */ #define MAX_SERVICE_INFO_FIELDS 5 Index: scan_engine.h =================================================================== --- scan_engine.h (revision 11639) +++ scan_engine.h (working copy) @@ -116,6 +116,10 @@ u16 dport; }; +struct probespec_sctpdata { + u16 dport; +}; + struct probespec_icmpdata { u8 type; u8 code; @@ -128,6 +132,7 @@ #define PS_ICMP 4 #define PS_ARP 5 #define PS_CONNECTTCP 6 +#define PS_SCTP 7 /* The size of this structure is critical, since there can be tens of thousands of them stored together ... */ @@ -139,6 +144,7 @@ union { struct probespec_tcpdata tcp; /* If type is PS_TCP or PS_CONNECTTCP. */ struct probespec_udpdata udp; /* PS_UDP */ + struct probespec_sctpdata sctp; /* PS_SCTP */ struct probespec_icmpdata icmp; /* PS_ICMP */ /* Nothing needed for PS_ARP, since src mac and target IP are avail from target structure anyway */ Index: NmapOps.cc =================================================================== --- NmapOps.cc (revision 11639) +++ NmapOps.cc (working copy) @@ -246,6 +246,7 @@ max_host_group_sz = 100000; // don't want to be restrictive unless user sets max_tcp_scan_delay = MAX_TCP_SCAN_DELAY; max_udp_scan_delay = MAX_UDP_SCAN_DELAY; + max_sctp_scan_delay = MAX_SCTP_SCAN_DELAY; max_ips_to_scan = 0; extra_payload_length = 0; extra_payload = NULL; @@ -266,6 +267,7 @@ listscan = pingscan = allowall = ackscan = bouncescan = connectscan = 0; rpcscan = nullscan = xmasscan = fragscan = synscan = windowscan = 0; maimonscan = idlescan = finscan = udpscan = ipprotscan = noresolve = 0; + sctpinitscan = 0; append_output = 0; memset(logfd, 0, sizeof(FILE *) * LOG_NUM_FILES); ttl = -1; @@ -274,6 +276,7 @@ gettimeofday(&start_time, NULL); pTrace = vTrace = false; reason = false; + adler32 = false; if (datadir) free(datadir); datadir = NULL; if (xsl_stylesheet) free(xsl_stylesheet); @@ -313,6 +316,10 @@ sourcesocklen = 0; } +bool NmapOps::SCTPScan() { + return sctpinitscan; +} + bool NmapOps::TCPScan() { return ackscan|bouncescan|connectscan|finscan|idlescan|maimonscan|nullscan|synscan|windowscan|xmasscan; } @@ -326,7 +333,7 @@ IPv6 is being used. It will return false in those cases where a RawScan is not neccessarily used. */ bool NmapOps::RawScan() { - if (ackscan|finscan|idlescan|ipprotscan|maimonscan|nullscan|osscan|synscan|udpscan|windowscan|xmasscan) + if (ackscan|finscan|idlescan|ipprotscan|maimonscan|nullscan|osscan|synscan|udpscan|windowscan|xmasscan|sctpinitscan) return true; if (pingtype & (PINGTYPE_ICMP_PING|PINGTYPE_ICMP_MASK|PINGTYPE_ICMP_TS|PINGTYPE_TCP_USE_ACK|PINGTYPE_UDP)) return true; @@ -344,7 +351,7 @@ /* Insure that at least one scantype is selected */ - if (TCPScan() + UDPScan() + ipprotscan + listscan + pingscan == 0) { + if (TCPScan() + UDPScan() + SCTPScan() + ipprotscan + listscan + pingscan == 0) { if (isr00t && af() == AF_INET) synscan++; else connectscan++; @@ -376,7 +383,7 @@ fatal("Sorry, IPProto Ping (-PO) only works if you are root (because we need to read raw responses off the wire) and only for IPv4"); } - if (ipprotscan + (TCPScan() || UDPScan()) + listscan + pingscan > 1) { + if (ipprotscan + (TCPScan() || UDPScan() || SCTPScan()) + listscan + pingscan > 1) { fatal("Sorry, the IPProtoscan, Listscan, and Pingscan (-sO, -sL, -sP) must currently be used alone rather than combined with other scan types."); } @@ -384,7 +391,7 @@ fatal("-PN (skip ping) is incompatable with -sP (ping scan). If you only want to enumerate hosts, try list scan (-sL)"); } - if (pingscan && (TCPScan() || UDPScan() || ipprotscan || listscan)) { + if (pingscan && (TCPScan() || UDPScan() || SCTPScan() || ipprotscan || listscan)) { fatal("Ping scan is not valid with any other scan types (the other ones all include a ping scan"); } @@ -402,7 +409,7 @@ /* We start with stuff users should not do if they are not root */ if (!isr00t) { - if (ackscan|finscan|idlescan|ipprotscan|maimonscan|nullscan|synscan|udpscan|windowscan|xmasscan) { + if (ackscan|finscan|idlescan|ipprotscan|maimonscan|nullscan|synscan|udpscan|windowscan|xmasscan|sctpinitscan) { fatal("You requested a scan type which requires %s.", privreq); } @@ -485,7 +492,7 @@ fatal("--min-rate=%g must be less than or equal to --max-rate=%g", min_packet_send_rate, max_packet_send_rate); } - if (af() == AF_INET6 && (numdecoys|osscan|bouncescan|fragscan|ackscan|finscan|idlescan|ipprotscan|maimonscan|nullscan|synscan|udpscan|windowscan|xmasscan)) { + if (af() == AF_INET6 && (numdecoys|osscan|bouncescan|fragscan|ackscan|finscan|idlescan|ipprotscan|maimonscan|nullscan|synscan|udpscan|windowscan|xmasscan|sctpinitscan)) { fatal("Sorry -- IPv6 support is currently only available for connect() scan (-sT), ping scan (-sP), and list scan (-sL). OS detection and decoys are also not supported with IPv6. Further support is under consideration."); } Index: tcpip.cc =================================================================== --- tcpip.cc (revision 11639) +++ tcpip.cc (working copy) @@ -193,6 +193,8 @@ return uppercase? "TCP" : "tcp"; break; case IPPROTO_UDP: return uppercase? "UDP" : "udp"; break; + case IPPROTO_SCTP: + return uppercase? "SCTP" : "sctp"; break; case IPPROTO_IP: return uppercase? "IP" : "ip"; break; default: @@ -436,6 +438,7 @@ struct ip *ip = (struct ip *) packet; struct tcp_hdr *tcp = NULL; struct udp_hdr *udp = NULL; + struct sctp_hdr *sctp = NULL; char ipinfo[512]; char srchost[INET6_ADDRSTRLEN], dsthost[INET6_ADDRSTRLEN]; char *p; @@ -558,6 +561,14 @@ Snprintf(protoinfo, sizeof(protoinfo), "UDP %s:%d > %s:%d %s", srchost, ntohs(udp->uh_sport), dsthost, ntohs(udp->uh_dport), ipinfo); + } else if (ip->ip_p == IPPROTO_SCTP && frag_off) { + Snprintf(protoinfo, sizeof(protoinfo), "SCTP %s:?? > %s:?? fragment %s (incomplete)", srchost, dsthost, ipinfo); + } else if (ip->ip_p == IPPROTO_SCTP) { + sctp = (struct sctp_hdr *) (packet + sizeof(struct ip)); + + Snprintf(protoinfo, sizeof(protoinfo), "SCTP %s:%d > %s:%d %s", + srchost, ntohs(sctp->sh_sport), dsthost, ntohs(sctp->sh_dport), + ipinfo); } else if (ip->ip_p == IPPROTO_ICMP && frag_off) { Snprintf(protoinfo, sizeof(protoinfo), "ICMP %s > %s fragment %s (incomplete)", srchost, dsthost, ipinfo); } else if (ip->ip_p == IPPROTO_ICMP) { @@ -586,6 +597,7 @@ if (pktlen + 8 < len) { tcp = (struct tcp_hdr *) ((char *) ip2 + (ip2->ip_hl * 4)); udp = (struct udp_hdr *) ((char *) ip2 + (ip2->ip_hl * 4)); + sctp = (struct sctp_hdr *) ((char *) ip2 + (ip2->ip_hl * 4)); } ip2dst = inet_ntoa(ip2->ip_dst); switch (ping->code) { @@ -603,6 +615,8 @@ Snprintf(icmptype, sizeof icmptype, "port %u unreachable", ntohs(udp->uh_dport)); else if (ip2->ip_p == IPPROTO_TCP && tcp) Snprintf(icmptype, sizeof icmptype, "port %u unreachable", ntohs(tcp->th_dport)); + else if (ip2->ip_p == IPPROTO_SCTP && sctp) + Snprintf(icmptype, sizeof icmptype, "port %u unreachable", ntohs(sctp->sh_dport)); else strcpy(icmptype, "port unreachable"); break; @@ -1770,6 +1784,67 @@ return res; } +/* Builds an SCTP packet (including an IP header) by packing the fields + with the given information. It allocates a new buffer to store the + packet contents, and then returns that buffer. The packet is not + actually sent by this function. Caller must delete the buffer when + finished with the packet. The packet length is returned in + packetlen, which must be a valid int pointer. */ +u8 *build_sctp_raw(const struct in_addr *source, const struct in_addr *victim, + int ttl, u16 ipid, u8 tos, bool df, + u8 *ipopt, int ipoptlen, + u16 sport, u16 dport, + u32 vtag, char *chunks, int chunkslen, + char *data, u16 datalen, u32 *outpacketlen) +{ + int packetlen = sizeof(struct ip) + ipoptlen + sizeof(struct sctp_hdr) + chunkslen + datalen; + u8 *packet = (u8 *) safe_malloc(packetlen); + struct ip *ip = (struct ip *) packet; + struct sctp_hdr *sctp = (struct sctp_hdr *) ((u8*)ip + sizeof(struct ip) + ipoptlen); + static int myttl = 0; + + /* check that required fields are there and not too silly */ + assert(victim); + assert(source); + assert(ipoptlen%4==0); + + /* Time to live */ + if (ttl == -1) { + myttl = (get_random_uint() % 23) + 37; + } else { + myttl = ttl; + } + + sctp->sh_sport = htons(sport); + sctp->sh_dport = htons(dport); + sctp->sh_sum = 0; + sctp->sh_vtag = htonl(vtag); + + if (chunks) + memcpy((u8*)sctp + sizeof(struct sctp_hdr), chunks, chunkslen); + + if (data) + memcpy((u8*)sctp + sizeof(struct sctp_hdr) + chunkslen, data, datalen); + + /* RFC 2960 originally defined Adler32 checksums, which was later + * revised to CRC32C in RFC 3309 and RFC 4960 respectively. + * Nmap uses CRC32C by default, unless --adler32 is given. */ + if (o.adler32) + sctp->sh_sum = htonl(adler32((unsigned char*)sctp, sizeof(struct sctp_hdr) + chunkslen + datalen)); + else + sctp->sh_sum = htonl(crc32c((unsigned char*)sctp, sizeof(struct sctp_hdr) + chunkslen + datalen)); + + if (o.badsum) + --sctp->sh_sum; + + fill_ip_raw(ip, packetlen, ipopt, ipoptlen, + tos, ipid, df?IP_DF:0, myttl, IPPROTO_SCTP, + source, victim); + + *outpacketlen = packetlen; + return packet; +} + /* Builds an IP packet (including an IP header) by packing the fields with the given information. It allocates a new buffer to store the packet contents, and then returns that buffer. The packet is not Index: portreasons.cc =================================================================== --- portreasons.cc (revision 11639) +++ portreasons.cc (working copy) @@ -122,7 +122,8 @@ "unknown", "admin-prohibited", "unknown", "time-exceeded", "unknown", "unknown", "timestamp-reply", "unknown", "unknown", "unknown", "addressmask-reply", "no-ipid-change", "ipid-change", "arp-response", "tcp-response", - "no-response", "localhost-response", "script-set", "unknown-response","user-set" + "no-response", "init-ack", "abort", + "localhost-response", "script-set", "unknown-response","user-set" }; const char *reason_pl_text[ER_MAX+1]={ @@ -134,7 +135,8 @@ "unknowns", "admin-prohibiteds", "unknowns", "time-exceededs", "unknowns", "unknowns", "timestamp-replies", "unknowns", "unknowns", "unknowns", "addressmask-replies", "no-ipid-changes", "ipid-changes", "arp-responses", - "tcp-responses", "no-responses", "localhost-response", "script-set", "unknown-responses" + "tcp-responses", "no-responses", "init-acks", "aborts", + "localhost-response", "script-set", "unknown-responses" }; static void state_reason_summary_init(state_reason_summary_t *r) { @@ -255,7 +257,7 @@ Port *current = NULL; state_reason_summary_t *reason; unsigned int total = 0; - unsigned short proto = (o.ipprotscan) ? IPPROTO_IP : TCPANDUDP; + unsigned short proto = (o.ipprotscan) ? IPPROTO_IP : TCPANDUDPANDSCTP; if(head == NULL) return 0; Index: tcpip.h =================================================================== --- tcpip.h (revision 11639) +++ tcpip.h (working copy) @@ -534,6 +534,20 @@ char *data, u16 datalen, u32 *packetlen); +/* Builds an SCTP packet (including an IP header) by packing the fields + with the given information. It allocates a new buffer to store the + packet contents, and then returns that buffer. The packet is not + actually sent by this function. Caller must delete the buffer when + finished with the packet. The packet length is returned in + packetlen, which must be a valid int pointer. */ +u8 *build_sctp_raw(const struct in_addr *source, const struct in_addr *victim, + int ttl, u16 ipid, u8 tos, bool df, + u8* ipopt, int ipoptlen, + u16 sport, u16 dport, + u32 vtag, char *chunks, int chunk_count, + char *data, u16 datalen, + u32 *packetlen); + /* Builds an ICMP packet (including an IP header) by packing the fields with the given information. It allocates a new buffer to store the packet contents, and then returns that buffer. The Index: portreasons.h =================================================================== --- portreasons.h (revision 11639) +++ portreasons.h (working copy) @@ -148,7 +148,8 @@ ER_ADDRESSMASKREPLY=29, ER_NOIPIDCHANGE, ER_IPIDCHANGE, ER_ARPRESPONSE, ER_TCPRESPONSE, ER_NORESPONSE, - ER_LOCALHOST, ER_SCRIPT, ER_UNKNOWN, ER_USER, ER_MAX=ER_USER /* 39 */ + ER_INITACK, ER_ABORT, + ER_LOCALHOST, ER_SCRIPT, ER_UNKNOWN, ER_USER, ER_MAX=ER_USER /* 41 */ }; /* Be careful to update these values if any ICMP Index: portlist.h =================================================================== --- portlist.h (revision 11639) +++ portlist.h (working copy) @@ -122,7 +122,8 @@ #define PORT_HIGHEST_STATE 9 /* ***IMPORTANT -- BUMP THIS UP WHEN STATES ARE ADDED *** */ -#define TCPANDUDP IPPROTO_MAX +#define TCPANDUDPANDSCTP IPPROTO_MAX +#define UDPANDSCTP (IPPROTO_MAX + 1) #define CONF_NONE 0 #define CONF_LOW 1 @@ -263,8 +264,9 @@ enum portlist_proto { // PortList Protocols PORTLIST_PROTO_TCP = 0, PORTLIST_PROTO_UDP = 1, - PORTLIST_PROTO_IP = 2, - PORTLIST_PROTO_MAX = 3 + PORTLIST_PROTO_SCTP = 2, + PORTLIST_PROTO_IP = 3, + PORTLIST_PROTO_MAX = 4 }; class PortList { @@ -290,12 +292,12 @@ 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 */ + specify IPPROTO_TCP, IPPROTO_UDP or UPPROTO_SCTP for + allowed_protocol. A TCPANDUDPANDSCTP 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 TCP, UDP & SCTP, all TCP ports will be + returned before we start returning UDP and finally SCTP ports */ Port *nextPort(Port *afterthisport, int allowed_protocol, int allowed_state); Index: nse_nsock.cc =================================================================== --- nse_nsock.cc (revision 11639) +++ nse_nsock.cc (working copy) @@ -16,6 +16,7 @@ #include "utils.h" #include "tcpip.h" +#include "protocols.h" #if HAVE_OPENSSL #include @@ -629,7 +630,7 @@ &local, &remote, sizeof(sockaddr)); log_write(LOG_STDOUT, "%s: %s %s:%d %s %s:%d | %s\n", SCRIPT_ENGINE, - (protocol == IPPROTO_TCP)? "TCP" : "UDP", + IPPROTO2STR_UC(protocol), inet_ntop_both(af, &local, ipstring_local), inet_port_both(af, &local), (direction == TO)? ">" : "<", Index: nmap-services =================================================================== --- nmap-services (revision 11639) +++ nmap-services (working copy) @@ -34,6 +34,7 @@ unknown 8/tcp 0.000013 discard 9/tcp 0.003764 # sink null discard 9/udp 0.015733 # sink null +discard 9/sctp # sink null unknown 10/tcp 0.000063 systat 11/tcp 0.000075 # Active Users systat 11/udp 0.000577 # Active Users @@ -50,10 +51,13 @@ chargen 19/udp 0.015865 # ttytst source Character Generator ftp-data 20/tcp 0.001079 # File Transfer [Default Data] ftp-data 20/udp 0.001878 # File Transfer [Default Data] +ftp-data 20/sctp # File Transfer [Default Data] ftp 21/tcp 0.197667 # File Transfer [Control] ftp 21/udp 0.004844 # File Transfer [Control] +ftp 21/sctp # File Transfer [Control] ssh 22/tcp 0.182286 # Secure Shell Login ssh 22/udp 0.003905 # Secure Shell Login +ssh 22/sctp # Secure Shell Login telnet 23/tcp 0.221265 telnet 23/udp 0.006211 priv-mail 24/tcp 0.001154 # any private mail system @@ -153,6 +157,7 @@ finger 79/udp 0.000956 http 80/tcp 0.484143 # World Wide Web HTTP http 80/udp 0.035767 # World Wide Web HTTP +http 80/sctp # World Wide Web HTTP hosts2-ns 81/tcp 0.012056 # HOSTS2 Name Server hosts2-ns 81/udp 0.001005 # HOSTS2 Name Server xfer 82/tcp 0.002923 # XFER Utility @@ -323,6 +328,7 @@ nextstep 178/udp 0.000346 # NextStep Window Server bgp 179/tcp 0.010538 # Border Gateway Protocol bgp 179/udp 0.000494 # Border Gateway Protocol +bgp 179/sctp # Border Gateway Protocol ris 180/tcp 0.000038 # Intergraph ris 180/udp 0.000478 # Intergraph unify 181/tcp 0.000025 @@ -660,6 +666,7 @@ cvc_hostd 442/udp 0.000774 https 443/tcp 0.208669 # secure http (SSL) https 443/udp 0.010840 +https 443/sctp snpp 444/tcp 0.004466 # Simple Network Paging Protocol snpp 444/udp 0.000873 # Simple Network Paging Protocol microsoft-ds 445/tcp 0.056944 # SMB directly over IP @@ -1865,8 +1872,9 @@ unknown 1165/tcp 0.000152 unknown 1166/tcp 0.000152 unknown 1166/udp 0.000330 -unknown 1167/tcp 0.000076 -phone 1167/udp 0.000593 # conference calling +cisco-ipsla 1167/tcp 0.000076 # Cisco IP SLAs Control Protocol +cisco-ipsla 1167/udp 0.000593 # Cisco IP SLAs Control Protocol +cisco-ipsla 1167/sctp # Cisco IP SLAs Control Protocol unknown 1168/tcp 0.000076 unknown 1168/udp 0.000330 unknown 1169/tcp 0.000380 @@ -2893,6 +2901,8 @@ msantipiracy 2222/udp 0.047902 # Microsoft Office OS X antipiracy network monitor unknown 2223/udp 0.010902 unknown 2224/tcp 0.000076 +rcip-itu 2225/tcp # Resource Connection Initiation Protocol +rcip-itu 2225/sctp # Resource Connection Initiation Protocol unknown 2226/udp 0.000330 ivs-video 2232/tcp 0.000151 # IVS Video default ivs-video 2232/udp 0.000626 # IVS Video default @@ -3189,7 +3199,11 @@ unknown 2902/tcp 0.000076 extensisportfolio 2903/tcp 0.000100 # Portfolio Server by Extensis Product Group unknown 2903/udp 0.000330 -unknown 2904/udp 0.000330 +m2ua 2904/tcp # SIGTRAN M2UA +m2ua 2904/udp 0.000330 # SIGTRAN M2UA +m2ua 2904/sctp # SIGTRAN M2UA +m3ua 2905/tcp # SIGTRAN M3UA +m3ua 2905/sctp # SIGTRAN M3UA unknown 2908/tcp 0.000076 unknown 2908/udp 0.000661 unknown 2909/tcp 0.000228 @@ -3203,7 +3217,12 @@ unknown 2930/tcp 0.000076 unknown 2932/udp 0.000330 unknown 2940/udp 0.000330 -unknown 2944/udp 0.000330 +megaco-h248 2944/tcp # Megaco H-248 (Text) +megaco-h248 2944/udp 0.000330 # Megaco H-248 (Text) +megaco-h248 2944/sctp # Megaco H-248 (Text) +h248-binary 2945/tcp # Megaco H-248 (Binary) +h248-binary 2945/udp # Megaco H-248 (Binary) +h248-binary 2945/sctp # Megaco H-248 (Binary) wap-push 2948/udp 0.000791 # Windows Mobile devices often have this unknown 2950/udp 0.000330 unknown 2951/udp 0.000330 @@ -3275,6 +3294,7 @@ sj3 3086/tcp 0.000050 # SJ3 (kanji input) unknown 3089/tcp 0.000076 unknown 3094/udp 0.000661 +itu-bicc-stc 3097/sctp # ITU-T Q.1902.1/Q.2150.3 unknown 3099/udp 0.000330 unknown 3102/tcp 0.000076 unknown 3102/udp 0.000330 @@ -3488,6 +3508,7 @@ unknown 3546/tcp 0.000304 unknown 3551/tcp 0.000380 unknown 3555/udp 0.000330 +m2pa 3565/sctp # M2PA unknown 3569/udp 0.000991 unknown 3571/udp 0.000330 unknown 3573/udp 0.000330 @@ -3630,8 +3651,13 @@ unknown 3856/tcp 0.000076 unknown 3859/tcp 0.000152 unknown 3860/tcp 0.000076 -unknown 3863/tcp 0.000152 -unknown 3868/tcp 0.000076 +asap-tcp 3863/tcp 0.000152 # RSerPool ASAP (TCP) +asap-udp 3863/udp # RSerPool ASAP (UDP) +asap-sctp 3863/sctp # RSerPool ASAP (SCTP) +asap-tcp-tls 3864/tcp # RSerPool ASAP/TLS (TCP) +asap-sctp-tls 3864/sctp # RSerPool ASAP/TLS (SCTP) +diameter 3868/tcp 0.000076 # DIAMETER +diameter 3868/sctp # DIAMETER unknown 3869/tcp 0.000228 unknown 3869/udp 0.000330 unknown 3870/tcp 0.000152 @@ -4048,6 +4074,12 @@ unknown 4713/udp 0.000330 unknown 4726/udp 0.000330 unknown 4734/udp 0.000330 +ipfix 4739/tcp # IP Flow Info Export +ipfix 4739/udp # IP Flow Info Export +ipfix 4739/sctp # IP Flow Info Export +ipfixs 4740/tcp # IP Flow Info Export over TLS +ipfixs 4740/udp # IP Flow Info Export over DTLS +ipfixs 4740/sctp # IP Flow Info Export over DTLS unknown 4741/udp 0.000330 unknown 4743/udp 0.000330 unknown 4745/tcp 0.000076 @@ -4184,6 +4216,7 @@ unknown 5059/udp 0.000330 sip 5060/tcp 0.010613 # Session Initiation Protocol (SIP) sip 5060/udp 0.044350 # Session Initiation Protocol (SIP) +sip 5060/sctp # Session Initiation Protocol (SIP) unknown 5061/tcp 0.000228 unknown 5061/udp 0.000330 unknown 5063/tcp 0.000152 @@ -4202,6 +4235,8 @@ unknown 5088/tcp 0.000076 unknown 5090/tcp 0.000076 unknown 5090/udp 0.000330 +car 5090/sctp # Candidate AR +cxtp 5091/sctp # Context Transfer Protocol unknown 5093/udp 0.003304 unknown 5094/udp 0.000330 unknown 5095/tcp 0.000076 @@ -4435,7 +4470,12 @@ unknown 5666/tcp 0.006614 unknown 5667/tcp 0.000076 unknown 5667/udp 0.000330 -unknown 5672/tcp 0.000076 +amqp 5672/tcp 0.000076 # AMQP +amqp 5672/udp # AMQP +amqp 5672/sctp # AMQP +v5ua 5675/tcp # V5UA application port +v5ua 5675/udp # V5UA application port +v5ua 5675/sctp # V5UA application port unknown 5678/tcp 0.000228 activesync 5679/tcp 0.000590 # Microsoft ActiveSync PDY synchronization canna 5680/tcp 0.000151 # Canna (Japanese Input) @@ -5133,6 +5173,7 @@ unknown 7613/udp 0.000661 unknown 7617/udp 0.000330 unknown 7625/tcp 0.000380 +simco 7626/sctp # SImple Middlebox COnfiguration (SIMCO) unknown 7627/tcp 0.000380 unknown 7628/tcp 0.000076 unknown 7630/udp 0.000330 @@ -5432,8 +5473,9 @@ unknown 8458/udp 0.000330 unknown 8468/udp 0.000330 unknown 8470/tcp 0.000076 -unknown 8471/tcp 0.000076 -unknown 8471/udp 0.000330 +pim-port 8471/tcp 0.000076 # PIM over Reliable Transport +pim-port 8471/udp 0.000330 # PIM over Reliable Transport +pim-port 8471/sctp # PIM over Reliable Transport unknown 8472/tcp 0.000076 unknown 8473/udp 0.000330 unknown 8474/tcp 0.000076 @@ -5624,7 +5666,9 @@ unknown 9080/tcp 0.000380 unknown 9080/udp 0.000330 unknown 9081/tcp 0.000228 -unknown 9084/tcp 0.000076 +aurora 9084/tcp 0.000076 # IBM AURORA Performance Visualizer +aurora 9084/udp # IBM AURORA Performance Visualizer +aurora 9084/sctp # IBM AURORA Performance Visualizer unknown 9085/udp 0.000330 unknown 9086/udp 0.000330 unknown 9088/udp 0.000330 @@ -5890,8 +5934,15 @@ unknown 9894/udp 0.000330 unknown 9897/udp 0.000661 unknown 9898/tcp 0.000228 -unknown 9900/tcp 0.000380 +sctp-tunneling 9899/udp # SCTP Tunneling +sctp-tunneling 9899/tcp # SCTP Tunneling +iua 9900/tcp 0.000380 # IUA +iua 9900/udp # IUA +iua 9900/sctp # IUA unknown 9901/tcp 0.000076 +enrp 9901/udp # ENRP server channel +enrp-sctp 9901/sctp # ENRP server channel +enrp-sctp-tls 9902/sctp # ENRP/TLS server channel unknown 9908/tcp 0.000076 unknown 9909/tcp 0.000076 unknown 9910/tcp 0.000076 @@ -6369,6 +6420,9 @@ unknown 11997/udp 0.000330 unknown 11998/udp 0.000330 unknown 11999/udp 0.000330 +wmereceiving 11997/sctp # WorldMailExpress +wmedistribution 11998/sctp # WorldMailExpress +wmereporting 11999/sctp # WorldMailExpress cce4x 12000/tcp 0.000427 # ClearCommerce Engine 4.x (www.clearcommerce.com) unknown 12000/udp 0.000661 unknown 12001/tcp 0.000076 @@ -6807,7 +6861,8 @@ unknown 13992/udp 0.000330 unknown 13996/udp 0.000330 unknown 14000/tcp 0.000380 -unknown 14001/tcp 0.000076 +sua 14001/tcp 0.000076 # SUA +sua 14001/sctp # SUA unknown 14006/udp 0.000330 unknown 14034/udp 0.000330 unknown 14035/udp 0.000330 @@ -8369,6 +8424,9 @@ unknown 20041/udp 0.000654 unknown 20045/udp 0.000654 unknown 20048/udp 0.000654 +nfsrdma 20049/tcp # Network File System (NFS) over RDMA +nfsrdma 20049/udp # Network File System (NFS) over RDMA +nfsrdma 20049/sctp # Network File System (NFS) over RDMA unknown 20052/tcp 0.000076 unknown 20055/udp 0.000654 unknown 20056/udp 0.000654 Index: nse_main.cc =================================================================== --- nse_main.cc (revision 11639) +++ nse_main.cc (working copy) @@ -648,15 +648,15 @@ /* because of the port iteration API we need to awkwardly iterate * over the kinds of ports we're interested in explictely. */ current = NULL; - while((current = plist->nextPort(current, TCPANDUDP, PORT_OPEN)) != NULL) { + while((current = plist->nextPort(current, TCPANDUDPANDSCTP, PORT_OPEN)) != NULL) { SCRIPT_ENGINE_TRY(process_pickScriptsForPort(L, target, current, torun_threads)); } - while((current = plist->nextPort(current, TCPANDUDP, PORT_OPENFILTERED)) != NULL) { + while((current = plist->nextPort(current, TCPANDUDPANDSCTP, PORT_OPENFILTERED)) != NULL) { SCRIPT_ENGINE_TRY(process_pickScriptsForPort(L, target, current, torun_threads)); } - while((current = plist->nextPort(current, TCPANDUDP, PORT_UNFILTERED)) != NULL) { + while((current = plist->nextPort(current, TCPANDUDPANDSCTP, PORT_UNFILTERED)) != NULL) { SCRIPT_ENGINE_TRY(process_pickScriptsForPort(L, target, current, torun_threads)); } Index: output.h =================================================================== --- output.h (revision 11639) +++ output.h (working copy) @@ -180,7 +180,7 @@ in sequential order for space savings and easier to read output */ void output_ports_to_machine_parseable_output(struct scan_lists *ports, int tcpscan, int udpscan, - int protscan); + int sctpscan, int protscan); /* Similar to output_ports_to_machine_parseable_output, this function outputs the XML version, which is scaninfo records of each scan Index: CHANGELOG =================================================================== --- CHANGELOG (revision 11639) +++ CHANGELOG (working copy) @@ -1,5 +1,11 @@ # Nmap Changelog ($Id$); -*-text-*- +o Added experimental support for SCTP port scanning. SCTP INIT + (stealth) scans work, as does IP protocol scan for SCTP, but + support for SCTP is otherwise still very much incomplete. An + initial list of 36 well-known SCTP ports has been added to Nmap's + services database. [Daniel Roethlisberger] + o When a system route can't be matched up directly with an interface by comparing addresses, Nmap now tries to match the route through another route. This helps for instance with a PPP connection where Index: docs/nmap.dtd =================================================================== --- docs/nmap.dtd (revision 11639) +++ docs/nmap.dtd (working copy) @@ -58,11 +58,11 @@ - + - +