aboutsummaryrefslogtreecommitdiff
path: root/ponymap.c
diff options
context:
space:
mode:
Diffstat (limited to 'ponymap.c')
-rw-r--r--ponymap.c76
1 files changed, 69 insertions, 7 deletions
diff --git a/ponymap.c b/ponymap.c
index bd7dcff..54f9df3 100644
--- a/ponymap.c
+++ b/ponymap.c
@@ -197,9 +197,10 @@ struct target
char ip_string[INET_ADDRSTRLEN]; ///< IP address as a string
char *hostname; ///< Hostname
- /// All units that have ended, successfully finding a service. These don't
- /// hold a reference to us as they're considered a part of this object;
- /// we hold a reference to them.
+ /// All units that have ended, either successfully finding a service, or
+ /// just successful in establishing a connection.
+ /// These don't hold a reference to us as they're considered a part of
+ /// this object; we hold a reference to them.
struct unit *results;
/// All currently running units for this target, holding a reference to us.
@@ -554,10 +555,12 @@ unit_abort (struct unit *u)
// the generator right now, though, as we could spin in a long loop
poller_idle_set (&u->target->ctx->step_event);
- if (u->success)
+ // If the scan has been started, we have successfully connected at least
+ if (u->scan_started || u->success)
{
struct target *target = u->target;
- target->ctx->stats_results++;
+ if (u->success)
+ target->ctx->stats_results++;
// Now we're a part of the target
LIST_PREPEND (target->results, u);
@@ -1314,6 +1317,7 @@ struct target_dump_data
{
struct unit **results; ///< Results sorted by service
size_t results_len; ///< Number of results
+ uint32_t *undetermined; ///< Bitmap of undetermined services
};
static void
@@ -1362,6 +1366,24 @@ target_dump_json (struct target *self, struct target_dump_data *data)
for (size_t k = 0; k < u->info.len; k++)
json_array_append_new (info, json_string (u->info.vector[k]));
}
+
+ json_t *undetermined = json_array ();
+ json_object_set_new (o, "undetermined", undetermined);
+
+ if (!data->undetermined)
+ return;
+
+ size_t block = 8 * sizeof *data->undetermined;
+ for (size_t i = 0; i < 65536 / block; i++)
+ for (size_t k = 0; k < block; k++)
+ {
+ if (!(data->undetermined[i] & (1 << k)))
+ continue;
+
+ service = json_object ();
+ json_object_set_new (service, "port", json_integer (i * block + k));
+ json_array_append_new (undetermined, service);
+ }
}
static void
@@ -1408,6 +1430,24 @@ target_dump_terminal (struct target *self, struct target_dump_data *data)
}
}
+ if (data->undetermined)
+ {
+ *s_tail = service = node_new (xstrdup ("undetermined"));
+ p_tail = &service->children;
+
+ size_t block = 8 * sizeof *data->undetermined;
+ for (size_t i = 0; i < 65536 / block; i++)
+ for (size_t k = 0; k < block; k++)
+ {
+ if (!(data->undetermined[i] & (1 << k)))
+ continue;
+
+ port = *p_tail = node_new (xstrdup_printf
+ ("port %" PRIu16, (uint16_t) (i * block + k)));
+ p_tail = &port->next;
+ }
+ }
+
node_print_tree (root);
node_delete (root);
putchar ('\n');
@@ -1432,20 +1472,42 @@ target_dump_results (struct target *self)
struct app_context *ctx = self->ctx;
struct target_dump_data data;
+ // Equals { successfully connected } \ { any service detected }
+ static uint32_t undetermined[65536 / 32];
+ memset (undetermined, 0, sizeof undetermined);
+
size_t len = 0;
for (struct unit *iter = self->results; iter; iter = iter->next)
- len++;
+ {
+ if (iter->success)
+ len++;
+ else
+ undetermined[iter->port / 32] |= 1 << (iter->port % 32);
+ }
struct unit *sorted[len];
data.results = sorted;
data.results_len = len;
for (struct unit *iter = self->results; iter; iter = iter->next)
- sorted[--len] = iter;
+ if (iter->success)
+ {
+ sorted[--len] = iter;
+ undetermined[iter->port / 32] &= ~(1 << (iter->port % 32));
+ }
// Sort them by service name so that they can be grouped
qsort (sorted, N_ELEMENTS (sorted), sizeof *sorted, unit_cmp_by_order);
+ // Only set the field if there were any undetermined services at all
+ data.undetermined = NULL;
+ for (size_t i = 0; i < N_ELEMENTS (undetermined); i++)
+ if (undetermined[i])
+ {
+ data.undetermined = undetermined;
+ break;
+ }
+
if (ctx->json_results)
target_dump_json (self, &data);
target_dump_terminal (self, &data);