Index: CHANGELOG =================================================================== --- CHANGELOG (revision 13566) +++ CHANGELOG (working copy) @@ -1,5 +1,12 @@ # Nmap Changelog ($Id$); -*-text-*- +o [Nsock] [Ncat] Implemented basic SCTP client functionality. Only the + default SCTP stream is used. This is also called TCP compatible mode. + While it allows Ncat to be used for manually probing open SCTP ports, + more complicated services making use of multiple streams or depending + on specific message boundaries cannot be talked to successfully. + [Daniel Roethlisberger] + o Rewrote the port list merging code in validate_scan_lists to be more maintainable [Josh Marlow] Index: nsock/include/nsock.h =================================================================== --- nsock/include/nsock.h (revision 13566) +++ nsock/include/nsock.h (working copy) @@ -408,6 +408,17 @@ void *userdata, struct sockaddr *ss, size_t sslen, unsigned short port); +/* Request an SCTP association to another system (by IP address). The + in_addr is normal network byte order, but the port number should be + given in HOST BYTE ORDER. ss should be a sockaddr_storage, + sockaddr_in6, or sockaddr_in as appropriate (just like what you + would pass to connect). sslen should be the sizeof the structure + you are passing in. */ +nsock_event_id nsock_connect_sctp(nsock_pool nsp, nsock_iod nsiod, + nsock_ev_handler handler, int timeout_msecs, + void *userdata, struct sockaddr *ss, + size_t sslen, unsigned short port); + /* Request a UDP "connection" to another system (by IP address). The in_addr is normal network byte order, but the port number should be given in HOST BYTE ORDER. Since this is UDP, no packets are Index: nsock/src/nsock_config.h.in =================================================================== --- nsock/src/nsock_config.h.in (revision 13566) +++ nsock/src/nsock_config.h.in (working copy) @@ -63,6 +63,8 @@ #undef SPRINTF_RETURNS_STRING +#undef HAVE_SCTP + #undef DEC #undef LINUX #undef FREEBSD Index: nsock/src/configure.ac =================================================================== --- nsock/src/configure.ac (revision 13566) +++ nsock/src/configure.ac (working copy) @@ -138,6 +138,11 @@ dnl Checks for header files. AC_HEADER_STDC +dnl SCTP support +AC_CHECK_HEADER([netinet/sctp.h], + [AC_DEFINE([HAVE_SCTP], 1, + [Define to 1 if you have SCTP support.])]) + dnl Checks for typedefs, structures, and compiler characteristics. AC_ARG_WITH(libnbase, Index: nsock/src/nsock_connect.c =================================================================== --- nsock/src/nsock_connect.c (revision 13566) +++ nsock/src/nsock_connect.c (working copy) @@ -129,7 +129,7 @@ else { int err = socket_errno(); - if (proto != IPPROTO_TCP || (err != EINPROGRESS && err != EAGAIN)) { + if (proto == IPPROTO_UDP || (err != EINPROGRESS && err != EAGAIN)) { nse->event_done = 1; nse->status = NSE_STATUS_ERROR; nse->errnum = err; @@ -174,6 +174,46 @@ return nse->id; } +/* Request an SCTP association to another system (by IP address). The + in_addr is normal network byte order, but the port number should be + given in HOST BYTE ORDER. ss should be a sockaddr_storage, + sockaddr_in6, or sockaddr_in as appropriate (just like what you + would pass to connect). sslen should be the sizeof the structure + you are passing in. */ +nsock_event_id nsock_connect_sctp(nsock_pool nsp, nsock_iod ms_iod, + nsock_ev_handler handler, int timeout_msecs, + void *userdata, struct sockaddr *saddr, + size_t sslen, unsigned short port) { + +#ifndef HAVE_SCTP + fatal("nsock_connect_sctp called - but nsock was built w/o SCTP support. QUITTING"); + return (nsock_event_id) 0; /* UNREACHED */ +#else + msiod *nsi = (msiod *) ms_iod; + mspool *ms = (mspool *) nsp; + msevent *nse; + struct sockaddr_storage *ss = (struct sockaddr_storage *) saddr; + + assert(nsi->state == NSIOD_STATE_INITIAL || nsi->state == NSIOD_STATE_UNKNOWN); + + /* Just in case someone waits a long time and then does a new connect */ + gettimeofday(&nsock_tod, NULL); + + nse = msevent_new(ms, NSE_TYPE_CONNECT, nsi, timeout_msecs, handler, userdata); + assert(nse); + + if (ms->tracelevel > 0) + nsock_trace(ms, "SCTP association requested to %s:%hu (IOD #%li) EID %li", + inet_ntop_ez(ss, sslen), port, nsi->id, nse->id); + + /* Do the actual connect() */ + nsock_connect_internal(ms, nse, IPPROTO_SCTP, ss, sslen, port); + nsp_add_event(ms, nse); + + return nse->id; +#endif /* HAVE_SCTP */ +} + /* Request an SSL over TCP connection to another system (by IP address). The in_addr is normal network byte order, but the port number should be given in HOST BYTE ORDER. This function will call Index: ncat/ncat_connect.c =================================================================== --- ncat/ncat_connect.c (revision 13566) +++ ncat/ncat_connect.c (working copy) @@ -185,6 +185,14 @@ inet_port(&targetss), cs.ssl_session); } #endif +#ifdef HAVE_SCTP + else if (o.sctp) { + ev = nsock_connect_sctp(mypool, cs.sock_nsi, connect_evt_handler, + o.conntimeout, &cs, + (struct sockaddr *) &targetss, targetsslen, + inet_port(&targetss)); + } +#endif else { ev = nsock_connect_tcp(mypool, cs.sock_nsi, connect_evt_handler, o.conntimeout, &cs, Index: ncat/configure =================================================================== --- ncat/ncat_core.h (revision 13566) +++ ncat/ncat_core.h (working copy) @@ -26,6 +26,9 @@ int recvonly; int telnet; int udp; +#ifdef HAVE_SCTP + int sctp; +#endif int linedelay; int chat; int nodns; Index: ncat/docs/ncat.xml =================================================================== --- ncat/docs/ncat.xml (revision 13566) +++ ncat/docs/ncat.xml (working copy) @@ -101,9 +101,21 @@ (Ncat option) - Use UDP for the connection (the default is TCP) + Use UDP for the connection (the default is TCP). + + + + (Use SCTP) + (Ncat option) + + + Use SCTP for the connection (the default is TCP). + SCTP support is implemented in TCP compatible mode. + There is currently no support for SCTP listening sockets. + + Index: ncat/configure.ac =================================================================== --- ncat/configure.ac (revision 13566) +++ ncat/configure.ac (working copy) @@ -50,6 +50,11 @@ AC_SEARCH_LIBS(setsockopt, socket) AC_SEARCH_LIBS(gethostbyname, nsl) +# SCTP support +AC_CHECK_HEADER([netinet/sctp.h], + [AC_DEFINE([HAVE_SCTP], 1, + [Define to 1 if you have SCTP support.])]) + # If they didn't specify it, we try to find it if test "$use_openssl" = "yes" -a -z "$specialssldir" ; then AC_CHECK_HEADER(openssl/ssl.h,, Index: ncat/ncat_main.c =================================================================== --- ncat/ncat_main.c (revision 13566) +++ ncat/ncat_main.c (working copy) @@ -169,6 +169,9 @@ {"allowfile", required_argument, NULL, 0}, {"telnet", no_argument, NULL, 't'}, {"udp", no_argument, NULL, 'u'}, +#ifdef HAVE_SCTP + {"sctp", no_argument, &o.sctp, 1}, +#endif {"version", no_argument, NULL, 0}, {"verbose", no_argument, NULL, 'v'}, {"wait", required_argument, NULL, 'w'}, @@ -390,6 +393,9 @@ printf(" -n, --nodns Do not resolve hostnames via DNS\n"); printf(" -t, --telnet Answer Telnet negotiations\n"); printf(" -u, --udp Use UDP instead of default TCP\n"); +#ifdef HAVE_SCTP + printf(" --sctp Use SCTP instead of default TCP\n"); +#endif printf(" -v, --verbose Set verbosity level (can be used up to 3 times)\n"); printf(" -w, --wait