rust/sdp: implement logger

This implements a logger for the SDP protocol.
Given that SDP is encapsulated within other protocols (such as SIP),
enabling it separately is not necessary.

Ticket #6627
pull/10952/head
Giuseppe Longo 1 year ago committed by Victor Julien
parent 1ccfc35214
commit bff790b6ac

@ -3312,6 +3312,135 @@
}, },
"version": { "version": {
"type": "string" "type": "string"
},
"sdp": {
"type": "object",
"description": "SDP message body",
"optional": true,
"properties": {
"version": {
"type": "integer",
"description": "SDP protocol version"
},
"origin": {
"type": "string",
"description": "Owner of the session"
},
"session_name": {
"type": "string",
"description": "Session name"
},
"session_info": {
"type": "string",
"optional": true,
"description": "Textual information about the session"
},
"uri": {
"type": "string",
"optional": true,
"description": "A pointer to additional information about the session"
},
"email": {
"type": "string",
"optional": true,
"description": "Email address for the person responsible for the conference"
},
"phone_number": {
"type": "string",
"optional": true,
"description": "Phone number for the person responsible for the conference"
},
"connection_data": {
"type": "string",
"optional": true,
"description": "Connection data"
},
"bandwidths": {
"type": "array",
"optional": true,
"description": "Proposed bandwidths to be used by the session or media",
"minItems": 1,
"items": {
"type": "string"
}
},
"time": {
"type": "string",
"optional": true,
"description": "Start and stop times for a session"
},
"repeat_time": {
"type": "string",
"optional": true,
"description": "Specify repeat times for a session"
},
"timezone": {
"type": "string",
"optional": true,
"description": "Timezone to specify adjustments for times and offsets from the base time"
},
"encryption_key": {
"type": "string",
"optional": true,
"description": "Field used to convey encryption keys if SDP is used over a secure channel"
},
"attributes": {
"type": "array",
"optional": true,
"description": "A list of attributes to extend SDP",
"minItems": 1,
"items": {
"type": "string",
"description": "Attribute's name and value"
}
},
"media_descriptions": {
"type": "array",
"description": "A list of media descriptions for a session",
"minItems": 1,
"items": {
"type": "object",
"optional": true,
"properties": {
"media": {
"type": "string",
"description": "Media description"
},
"media_info": {
"type": "string",
"optional": true,
"description": "Media information primarily intended for labelling media streams"
},
"bandwidths": {
"type": "array",
"optional": true,
"description": "A list of bandwidth proposed for a media",
"minItems": 1,
"items": {
"type": "string"
}
},
"connection_data": {
"type": "string",
"optional": true,
"description": "Connection data per media description"
},
"attributes": {
"type": "array",
"description": "A list of attributes specified for a media description",
"optional": true,
"minItems": 1,
"items": {
"type": "string",
"description": "Attribute's name and value"
}
}
},
"additionalProperties": false
}
}
},
"additionalProperties": false
} }
}, },
"additionalProperties": false "additionalProperties": false

@ -0,0 +1,154 @@
/* Copyright (C) 2024 Open Information Security Foundation
*
* You can copy, redistribute or modify this Program under the terms of
* the GNU General Public License version 2 as published by the Free
* Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* version 2 along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
// written by Giuseppe Longo <giuseppe@glongo.it>
use crate::jsonbuilder::{JsonBuilder, JsonError};
use super::parser::{ConnectionData, MediaDescription, SdpMessage};
pub fn sdp_log(msg: &SdpMessage, js: &mut JsonBuilder) -> Result<(), JsonError> {
js.open_object("sdp")?;
let origin = format!(
"{} {} {} {} {} {}",
&msg.origin.username,
&msg.origin.sess_id,
&msg.origin.sess_version,
&msg.origin.nettype,
&msg.origin.addrtype,
&msg.origin.unicast_address
);
js.set_string("origin", &origin)?;
js.set_string("session_name", &msg.session_name)?;
if let Some(session_info) = &msg.session_info {
js.set_string("session_info", session_info)?;
}
if let Some(uri) = &msg.uri {
js.set_string("uri", uri)?;
}
if let Some(email) = &msg.email {
js.set_string("email", email)?;
}
if let Some(phone_number) = &msg.phone_number {
js.set_string("phone_number", phone_number)?;
}
if let Some(conn_data) = &msg.connection_data {
log_connection_data(conn_data, js)?;
}
if let Some(bws) = &msg.bandwidths {
log_bandwidth(bws, js)?;
}
js.set_string("time", &msg.time)?;
if let Some(repeat_time) = &msg.repeat_time {
js.set_string("repeat_time", repeat_time)?;
}
if let Some(tz) = &msg.time_zone {
js.set_string("timezone", tz)?;
}
if let Some(enc_key) = &msg.encryption_key {
js.set_string("encryption_key", enc_key)?;
}
if let Some(attrs) = &msg.attributes {
log_attributes(attrs, js)?;
}
if let Some(media) = &msg.media_description {
log_media_description(media, js)?;
}
js.close()?;
Ok(())
}
fn log_media_description(
media: &Vec<MediaDescription>, js: &mut JsonBuilder,
) -> Result<(), JsonError> {
if !media.is_empty() {
js.open_array("media_descriptions")?;
for m in media {
js.start_object()?;
let port = if let Some(num_ports) = m.number_of_ports {
format!("{}/{}", m.port, num_ports)
} else {
format!("{}", m.port)
};
let mut media = format!("{} {} {}", &m.media, &port, &m.proto);
for f in &m.fmt {
media = format!("{} {}", media, f);
}
js.set_string("media", &media)?;
if let Some(session_info) = &m.session_info {
js.set_string("media_info", session_info)?;
};
if let Some(bws) = &m.bandwidths {
log_bandwidth(bws, js)?;
}
if let Some(conn_data) = &m.connection_data {
log_connection_data(conn_data, js)?;
}
if let Some(attrs) = &m.attributes {
log_attributes(attrs, js)?;
}
js.close()?;
}
}
js.close()?;
Ok(())
}
fn log_bandwidth(bws: &Vec<String>, js: &mut JsonBuilder) -> Result<(), JsonError> {
if !bws.is_empty() {
js.open_array("bandwidths")?;
for bw in bws {
js.append_string(bw)?;
}
js.close()?;
}
Ok(())
}
fn log_connection_data(conn_data: &ConnectionData, js: &mut JsonBuilder) -> Result<(), JsonError> {
let mut conn = format!(
"{} {} {}",
&conn_data.nettype,
&conn_data.addrtype,
&conn_data.connection_address.to_string()
);
if let Some(ttl) = conn_data.ttl {
conn = format!("{}/{}", conn, ttl);
js.set_uint("ttl", ttl as u64)?;
}
if let Some(num_addrs) = conn_data.number_of_addresses {
conn = format!("{}/{}", conn, num_addrs);
}
js.set_string("connection_data", &conn)?;
Ok(())
}
fn log_attributes(attrs: &Vec<String>, js: &mut JsonBuilder) -> Result<(), JsonError> {
if !attrs.is_empty() {
js.open_array("attributes")?;
for attr in attrs {
js.append_string(attr)?;
}
js.close()?;
}
Ok(())
}

@ -1 +1,2 @@
pub mod logger;
pub mod parser; pub mod parser;

Loading…
Cancel
Save