diff --git a/Makefile.in b/Makefile.in index d4646883a..f0b3b7f03 100644 --- a/Makefile.in +++ b/Makefile.in @@ -91,11 +91,11 @@ NSE_OBJS+=nse_openssl.o nse_ssl_cert.o endif endif -export SRCS = main.cc nmap.cc targets.cc tcpip.cc nmap_error.cc utils.cc idle_scan.cc osscan.cc osscan2.cc output.cc payload.cc scan_engine.cc timing.cc charpool.cc services.cc protocols.cc nmap_rpc.cc portlist.cc NmapOps.cc TargetGroup.cc Target.cc FingerPrintResults.cc service_scan.cc NmapOutputTable.cc MACLookup.cc nmap_tty.cc nmap_dns.cc traceroute.cc portreasons.cc $(NSE_SRC) @COMPAT_SRCS@ +export SRCS = main.cc nmap.cc targets.cc tcpip.cc nmap_error.cc utils.cc idle_scan.cc osscan.cc osscan2.cc output.cc payload.cc scan_engine.cc timing.cc charpool.cc services.cc protocols.cc nmap_rpc.cc portlist.cc NmapOps.cc TargetGroup.cc Target.cc FingerPrintResults.cc service_scan.cc NmapOutputTable.cc MACLookup.cc nmap_tty.cc nmap_dns.cc traceroute.cc portreasons.cc xml.cc $(NSE_SRC) @COMPAT_SRCS@ -export HDRS = charpool.h FingerPrintResults.h global_structures.h idle_scan.h MACLookup.h nmap_amigaos.h nmap_dns.h nmap_error.h nmap.h NmapOps.h NmapOutputTable.h nmap_rpc.h nmap_tty.h nmap_winconfig.h osscan.h osscan2.h output.h payload.h portlist.h protocols.h scan_engine.h service_scan.h services.h TargetGroup.h Target.h targets.h tcpip.h timing.h utils.h traceroute.h portreasons.h $(NSE_HDRS) +export HDRS = charpool.h FingerPrintResults.h global_structures.h idle_scan.h MACLookup.h nmap_amigaos.h nmap_dns.h nmap_error.h nmap.h NmapOps.h NmapOutputTable.h nmap_rpc.h nmap_tty.h nmap_winconfig.h osscan.h osscan2.h output.h payload.h portlist.h protocols.h scan_engine.h service_scan.h services.h TargetGroup.h Target.h targets.h tcpip.h timing.h utils.h traceroute.h portreasons.h xml.h $(NSE_HDRS) -OBJS = main.o nmap.o targets.o tcpip.o nmap_error.o utils.o idle_scan.o osscan.o osscan2.o output.o payload.o scan_engine.o timing.o charpool.o services.o protocols.o nmap_rpc.o portlist.o NmapOps.o TargetGroup.o Target.o FingerPrintResults.o service_scan.o NmapOutputTable.o MACLookup.o nmap_tty.o nmap_dns.o traceroute.o portreasons.o $(NSE_OBJS) @COMPAT_OBJS@ +OBJS = main.o nmap.o targets.o tcpip.o nmap_error.o utils.o idle_scan.o osscan.o osscan2.o output.o payload.o scan_engine.o timing.o charpool.o services.o protocols.o nmap_rpc.o portlist.o NmapOps.o TargetGroup.o Target.o FingerPrintResults.o service_scan.o NmapOutputTable.o MACLookup.o nmap_tty.o nmap_dns.o traceroute.o portreasons.o xml.o $(NSE_OBJS) @COMPAT_OBJS@ # %.o : %.cc -- nope this is a GNU extension .cc.o: diff --git a/NmapOps.cc b/NmapOps.cc index 9cb965c4d..2b234db9d 100644 --- a/NmapOps.cc +++ b/NmapOps.cc @@ -157,7 +157,7 @@ const struct in_addr *NmapOps::v4sourceip() { // Number of milliseconds since getStartTime(). The current time is an // optional argument to avoid an extra gettimeofday() call. -int NmapOps::TimeSinceStartMS(struct timeval *now) { +int NmapOps::TimeSinceStartMS(const struct timeval *now) { struct timeval tv; if (!now) gettimeofday(&tv, NULL); diff --git a/NmapOps.h b/NmapOps.h index 7629b9fff..9b8414e07 100644 --- a/NmapOps.h +++ b/NmapOps.h @@ -115,7 +115,7 @@ class NmapOps { const struct timeval *getStartTime() { return &start_time; } // Number of milliseconds since getStartTime(). The current time is an // optional argument to avoid an extra gettimeofday() call. - int TimeSinceStartMS(struct timeval *now=NULL); + int TimeSinceStartMS(const struct timeval *now=NULL); struct in_addr v4source(); const struct in_addr *v4sourceip(); diff --git a/NmapOutputTable.h b/NmapOutputTable.h index 55f1becb3..6297b4b85 100644 --- a/NmapOutputTable.h +++ b/NmapOutputTable.h @@ -95,10 +95,6 @@ #include "nmap.h" -#ifndef __attribute__ -#define __attribute__(args) -#endif - /********************** DEFINES/ENUMS ***********************************/ /********************** STRUCTURES ***********************************/ @@ -131,7 +127,7 @@ class NmapOutputTable { // Like addItem except this version takes a printf-style format string followed by varargs void addItemFormatted(unsigned int row, unsigned int column, bool fullrow, const char *fmt, ...) - __attribute__ ((format (printf, 4, 5))); + __attribute__ ((format (printf, 5, 6))); // Offset by 1 to account for implicit "this" parameter. // This function sticks the entire table into a character buffer. // Note that the buffer is likely to be reused if you call the diff --git a/docs/nmap.dtd b/docs/nmap.dtd index 502af1472..41bde3a53 100644 --- a/docs/nmap.dtd +++ b/docs/nmap.dtd @@ -313,12 +313,15 @@ - + diff --git a/mswin32/nmap.vcproj b/mswin32/nmap.vcproj index f53908395..737bca9c9 100644 --- a/mswin32/nmap.vcproj +++ b/mswin32/nmap.vcproj @@ -366,6 +366,10 @@ RelativePath="..\utils.cc" > + + @@ -559,6 +563,10 @@ RelativePath="..\utils.h" > + + diff --git a/nmap.cc b/nmap.cc index f8c628549..9cbfacec0 100644 --- a/nmap.cc +++ b/nmap.cc @@ -109,6 +109,7 @@ #include "charpool.h" #include "nmap_error.h" #include "utils.h" +#include "xml.h" #ifndef NOLUA #include "nse_main.h" @@ -1565,39 +1566,53 @@ int nmap_main(int argc, char *argv[]) { Strncpy(mytime, ctime(&timep), sizeof(mytime)); chomp(mytime); char *xslfname = o.XSLStyleSheet(); - char xslline[1024]; + xml_start_document(); if (xslfname) { - char *p = xml_convert(xslfname); - Snprintf(xslline, sizeof(xslline), "\n", p); - free(p); - } else xslline[0] = '\0'; - log_write(LOG_XML, "\n%s"); - log_write(LOG_NORMAL|LOG_MACHINE|LOG_XML,"\n"); - - log_write(LOG_XML, "\n", - (unsigned long) timep, mytime, NMAP_VERSION); + xml_open_start_tag("nmaprun"); + xml_attribute("scanner", "nmap"); + xml_attribute("args", "%s", command.c_str()); + xml_attribute("start", "%lu", (unsigned long) timep); + xml_attribute("startstr", "%s", mytime); + xml_attribute("version", "%s", NMAP_VERSION); + xml_attribute("xmloutputversion", "1.03"); + xml_close_start_tag(); + xml_newline(); output_xml_scaninfo_records(&ports); - log_write(LOG_XML, "\n\n", - o.verbose, o.debugging); + xml_open_start_tag("verbose"); + xml_attribute("level", "%d", o.verbose); + xml_close_empty_tag(); + xml_newline(); + xml_open_start_tag("debugging"); + xml_attribute("level", "%d", o.debugging); + xml_close_empty_tag(); + xml_newline(); /* Before we randomize the ports scanned, lets output them to machine parseable output */ @@ -1740,13 +1755,14 @@ int nmap_main(int argc, char *argv[]) { #endif ) || o.listscan) { /* We're done with the hosts */ - log_write(LOG_XML, ""); + xml_start_tag("host"); write_host_header(currenths); printmacinfo(currenths); // if (currenths->flags & HOST_UP) // log_write(LOG_PLAIN,"\n"); printtimes(currenths); - log_write(LOG_XML, "\n"); + xml_end_tag(); + xml_newline(); log_flush_all(); delete currenths; o.numhosts_scanned++; @@ -1762,9 +1778,10 @@ int nmap_main(int argc, char *argv[]) { rare cases, such IPs CAN be port successfully scanned and even connected to */ if (!(currenths->flags & HOST_UP)) { if (o.verbose && (!o.openOnly() || currenths->ports.hasOpenPorts())) { - log_write(LOG_XML, ""); + xml_start_tag("host"); write_host_header(currenths); - log_write(LOG_XML, "\n"); + xml_end_tag(); + xml_newline(); } delete currenths; o.numhosts_scanned++; @@ -1920,9 +1937,10 @@ int nmap_main(int argc, char *argv[]) { if (o.openOnly() && !currenths->ports.hasOpenPorts()) continue; - log_write(LOG_XML, "", - (unsigned long) currenths->StartTime(), - (unsigned long) currenths->EndTime()); + xml_open_start_tag("host"); + xml_attribute("starttime", "%lu", (unsigned long) currenths->StartTime()); + xml_attribute("endtime", "%lu", (unsigned long) currenths->EndTime()); + xml_close_start_tag(); write_host_header(currenths); printportoutput(currenths, ¤ths->ports); printmacinfo(currenths); @@ -1935,7 +1953,8 @@ int nmap_main(int argc, char *argv[]) { printtraceroute(currenths); printtimes(currenths); log_write(LOG_PLAIN|LOG_MACHINE,"\n"); - log_write(LOG_XML, "\n"); + xml_end_tag(); /* host */ + xml_newline(); } } log_flush_all(); diff --git a/nmap_error.cc b/nmap_error.cc index 082059a47..043c54f40 100644 --- a/nmap_error.cc +++ b/nmap_error.cc @@ -92,6 +92,7 @@ #include "nmap_error.h" #include "output.h" #include "NmapOps.h" +#include "xml.h" extern NmapOps o; @@ -99,8 +100,15 @@ extern NmapOps o; #include #endif /* WIN32 */ + void fatal(const char *fmt, ...) { + time_t timep; + struct timeval tv; va_list ap; + + gettimeofday(&tv, NULL); + timep = time(NULL); + va_start(ap, fmt); log_vwrite(LOG_STDERR, fmt, ap); va_end(ap); @@ -110,6 +118,37 @@ void fatal(const char *fmt, ...) { va_end(ap); } log_write(o.log_errors? LOG_NORMAL|LOG_STDERR : LOG_STDERR, "\nQUITTING!\n"); + + if (!xml_root_written()) + xml_start_tag("nmaprun"); + /* Close all open XML elements but one. */ + while (xml_depth() > 1) { + xml_end_tag(); + xml_newline(); + } + if (xml_depth() == 1) { + char errbuf[1024]; + + va_start(ap, fmt); + Vsnprintf(errbuf, sizeof(errbuf), fmt, ap); + va_end(ap); + + xml_start_tag("runstats"); + print_xml_finished_open(timep, &tv); + xml_attribute("exit", "error"); + xml_attribute("errormsg", "%s", errbuf); + xml_close_empty_tag(); + + print_xml_hosts(); + xml_newline(); + + xml_end_tag(); /* runstats */ + xml_newline(); + + xml_end_tag(); /* nmaprun */ + xml_newline(); + } + exit(1); } @@ -129,72 +168,93 @@ void error(const char *fmt, ...) { return; } -void pfatal(const char *err, ...) { -#ifdef WIN32 - int lasterror =0; - char *errstr = NULL; -#endif +void pfatal(const char *fmt, ...) { + time_t timep; + struct timeval tv; va_list ap; - - va_start(ap, err); - log_vwrite(LOG_STDERR, err, ap); + int error_number; + char errbuf[1024], *strerror_s; + +#ifdef WIN32 + error_number = GetLastError(); + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM, + NULL, error_number, MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR) &strerror_s, 0, NULL); +#else + error_number = errno; + strerror_s = strerror(error_number); +#endif + + gettimeofday(&tv, NULL); + timep = time(NULL); + + va_start(ap, fmt); + Vsnprintf(errbuf, sizeof(errbuf), fmt, ap); va_end(ap); - if (o.log_errors) { - va_start(ap, err); - log_vwrite(LOG_NORMAL, err, ap); - va_end(ap); + log_write(o.log_errors? LOG_NORMAL|LOG_STDERR : LOG_STDERR, "%s: %s (%d)\n", + errbuf, strerror_s, error_number); + + if (!xml_root_written()) + xml_start_tag("nmaprun"); + /* Close all open XML elements but one. */ + while (xml_depth() > 1) { + xml_end_tag(); + xml_newline(); + } + if (xml_depth() == 1) { + xml_start_tag("runstats"); + print_xml_finished_open(timep, &tv); + xml_attribute("exit", "error"); + xml_attribute("errormsg", "%s: %s (%d)", errbuf, strerror_s, error_number); + xml_close_empty_tag(); + + print_xml_hosts(); + xml_newline(); + + xml_end_tag(); /* runstats */ + xml_newline(); + + xml_end_tag(); /* nmaprun */ + xml_newline(); } #ifdef WIN32 - lasterror = GetLastError(); - FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM, - NULL, lasterror, MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPTSTR) &errstr, 0, NULL); - log_write(o.log_errors? LOG_NORMAL|LOG_STDERR : LOG_STDERR, ": %s (%d)\n", - errstr, lasterror); - HeapFree(GetProcessHeap(), 0, errstr); -#else - log_write(o.log_errors? LOG_NORMAL|LOG_STDERR : LOG_STDERR, ": %s (%d)\n", - strerror(errno), errno); -#endif /* WIN32 perror() compatability switch */ + HeapFree(GetProcessHeap(), 0, strerror_s); +#endif + if (o.log_errors) log_flush(LOG_NORMAL); fflush(stderr); exit(1); } -/* This function is the Nmap version of perror. It is just copy and - pasted from pfatal(), except the exit has been replaced with a - return. */ -void gh_perror(const char *err, ...) { -#ifdef WIN32 - int lasterror =0; - char *errstr = NULL; -#endif +/* This function is the Nmap version of perror. It is like pfatal, but it + doesn't write to XML and it only returns, doesn't exit. */ +void gh_perror(const char *fmt, ...) { va_list ap; - - va_start(ap, err); - log_vwrite(LOG_STDERR, err, ap); - va_end(ap); - - if (o.log_errors) { - va_start(ap, err); - log_vwrite(LOG_NORMAL, err, ap); - va_end(ap); - } + int error_number; + char *strerror_s; #ifdef WIN32 - lasterror = GetLastError(); + error_number = GetLastError(); FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM, - NULL, lasterror, MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPTSTR) &errstr, 0, NULL); - log_write(o.log_errors? LOG_NORMAL|LOG_STDERR : LOG_STDERR, ": %s (%d)\n", - errstr, lasterror); - HeapFree(GetProcessHeap(), 0, errstr); + NULL, error_number, MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR) &strerror_s, 0, NULL); #else - log_write(o.log_errors? LOG_NORMAL|LOG_STDERR : LOG_STDERR, ": %s (%d)\n", - strerror(errno), errno); -#endif /* WIN32 perror() compatability switch */ + error_number = errno; + strerror_s = strerror(error_number); +#endif + + va_start(ap, fmt); + log_vwrite(o.log_errors? LOG_NORMAL|LOG_STDERR : LOG_STDERR, fmt, ap); + va_end(ap); + log_write(o.log_errors? LOG_NORMAL|LOG_STDERR : LOG_STDERR, ": %s (%d)\n", + strerror_s, error_number); + +#ifdef WIN32 + HeapFree(GetProcessHeap(), 0, strerror_s); +#endif + if (o.log_errors) log_flush(LOG_NORMAL); fflush(stderr); return; diff --git a/output.cc b/output.cc index a02f00a88..d7728eb5c 100644 --- a/output.cc +++ b/output.cc @@ -104,6 +104,7 @@ #include "nmap_rpc.h" #include "Target.h" #include "utils.h" +#include "xml.h" #include @@ -171,7 +172,7 @@ static void skid_output(char *s) { } /* Remove all "\nSF:" from fingerprints */ -static char *xml_sf_convert(const char *str) { +static char *servicefp_sf_remove(const char *str) { char *temp = (char *) safe_malloc(strlen(str) + 1); char *dst = temp, *src = (char *) str; char *ampptr = 0; @@ -197,106 +198,44 @@ static char *xml_sf_convert(const char *str) { return temp; } -// Creates an XML element for the information given in +// Prints an XML element for the information given in // serviceDeduction. This function should only be called if ether // the service name or the service fingerprint is non-null. -// Returns a pointer to a buffer containing the element, -// you will have to call free on it. -static char *getServiceXMLBuf(const struct serviceDeductions *sd) { - string versionxmlstring = ""; - char rpcbuf[128]; - char confBuf[20]; - char *xml_product = NULL, *xml_version = NULL, *xml_extrainfo = NULL; - char *xml_hostname = NULL, *xml_ostype = NULL, *xml_devicetype = NULL; - char *xml_servicefp = NULL, *xml_servicefp_temp = NULL; - - versionxmlstring = "name ? sd->name : "unknown"; - versionxmlstring += "\""; - if (sd->product) { - xml_product = xml_convert(sd->product); - versionxmlstring += " product=\""; - versionxmlstring += xml_product; - free(xml_product); - xml_product = NULL; - versionxmlstring += '\"'; - } - - if (sd->version) { - xml_version = xml_convert(sd->version); - versionxmlstring += " version=\""; - versionxmlstring += xml_version; - free(xml_version); - xml_version = NULL; - versionxmlstring += '\"'; - } - - if (sd->extrainfo) { - xml_extrainfo = xml_convert(sd->extrainfo); - versionxmlstring += " extrainfo=\""; - versionxmlstring += xml_extrainfo; - free(xml_extrainfo); - xml_extrainfo = NULL; - versionxmlstring += '\"'; - } - - if (sd->hostname) { - xml_hostname = xml_convert(sd->hostname); - versionxmlstring += " hostname=\""; - versionxmlstring += xml_hostname; - free(xml_hostname); - xml_hostname = NULL; - versionxmlstring += '\"'; - } - - if (sd->ostype) { - xml_ostype = xml_convert(sd->ostype); - versionxmlstring += " ostype=\""; - versionxmlstring += xml_ostype; - free(xml_ostype); - xml_ostype = NULL; - versionxmlstring += '\"'; - } - - if (sd->devicetype) { - xml_devicetype = xml_convert(sd->devicetype); - versionxmlstring += " devicetype=\""; - versionxmlstring += xml_devicetype; - free(xml_devicetype); - xml_devicetype = NULL; - versionxmlstring += '\"'; - } +static void print_xml_service(const struct serviceDeductions *sd) { + xml_open_start_tag("service"); + xml_attribute("name", "%s", sd->name ? sd->name : "unknown"); + if (sd->product) + xml_attribute("product", "%s", sd->product); + if (sd->version) + xml_attribute("version", "%s", sd->version); + if (sd->extrainfo) + xml_attribute("extrainfo", "%s", sd->extrainfo); + if (sd->hostname) + xml_attribute("hostname", "%s", sd->hostname); + if (sd->ostype) + xml_attribute("ostype", "%s", sd->ostype); + if (sd->devicetype) + xml_attribute("devicetype", "%s", sd->devicetype); if (sd->service_fp) { - xml_servicefp_temp = xml_convert(sd->service_fp); - xml_servicefp = xml_sf_convert(xml_servicefp_temp); - versionxmlstring += " servicefp=\""; - versionxmlstring += xml_servicefp; - free(xml_servicefp_temp); - xml_servicefp_temp = NULL; - free(xml_servicefp); - xml_servicefp = NULL; - versionxmlstring += '\"'; + char *servicefp = servicefp_sf_remove(sd->service_fp); + xml_attribute("servicefp", "%s", servicefp); + free(servicefp); } + if (sd->service_tunnel == SERVICE_TUNNEL_SSL) + xml_attribute("tunnel", "ssl"); + xml_attribute("method", "%s", (sd->dtype == SERVICE_DETECTION_TABLE) ? "table" : "probed"); + xml_attribute("conf", "%i", sd->name_confidence); + if (o.rpcscan && sd->rpc_status == RPC_STATUS_GOOD_PROG) { - Snprintf(rpcbuf, sizeof(rpcbuf), - " rpcnum=\"%li\" lowver=\"%i\" highver=\"%i\" proto=\"rpc\"", - sd->rpc_program, sd->rpc_lowver, sd->rpc_highver); - } else - rpcbuf[0] = '\0'; + xml_attribute("rpcnum", "%li", sd->rpc_program); + xml_attribute("lowver", "%i", sd->rpc_lowver); + xml_attribute("highver", "%i", sd->rpc_highver); + xml_attribute("proto", "rpc"); + } - versionxmlstring += " "; - versionxmlstring += (sd->service_tunnel == SERVICE_TUNNEL_SSL) ? "tunnel=\"ssl\" " : ""; - versionxmlstring += "method=\""; - versionxmlstring += (sd->dtype == SERVICE_DETECTION_TABLE) ? "table" : "probed"; - versionxmlstring += "\" conf=\""; - Snprintf(confBuf, 20, "%i", sd->name_confidence); - versionxmlstring += confBuf; - versionxmlstring += "\""; - versionxmlstring += rpcbuf; - versionxmlstring += " />"; - return strdup(versionxmlstring.c_str()); + xml_close_empty_tag(); } #ifdef WIN32 @@ -514,7 +453,6 @@ void printportoutput(Target * currenths, PortList * plist) { char portinfo[64]; char grepvers[256]; char *p; - char *xmlBuf = NULL; const char *state; char serviceinfo[64]; char *name = NULL; @@ -542,15 +480,19 @@ void printportoutput(Target * currenths, PortList * plist) { if (o.noportscan) return; - log_write(LOG_XML, ""); + xml_start_tag("ports"); int prevstate = PORT_UNKNOWN; int istate; while ((istate = plist->nextIgnoredState(prevstate)) != PORT_UNKNOWN) { - log_write(LOG_XML, "\n", - statenum2str(istate), plist->getStateCounts(istate)); + xml_open_start_tag("extraports"); + xml_attribute("state", "%s", statenum2str(istate)); + xml_attribute("count", "%d", plist->getStateCounts(istate)); + xml_close_start_tag(); + xml_newline(); print_xml_state_summary(plist, istate); - log_write(LOG_XML, "\n"); + xml_end_tag(); + xml_newline(); prevstate = istate; } @@ -583,7 +525,8 @@ void printportoutput(Target * currenths, PortList * plist) { log_write(LOG_MACHINE, "Host: %s (%s)\tStatus: Up", currenths->targetipstr(), currenths->HostName()); - log_write(LOG_XML, "\n"); + xml_end_tag(); /* ports */ + xml_newline(); return; } @@ -688,19 +631,28 @@ void printportoutput(Target * currenths, PortList * plist) { Tbl->addItem(rowno, servicecol, true, portinfo); log_write(LOG_MACHINE, "%d/%s/%s/", current->portno, state, (proto) ? proto->p_name : ""); - log_write(LOG_XML, "" - "portno, state, - reason_str(current->reason.reason_id, SINGULAR), - current->reason.ttl); - + xml_open_start_tag("port"); + xml_attribute("protocol", "ip"); + xml_attribute("portid", "%d", current->portno); + xml_close_start_tag(); + xml_open_start_tag("state"); + xml_attribute("state", "%s", state); + xml_attribute("reason", "%s", reason_str(current->reason.reason_id, SINGULAR)); + xml_attribute("reason_ttl", "%d", current->reason.ttl); if (current->reason.ip_addr.s_addr) - log_write(LOG_XML, " reason_ip=\"%s\"", inet_ntoa(current->reason.ip_addr)); - log_write(LOG_XML, "/>"); + xml_attribute("reason_ip", "%s", inet_ntoa(current->reason.ip_addr)); + xml_close_empty_tag(); - if (proto && proto->p_name && *proto->p_name) - log_write(LOG_XML, "\n", proto->p_name); - log_write(LOG_XML, "\n"); + if (proto && proto->p_name && *proto->p_name) { + xml_newline(); + xml_open_start_tag("service"); + xml_attribute("name", "%s", proto->p_name); + xml_attribute("conf", "8"); + xml_attribute("method", "table"); + xml_close_empty_tag(); + } + xml_end_tag(); /* port */ + xml_newline(); rowno++; } } @@ -797,23 +749,20 @@ void printportoutput(Target * currenths, PortList * plist) { log_write(LOG_MACHINE, "%d/%s/%s//%s/%s/%s/", current->portno, state, protocol, serviceinfo, rpcmachineinfo, grepvers); - log_write(LOG_XML, "", - protocol, current->portno); - log_write(LOG_XML, "reason.reason_id, SINGULAR), - current->reason.ttl); + xml_open_start_tag("port"); + xml_attribute("protocol", "%s", protocol); + xml_attribute("portid", "%d", current->portno); + xml_close_start_tag(); + xml_open_start_tag("state"); + xml_attribute("state", "%s", state); + xml_attribute("reason", "%s", reason_str(current->reason.reason_id, SINGULAR)); + xml_attribute("reason_ttl", "%d", current->reason.ttl); if (current->reason.ip_addr.s_addr) - log_write(LOG_XML, " reason_ip=\"%s\"", inet_ntoa(current->reason.ip_addr)); - log_write(LOG_XML, "/>"); + xml_attribute("reason_ip", "%s", inet_ntoa(current->reason.ip_addr)); + xml_close_empty_tag(); - if (sd.name || sd.service_fp) { - xmlBuf = getServiceXMLBuf(&sd); - if (xmlBuf) { - log_write(LOG_XML, "%s", xmlBuf); - free(xmlBuf); - xmlBuf = NULL; - } - } + if (sd.name || sd.service_fp) + print_xml_service(&sd); rowno++; #ifndef NOLUA @@ -822,13 +771,10 @@ void printportoutput(Target * currenths, PortList * plist) { for (ssr_iter = current->scriptResults.begin(); ssr_iter != current->scriptResults.end(); ssr_iter++) { - char *xml_id = xml_convert(ssr_iter->get_id().c_str()); - char *xml_scriptoutput = - xml_convert(ssr_iter->get_output().c_str()); - log_write(LOG_XML, "