Net::SIP::Packet(3pm)

πŸ’– Net::SIP::Packet πŸ’–

okay bestie, welcome to Net::SIP::Packet β€” the Perl module that does all the SIP packet handling, straight out of the User Contributed Perl Documentation. this is the 3pm-era one, so pull up a chair, grab a strawberry drink πŸ“, and let's get into it.


✨ NAME ✨

Net::SIP::Packet β€” handling of SIP packets 🫢


✨ SYNOPSIS ✨

use Net::SIP::Packet;
use Net::SIP::Request;
use Net::SIP::Response;
my $pkt = eval { Net::SIP::Packet->new( $sip_string ) }
  or die "invalid SIP packet";
$pkt->get_header( 'call-id' ) || die "no call-id";
$pkt->set_header( via => \@via );
print $pkt->as_string;

like... that's the whole vibe check right there. πŸ’…


✨ DESCRIPTION ✨

so this module is out here implementing the parsing, the manipulation and the creation of SIP packets, all per RFC3261. no cap.

NET::SIP::Packet's objects can show up two ways:

  • by parsing a string that contains the SIP packet, or
  • by constructing it from parts β€” think header keys and values, body, method+URI (for requests) or code+text (for responses).

every single part can be manipulated, and then the string representation of your now-gloriously-manipulated packet can be (re)created. iconic behaviour honestly.

heads up bestie: if you're dealing with requests and responses directly, you'll usually be using the subclasses Net::SIP::Request or Net::SIP::Response instead. iykyk πŸ’œ

✨ EXAMPLES ✨

# create packet from string
my $invite = Net::SIP::Packet->new(  <<'EOS' );
INVITE sip:you@example.com SIP/2.0
From: <sip:me@example.com>
To: <sip:you@example.com>
...
EOS

# show and manipulate some header
print "callid=".$invite->get_header( 'call-id' )."\n";
print "route=".join( ",", $invite->get_header( 'route' ))."\n";
$invite->set_header( 'via' => [ $via1,$via2,.. ] );

# get resulting string representation
print $invite->as_string;

# create packet from parts
my $resp = Net::SIP::Packet->new(
      200, 'Ok',
      { to => '<sip:you@example.com>', from => '<sip:me@example.com>',.. }
      Net::SIP::SDP->new(...)
);

# and get the packet as string
print $resp->as_string;

she's giving create, peek, poke, print. obsessed. 😭✨


✨ CONSTRUCTOR ✨

πŸŽ€ new ( STRING | @PARTS | HASH )

the default constructor, the main character πŸ‘‘. depending on how many arguments you hand her, she branches:

  • into new_from_string, or
  • into new_from_parts, or
  • just creates the object directly from the HASH you gave her.

πŸŽ€ new_from_string ( STRING )

reads STRING as a SIP request or response and creates a Net::SIP::Request or Net::SIP::Response object accordingly β€” and ngl, those classes have to have been loaded already or this doesn't work.

⚠️ she will die() if she can't parse the string as a SIP packet. so like, eval it, bestie. πŸ™ˆ

πŸŽ€ new_from_parts ( CODE|METHOD, TEXT|URI, \%HEADER|\@HEADER, [ BODY ] )

here's the tea:

  • if CODE|METHOD is numeric, you get a Net::SIP::Response object with the response code CODE and the text TEXT.
  • otherwise you get a Net::SIP::Request object with the method METHOD and the uri URI.
⚠️ note that the Request or Response class needs to be loaded already. fr fr.

now, the header data can be handed over as a hash %HEADER or an array @HEADER reference, and these two behave so differently:

  • hash vibes: the key is the SIP field name and the value is either a string or a \@list of strings. the fields on the resulting SIP packet get sorted by name, and fields with multiple values get created as seperate lines. (yes, the original says "seperat", we love her.)
  • array vibes: the elements of the array are [ key => value ] pairs, where the keys are the field names and the values are strings or \@list of strings. each pair results in a single line in the SIP header. if the value was a list reference, the values in that list get concatened by ','. the order of the fields in the resulting SIP packet is the same as in the array. slay, order preserved. πŸ’…

