Refactor proto_to_str() function to be thread-safe

Refactor the proto_to_str() function to write the protocol string to a
provided buffer instead of providing a pointer to a static
buffer. This makes it possible to safely use the function in
multi-threaded contexts or call it multiple times before printing the
returned value.

Also rename it to ipproto_to_str(), to clarify that it's for IP
protocols.

Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
This commit is contained in:
Simon Sundberg
2023-10-20 11:27:05 +02:00
parent 0200196244
commit a7972a6f0f

View File

@ -869,21 +869,30 @@ static int format_ipprefix(char *buf, size_t size, int af,
return err; return err;
} }
static const char *proto_to_str(__u16 proto) static char *ipproto_to_str(char *buf, size_t size, __u8 proto)
{ {
static char buf[8]; /* Rather than doing additional checks to ensure we return a null
terminated truncated string, just outright fail if passed buffer
is too small to fit largest possible string */
if (size < 7)
return NULL;
switch (proto) { switch (proto) {
case IPPROTO_TCP: case IPPROTO_TCP:
return "TCP"; strcpy(buf, "TCP");
break;
case IPPROTO_ICMP: case IPPROTO_ICMP:
return "ICMP"; strcpy(buf, "ICMP");
break;
case IPPROTO_ICMPV6: case IPPROTO_ICMPV6:
return "ICMPv6"; strcpy(buf, "ICMPv6");
break;
default: default:
snprintf(buf, sizeof(buf), "%d", proto); snprintf(buf, size, "%d", proto);
return buf; break;
} }
return buf;
} }
static const char *flowevent_to_str(enum flow_event_type fe) static const char *flowevent_to_str(enum flow_event_type fe)
@ -961,17 +970,22 @@ static void print_ns_datetime(FILE *stream, __u64 monotonic_ns)
static void print_event_standard(FILE *stream, const union pping_event *e) static void print_event_standard(FILE *stream, const union pping_event *e)
{ {
char protostr[16];
if (e->event_type == EVENT_TYPE_RTT) { if (e->event_type == EVENT_TYPE_RTT) {
print_ns_datetime(stream, e->rtt_event.timestamp); print_ns_datetime(stream, e->rtt_event.timestamp);
fprintf(stream, " %.6g ms %.6g ms %s ", fprintf(stream, " %.6g ms %.6g ms %s ",
(double)e->rtt_event.rtt / NS_PER_MS, (double)e->rtt_event.rtt / NS_PER_MS,
(double)e->rtt_event.min_rtt / NS_PER_MS, (double)e->rtt_event.min_rtt / NS_PER_MS,
proto_to_str(e->rtt_event.flow.proto)); ipproto_to_str(protostr, sizeof(protostr),
e->rtt_event.flow.proto));
print_flow_ppvizformat(stream, &e->rtt_event.flow); print_flow_ppvizformat(stream, &e->rtt_event.flow);
fprintf(stream, "\n"); fprintf(stream, "\n");
} else if (e->event_type == EVENT_TYPE_FLOW) { } else if (e->event_type == EVENT_TYPE_FLOW) {
print_ns_datetime(stream, e->flow_event.timestamp); print_ns_datetime(stream, e->flow_event.timestamp);
fprintf(stream, " %s ", proto_to_str(e->rtt_event.flow.proto)); fprintf(stream, " %s ",
ipproto_to_str(protostr, sizeof(protostr),
e->rtt_event.flow.proto));
print_flow_ppvizformat(stream, &e->flow_event.flow); print_flow_ppvizformat(stream, &e->flow_event.flow);
fprintf(stream, " %s due to %s from %s\n", fprintf(stream, " %s due to %s from %s\n",
flowevent_to_str(e->flow_event.flow_event_type), flowevent_to_str(e->flow_event.flow_event_type),
@ -1002,6 +1016,7 @@ static void print_common_fields_json(json_writer_t *ctx,
const struct network_tuple *flow = &e->rtt_event.flow; const struct network_tuple *flow = &e->rtt_event.flow;
char saddr[INET6_ADDRSTRLEN]; char saddr[INET6_ADDRSTRLEN];
char daddr[INET6_ADDRSTRLEN]; char daddr[INET6_ADDRSTRLEN];
char protostr[16];
format_ip_address(saddr, sizeof(saddr), flow->ipv, &flow->saddr.ip); format_ip_address(saddr, sizeof(saddr), flow->ipv, &flow->saddr.ip);
format_ip_address(daddr, sizeof(daddr), flow->ipv, &flow->daddr.ip); format_ip_address(daddr, sizeof(daddr), flow->ipv, &flow->daddr.ip);
@ -1012,7 +1027,9 @@ static void print_common_fields_json(json_writer_t *ctx,
jsonw_hu_field(ctx, "src_port", ntohs(flow->saddr.port)); jsonw_hu_field(ctx, "src_port", ntohs(flow->saddr.port));
jsonw_string_field(ctx, "dest_ip", daddr); jsonw_string_field(ctx, "dest_ip", daddr);
jsonw_hu_field(ctx, "dest_port", ntohs(flow->daddr.port)); jsonw_hu_field(ctx, "dest_port", ntohs(flow->daddr.port));
jsonw_string_field(ctx, "protocol", proto_to_str(flow->proto)); jsonw_string_field(ctx, "protocol",
ipproto_to_str(protostr, sizeof(protostr),
flow->proto));
} }
static void print_rttevent_fields_json(json_writer_t *ctx, static void print_rttevent_fields_json(json_writer_t *ctx,