Skip to content

Commit

Permalink
Implement SSDP Metadata export (#2729)
Browse files Browse the repository at this point in the history
Close #2524
  • Loading branch information
koltiradw authored Feb 16, 2025
1 parent d51b6ab commit ccb15db
Show file tree
Hide file tree
Showing 7 changed files with 363 additions and 10 deletions.
14 changes: 14 additions & 0 deletions src/include/ndpi_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,20 @@ struct ndpi_packet_struct {
struct ndpi_int_one_line_struct upgrade_line;
struct ndpi_int_one_line_struct http_response; /* the first "word" in this pointer is the
response code in the packet (200, etc) */
struct ndpi_int_one_line_struct bootid;
struct ndpi_int_one_line_struct usn;
struct ndpi_int_one_line_struct cache_controle;
struct ndpi_int_one_line_struct location;
struct ndpi_int_one_line_struct household_smart_speaker_audio;
struct ndpi_int_one_line_struct rincon_household;
struct ndpi_int_one_line_struct rincon_bootseq;
struct ndpi_int_one_line_struct rincon_wifimode;
struct ndpi_int_one_line_struct rincon_variant;
struct ndpi_int_one_line_struct sonos_securelocation;
struct ndpi_int_one_line_struct securelocation_upnp;
struct ndpi_int_one_line_struct location_smart_speaker_audio;
struct ndpi_int_one_line_struct nt;
struct ndpi_int_one_line_struct nts;

u_int16_t l3_packet_len;
u_int16_t payload_packet_len;
Expand Down
19 changes: 19 additions & 0 deletions src/include/ndpi_typedefs.h
Original file line number Diff line number Diff line change
Expand Up @@ -1577,6 +1577,25 @@ struct ndpi_flow_struct {
u_int32_t ipv4_addr, uptime;
struct ndpi_in6_addr ipv6_addr;
} mikrotik;

struct {
char *method;
char *bootid;
char *usn;
char *cache_controle;
char *location;
char *household_smart_speaker_audio;
char *rincon_household;
char *rincon_bootseq;
char *rincon_wifimode;
char *rincon_variant;
char *sonos_securelocation;
char *securelocation_upnp;
char *location_smart_speaker_audio;
char *nt;
char *nts;
char *server;
} ssdp;
} protos;

/* **Packet** metadata for flows where monitoring is enabled. It is reset after each packet! */
Expand Down
96 changes: 94 additions & 2 deletions src/lib/ndpi_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -6858,6 +6858,56 @@ void ndpi_free_flow_data(struct ndpi_flow_struct* flow) {
ndpi_free(flow->protos.sip.to);
}

if (flow_is_proto(flow, NDPI_PROTOCOL_SSDP)) {
if(flow->protos.ssdp.bootid)
ndpi_free(flow->protos.ssdp.bootid);

if(flow->protos.ssdp.usn)
ndpi_free(flow->protos.ssdp.usn);

if(flow->protos.ssdp.cache_controle)
ndpi_free(flow->protos.ssdp.cache_controle);

if(flow->protos.ssdp.location)
ndpi_free(flow->protos.ssdp.location);

if(flow->protos.ssdp.household_smart_speaker_audio)
ndpi_free(flow->protos.ssdp.household_smart_speaker_audio);

if(flow->protos.ssdp.rincon_household)
ndpi_free(flow->protos.ssdp.rincon_household);

if(flow->protos.ssdp.rincon_bootseq)
ndpi_free(flow->protos.ssdp.rincon_bootseq);

if(flow->protos.ssdp.rincon_wifimode)
ndpi_free(flow->protos.ssdp.rincon_wifimode);

if(flow->protos.ssdp.rincon_variant)
ndpi_free(flow->protos.ssdp.rincon_variant);

if(flow->protos.ssdp.sonos_securelocation)
ndpi_free(flow->protos.ssdp.sonos_securelocation);

if(flow->protos.ssdp.securelocation_upnp)
ndpi_free(flow->protos.ssdp.securelocation_upnp);

if(flow->protos.ssdp.location_smart_speaker_audio)
ndpi_free(flow->protos.ssdp.location_smart_speaker_audio);

if(flow->protos.ssdp.nt)
ndpi_free(flow->protos.ssdp.nt);

if(flow->protos.ssdp.nts)
ndpi_free(flow->protos.ssdp.nts);

if(flow->protos.ssdp.server)
ndpi_free(flow->protos.ssdp.server);

if(flow->protos.ssdp.method)
ndpi_free(flow->protos.ssdp.method);
}

if(flow->tls_quic.message[0].buffer)
ndpi_free(flow->tls_quic.message[0].buffer);
if(flow->tls_quic.message[1].buffer)
Expand Down Expand Up @@ -8485,7 +8535,21 @@ static void ndpi_reset_packet_line_info(struct ndpi_packet_struct *packet) {
packet->server_line.len = 0, packet->http_method.ptr = NULL, packet->http_method.len = 0,
packet->http_response.ptr = NULL, packet->http_response.len = 0,
packet->forwarded_line.ptr = NULL, packet->forwarded_line.len = 0;
packet->upgrade_line.ptr = NULL, packet->upgrade_line.len = 0;
packet->upgrade_line.ptr = NULL, packet->upgrade_line.len = 0;
packet->bootid.ptr = NULL, packet->bootid.len = 0;
packet->usn.ptr = NULL, packet->usn.len = 0;
packet->cache_controle.ptr = NULL, packet->cache_controle.len = 0;
packet->location.ptr = NULL, packet->location.len = 0;
packet->household_smart_speaker_audio.ptr = NULL, packet->household_smart_speaker_audio.len = 0;
packet->rincon_household.ptr = NULL, packet->rincon_household.len = 0;
packet->rincon_bootseq.ptr = NULL, packet->rincon_bootseq.len = 0;
packet->rincon_wifimode.ptr = NULL, packet->rincon_wifimode.len = 0;
packet->rincon_variant.ptr = NULL, packet->rincon_variant.len = 0;
packet->sonos_securelocation.ptr = NULL, packet->sonos_securelocation.len = 0;
packet->securelocation_upnp.ptr = NULL, packet->securelocation_upnp.len = 0;
packet->location_smart_speaker_audio.ptr = NULL, packet->location_smart_speaker_audio.len = 0;
packet->nt.ptr = NULL, packet->nt.len = 0;
packet->nts.ptr = NULL, packet->nts.len = 0;
}

/* ********************************************************************************* */
Expand Down Expand Up @@ -9229,23 +9293,39 @@ static void parse_single_packet_line(struct ndpi_detection_module_struct *ndpi_s
struct header_line headers_a[] = { { "Accept:", &packet->accept_line },
{ "Authorization:", &packet->authorization_line },
{ NULL, NULL} };
struct header_line headers_b[] = { { "BOOTID.UPNP.ORG:", &packet->bootid},
{ NULL, NULL} };
struct header_line headers_u[] = { { "User-agent:", &packet->user_agent_line },
{ "Upgrade:", &packet->upgrade_line },
{ "USN:", &packet->usn },
{ NULL, NULL} };
struct header_line headers_c[] = { { "Content-Disposition:", &packet->content_disposition_line },
{ "Content-type:", &packet->content_line },
{ "CACHE-CONTROL:", &packet->cache_controle},
{ NULL, NULL} };
struct header_line headers_o[] = { { "Origin:", &packet->http_origin },
{ NULL, NULL} };
struct header_line headers_h[] = { { "Host:", &packet->host_line },
{ "HOUSEHOLD.SMARTSPEAKER.AUDIO:", &packet->household_smart_speaker_audio },
{ NULL, NULL} };
struct header_line headers_x[] = { { "X-Forwarded-For:", &packet->forwarded_line },
{ "X-RINCON-HOUSEHOLD:", &packet->rincon_household },
{ "X-RINCON-BOOTSEQ:", &packet->rincon_bootseq },
{ "X-RINCON-WIFIMODE:", &packet->rincon_wifimode },
{ "X-RINCON-VARIANT:", &packet->rincon_variant },
{ "X-SONOS-HHSECURELOCATION:", &packet->sonos_securelocation },
{ NULL, NULL} };
struct header_line headers_r[] = { { "Referer:", &packet->referer_line },
{ NULL, NULL} };
struct header_line headers_s[] = { { "Server:", &packet->server_line },
{ "SECURELOCATION.UPNP.ORG:", &packet->securelocation_upnp },
{ NULL, NULL} };

struct header_line headers_l[] = { { "LOCATION:", &packet->location },
{ "LOCATION.SMARTSPEAKER.AUDIO:", &packet->location_smart_speaker_audio },
{ NULL, NULL}};
struct header_line headers_n[] = { { "NT:", &packet->nt },
{ "NTS:", &packet->nts },
{ NULL, NULL}};

line = &packet->line[packet->parsed_lines];
if(line->len == 0)
Expand Down Expand Up @@ -9274,6 +9354,10 @@ static void parse_single_packet_line(struct ndpi_detection_module_struct *ndpi_s
case 'A':
hs = headers_a;
break;
case 'b':
case 'B':
hs = headers_b;
break;
case 'c':
case 'C':
hs = headers_c;
Expand Down Expand Up @@ -9302,6 +9386,14 @@ static void parse_single_packet_line(struct ndpi_detection_module_struct *ndpi_s
case 'X':
hs = headers_x;
break;
case 'l':
case 'L':
hs = headers_l;
break;
case 'n':
case 'N':
hs = headers_n;
break;
default:
return;
}
Expand Down
70 changes: 70 additions & 0 deletions src/lib/ndpi_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -1592,6 +1592,76 @@ int ndpi_dpi2json(struct ndpi_detection_module_struct *ndpi_struct,
}
break;

case NDPI_PROTOCOL_SSDP:
ndpi_serialize_start_of_block(serializer, "ssdp");

if (flow->protos.ssdp.method) {
ndpi_serialize_string_string(serializer, "METHOD", flow->protos.ssdp.method);
}

if (flow->protos.ssdp.cache_controle) {
ndpi_serialize_string_string(serializer, "CACHE-CONTROL", flow->protos.ssdp.cache_controle);
}

if (flow->protos.ssdp.location) {
ndpi_serialize_string_string(serializer, "LOCATION", flow->protos.ssdp.location);
}

if (flow->protos.ssdp.nt) {
ndpi_serialize_string_string(serializer, "NT", flow->protos.ssdp.nt);
}

if (flow->protos.ssdp.nts) {
ndpi_serialize_string_string(serializer, "NTS", flow->protos.ssdp.nts);
}

if (flow->protos.ssdp.server) {
ndpi_serialize_string_string(serializer, "SERVER", flow->protos.ssdp.server);
}

if (flow->protos.ssdp.usn) {
ndpi_serialize_string_string(serializer, "USN", flow->protos.ssdp.usn);
}

if (flow->protos.ssdp.rincon_household) {
ndpi_serialize_string_string(serializer, "X-RINCON-HOUSEHOLD", flow->protos.ssdp.rincon_household);
}

if (flow->protos.ssdp.rincon_bootseq) {
ndpi_serialize_string_string(serializer, "X-RINCON-BOOTSEQ", flow->protos.ssdp.rincon_bootseq);
}

if (flow->protos.ssdp.bootid) {
ndpi_serialize_string_string(serializer, "BOOTID.UPNP.ORG", flow->protos.ssdp.bootid);
}

if (flow->protos.ssdp.rincon_wifimode) {
ndpi_serialize_string_string(serializer, "X-RINCON-WIFIMODE", flow->protos.ssdp.rincon_wifimode);
}

if (flow->protos.ssdp.rincon_variant) {
ndpi_serialize_string_string(serializer, "X-RINCON-VARIANT", flow->protos.ssdp.rincon_variant);
}

if (flow->protos.ssdp.household_smart_speaker_audio) {
ndpi_serialize_string_string(serializer, "HOUSEHOLD.SMARTSPEAKER.AUDIO", flow->protos.ssdp.household_smart_speaker_audio);
}

if (flow->protos.ssdp.location_smart_speaker_audio) {
ndpi_serialize_string_string(serializer, "LOCATION.SMARTSPEAKER.AUDIO", flow->protos.ssdp.location_smart_speaker_audio);
}

if (flow->protos.ssdp.securelocation_upnp) {
ndpi_serialize_string_string(serializer, "SECURELOCATION.UPNP.ORG", flow->protos.ssdp.securelocation_upnp);
}

if (flow->protos.ssdp.sonos_securelocation) {
ndpi_serialize_string_string(serializer, "X-SONOS-HHSECURELOCATION", flow->protos.ssdp.sonos_securelocation);
}

ndpi_serialize_end_of_block(serializer);
break;

case NDPI_PROTOCOL_DISCORD:
if (l7_protocol.proto.master_protocol != NDPI_PROTOCOL_TLS) {
ndpi_serialize_start_of_block(serializer, "discord");
Expand Down
Loading

0 comments on commit ccb15db

Please sign in to comment.