the BODY is optional, and you can give it as either a string or as a reference to an object that has a method as_string, like Net::SIP::SDP. and here's the cute part: if BODY is an object that has a method content_type, she'll set the "content-type" header of the SIP object based on the result of "BODY->content_type" β€” unless a "content-type" header was explicitly given. respect the explicit, periodt.

πŸŽ€ _new_request | _new_response

these work exactly like "new", except they assign the new object to the subclasses "Net::SIP::Request" resp. "Net::SIP:.Response".

🚫 these are not meant to be used directly! they're only there so you can redefine them when you subclass "Net::SIP::Packet" and want to use different subclasses. it's giving "for internal use only" energy.

✨ METHODS ✨

πŸ¦‹ is_request

returns TRUE if the SIP packet is a request, otherwise FALSE.

πŸ¦‹ is_response

returns TRUE if the SIP packet is a response, otherwise FALSE.

πŸ¦‹ tid

returns a transaction ID created from the sequence number in the "CSeq" header and the "Call-Id" header. all packets with the same tid belong to the same transaction β€” they're literally in the same group chat. πŸ’¬

πŸ¦‹ cseq

returns the "CSeq" header. short for "$self->get_header( 'cseq' )". lazy girl summer but make it efficient.

πŸ¦‹ callid

returns the "Call-Id" header. short for "$self->get_header( 'call-id' )". same energy. ✨

πŸ¦‹ get_header ( [ NAME ] )

okay so here's the whole situation:

  • if NAME is given, she returns the SIP header for NAME.
  • if no header exists, she returns ().
  • if there's only one value for the header, she returns that value.
  • if there are multiple values, she returns a @list of all the values β€” but if "wantarray" says the caller is only expecting a single value, she will croak(). πŸ’€ so like, know what you're asking for, bestie.
  • if no NAME is given, she returns a reference to a hash containing all fields, in the format described in new_from_parts.

πŸ¦‹ add_header ( NAME, VAL )

adds the header at the end of the SIP header. VAL can be a string or a reference to a list of strings.

πŸ¦‹ insert_header ( NAME, VAL )

like add_header, but the lines get added on top of the header. front of the line privileges. πŸ‘‘

πŸ¦‹ del_header ( NAME )

deletes all lines from the header where the field name is NAME. gone. blocked. 🚫

πŸ¦‹ set_header ( NAME, VAL )

replaces an existing header, like del_header followed by add_header. out with the old, in with the new.

πŸ¦‹ set_body ( VAL )

sets the body to VAL, which can be a string or an object. for how body objects are handled, go look at new_from_parts. 🫢

πŸ¦‹ as_string

returns the string representation of the SIP packet. the glow-up moment. ✨

πŸ¦‹ dump ( [ LEVEL ] )

returns a dump of the packet as a string, for debugging. the higher LEVEL is, the more details you get. at the moment, a LEVEL of 0 gets you a one-line summary, and everything else gets you the result from as_string.

πŸ¦‹ as_parts

returns an Array with CODE|METHOD, TEXT|URI, \@HEADER and BODY, like the ones used in new_from_parts. it's giving reverse uno card. πŸƒ

πŸ¦‹ sdp_body( [ SDP ] )

returns the body as a Net::SIP::SDP object if there's a body and the content-type is 'application/sdp' or empty. she'll also find 'application/sdp' inside a 'multipart/mixed' body. she's thorough like that. πŸ”

⚠️ if the body contains invalid SDP, she raises an exception (e.g. die()). no cap, watch out.

if the optional SDP argument is given, it's expected to be a Net::SIP::SDP object. it gets converted into a string and will replace an existing body (also inside multipart/mixed, leaving the rest untouched) β€” or set a new body if none existed before. either way, she ate. πŸ’…


🌸 UNDOCUMENTED METHODS 🌸

these ones are lurking in the shadows, no docs, just vibes:

  • get_header_hashval ( [ NAME ] )
  • scan_header ( @ARG )
  • clone

iykyk. don't ask her to explain, she won't. πŸ™ˆ


and that's the whole page, bestie! this gem of a page came to you from perl v5.40.1, dated 2025-12-07, and it's the Net::SIP::Packet(3pm) manpage β€” so if you ever need to find her again, that's the name to search. πŸŽ€βœ¨πŸ’– bye pookie, go parse something iconic! πŸ¦‹

πŸ“¦ where this page comes from