Difference between revisions of "M4 Kamailio Transformations"
(27 intermediate revisions by 5 users not shown) | |||
Line 1: | Line 1: | ||
Kamailio transformations using regexp allow modifying PAI (P-Asserted-Identity) and RPID (Remote-Party-ID) headers. | |||
<br><br> | <br><br> | ||
=Usage= | =Usage= | ||
Go to '''Users -> Connection Points''', | Go to '''Users -> Connection Points''', and click EDIT on Connection Point. | ||
PAI/RPID Transformations for OP are located under ''' Advanced Origination Point Settings''': | PAI/RPID Transformations for OP are located under ''' Advanced Origination Point Settings''': | ||
Line 20: | Line 20: | ||
* match_expression - POSIX regular expression | * match_expression - POSIX regular expression | ||
* replacement_expression - replacement expression with back references to matched tokes: \1, \2, …, \9 | * replacement_expression - replacement expression with back references to matched tokes: \1, \2, …, \9 | ||
* flags: | * flags (optional): | ||
** i - match ignore case | ** i - match ignore case | ||
** g - replace all matches | ** g - replace all matches | ||
Line 27: | Line 27: | ||
==Match Expression== | ==Match Expression== | ||
POSIX regular expression (regex) matching is done on full PAI/RPID header (for example: "name" <sip:number@host>;params). This allows to match and modify any part of the header (name, number, host, parameters). | POSIX regular expression (regex) matching is done on '''full PAI/RPID header''' (for example: <nowiki>"name" <sip:number@host>;params</nowiki>). This allows to match and modify any part of the header (name, number, host, parameters). | ||
<br><br> | <br><br> | ||
==Replacement Expression== | ==Replacement Expression== | ||
Line 36: | Line 37: | ||
A Transformation: | A Transformation: | ||
/sip:00/sip:/ | <nowiki>/sip:00/sip:/</nowiki> | ||
applied on a header: | applied on a header: | ||
<sip:00370123456789@example.sip> | <nowiki><sip:00370123456789@example.sip></nowiki> | ||
would result in: | would result in: | ||
<sip:370123456789@example.sip> | <nowiki><sip:370123456789@example.sip></nowiki> | ||
Here we match '''sip:00''' in the original header and replace it with '''sip:'''. If the original header did not contain a number starting with 00, then regex would not match and nothing is replaced. | Here we match '''<nowiki>sip:00</nowiki>''' in the original header and replace it with '''sip:'''. If the original header did not contain a number starting with 00, then regex would not match and nothing is replaced. | ||
Additionally, the replacement can contain '''\n''' (n is a number from 1 to 9, inclusive) references, which refer to the portion of the match which is contained between parentheses '''( )'''. References are numbered by counting their opening parentheses from left to right. | Additionally, the replacement can contain '''\n''' (n is a number from 1 to 9, inclusive) references, which refer to the portion of the match which is contained between parentheses '''( )'''. References are numbered by counting their opening parentheses from left to right. | ||
Line 52: | Line 53: | ||
A regex: | A regex: | ||
(.*) <sip:(.*)@(.*)>(.*) | <nowiki>(.*) <sip:(.*)@(.*)>(.*)</nowiki> | ||
applied on a header: | applied on a header: | ||
"John" <sip:00370123456789@example.sip>;user=phone | <nowiki>"John" <sip:00370123456789@example.sip>;user=phone</nowiki> | ||
would produce the following references: | would produce the following references: | ||
Line 69: | Line 70: | ||
A Transformation: | A Transformation: | ||
/(.*) <sip:(.*)@(.*)>(.*)/\2 <sip:\2@myhost.sip>\4/ | <nowiki>/(.*) <sip:(.*)@(.*)>(.*)/\2 <sip:\2@myhost.sip>\4/</nowiki> | ||
applied on a header: | applied on a header: | ||
"John" <sip:00370123456789@example.sip>;user=phone | <nowiki>"John" <sip:00370123456789@example.sip>;user=phone</nowiki> | ||
would result in: | would result in: | ||
00370123456789 <sip:00370123456789@myhost.sip>;user=phone | <nowiki>00370123456789 <sip:00370123456789@myhost.sip>;user=phone</nowiki> | ||
Here we construct a new header and set the '''name''' part to '''\2''' (which in our case is a number) and set static text as a '''host'''. | Here we construct a new header and set the '''name''' part to '''\2''' (which in our case is a number) and set static text as a '''host'''. | ||
<br><br> | <br><br> | ||
=Kamailio variables= | =Kamailio variables= | ||
Line 90: | Line 92: | ||
A Transformation: | A Transformation: | ||
/sip:(.*)@/sip:$fU@/ | <nowiki>/sip:(.*)@/sip:$fU@/</nowiki> | ||
applied on a PAI header: | applied on a PAI header: | ||
Line 105: | Line 107: | ||
<br><br> | <br><br> | ||
=Custom variables= | |||
In addition to Kamailio variables, you can use custom M4 variables: | |||
* $src - localized source number (number that will be sent to Termination Point) | |||
<br><br> | |||
=Testing= | =Testing= | ||
Line 114: | Line 125: | ||
Execute '''sed''' command (add s before transformation '''s'''/regex/replacement/flags): | Execute '''sed''' command (add s before transformation '''s'''/regex/replacement/flags): | ||
echo '<sip:00370123456789@myhost.sip>' | sed -E 's/sip:00/sip:/' | <nowiki>echo '<sip:00370123456789@myhost.sip>' | sed -E 's/sip:00/sip:/'</nowiki> | ||
<br><br> | <br><br> | ||
====Test in online sed live editor==== | ====Test in online sed live editor==== | ||
Line 123: | Line 135: | ||
====Validate regex==== | ====Validate regex==== | ||
Regex part of a Transformation can be validated using https://regexr.com/ (or any other online regex editor). | The Regex part of a Transformation can be validated using https://regexr.com/ (or any other online regex editor). | ||
<br><br> | <br><br> | ||
Line 140: | Line 152: | ||
| '''Transformation''' || '''Original header''' || '''Modified header''' || '''Comment''' | | '''Transformation''' || '''Original header''' || '''Modified header''' || '''Comment''' | ||
|- | |- | ||
| /sip:00/sip:/ || <sip:003701234567@myhost.sip> || <sip:3701234567@myhost.sip> || Cut prefix 00 | | <nowiki>/sip:00/sip:/</nowiki> || <nowiki><sip:003701234567@myhost.sip></nowiki> || <nowiki><sip:3701234567@myhost.sip></nowiki> || Cut prefix 00 | ||
|- | |||
| <nowiki>/sip:\+/sip:/</nowiki> || <nowiki><sip:+3701234567@myhost.sip></nowiki> || <nowiki><sip:3701234567@myhost.sip></nowiki> || Cut + (here + is escaped by \ since it is special regex symbol) | |||
|- | |||
| <nowiki>/sip:\+370/sip:86/</nowiki> || <nowiki><sip:+3701234567@myhost.sip></nowiki> || <nowiki><sip:861234567@myhost.sip></nowiki> || Cut prefix +370, add prefix 86 | |||
|- | |||
| <nowiki>/sip:\+?(.*)/sip:+\1/</nowiki> || <nowiki><sip:3701234567@myhost.sip></nowiki> || <nowiki><sip:+3701234567@myhost.sip></nowiki> || Add + if it is not present already | |||
|- | |||
| <nowiki>/sip:(.*)@/sip:$fU@/</nowiki> || <nowiki><sip:anonymous@myhost.sip></nowiki> || <nowiki><sip:3701234567@myhost.sip></nowiki> || Using Kamailio variable $fU replace the original number with the number from SIP FROM header | |||
|- | |- | ||
| /sip:\+/sip:/ || <sip: | | <nowiki>/sip:(\+|00)/sip:/</nowiki> || <nowiki><sip:003701234567@myhost.sip></nowiki> || <nowiki><sip:3701234567@myhost.sip></nowiki> || Cut prefix 00 or + | ||
|- | |- | ||
| | | <nowiki><tel:$fU;cpc=ordinary></nowiki> || Overwriting current header or creating a new header || <nowiki><tel:5557061219;cpc=ordinary></nowiki> || Format header in the format requested by the Supplier: <nowiki><tel:NUMBER;cpc=ordinary>/</nowiki> (special PAI example here) | ||
|- | |- | ||
| /sip: | | <nowiki>/sip:(.*)@/sip:0\1123@/</nowiki> || <nowiki><sip:XXXXXXXX@myhost.sip></nowiki> || <nowiki><sip:0XXXXXXXX123@myhost.sip></nowiki> || Add 0 in front and 123 at the end | ||
|- | |- | ||
| /sip:(.*)@/sip: | | <nowiki>/"([^"]*)"[[:space:]]*<sip:(.*)@(.*)/"\1" <sip:\1@\3/</nowiki> || <nowiki>"YYYYYYYY" <sip:XXXXXXXX@myhost.sip></nowiki> || <nowiki>"YYYYYYYY" <sip:YYYYYYYY@myhost.sip></nowiki> || Copy Callerid name part to Callerid number part (username) | ||
|- | |- | ||
|} | |} | ||
<br><br> | <br><br> | ||
=See also= | =See also= | ||
* [[M4 Regexp Examples]] | |||
* [[M4 Origination Points]] | * [[M4 Origination Points]] | ||
* [[M4 Termination Points]] | * [[M4 Termination Points]] | ||
* [[M4 Source Transformation]] | |||
* [[M4 Destination Transformation]] |
Latest revision as of 06:21, 14 June 2024
Kamailio transformations using regexp allow modifying PAI (P-Asserted-Identity) and RPID (Remote-Party-ID) headers.
Usage
Go to Users -> Connection Points, and click EDIT on Connection Point.
PAI/RPID Transformations for OP are located under Advanced Origination Point Settings:
PAI/RPID Transformations for TP are located under Termination Point Signaling Settings:
Transformation format
/match_expression/replacement_expression/flags
- match_expression - POSIX regular expression
- replacement_expression - replacement expression with back references to matched tokes: \1, \2, …, \9
- flags (optional):
- i - match ignore case
- g - replace all matches
Match Expression
POSIX regular expression (regex) matching is done on full PAI/RPID header (for example: "name" <sip:number@host>;params). This allows to match and modify any part of the header (name, number, host, parameters).
Replacement Expression
If the regex match is successful, then the portion which was matched is replaced with a replacement.
A Transformation:
/sip:00/sip:/
applied on a header:
<sip:00370123456789@example.sip>
would result in:
<sip:370123456789@example.sip>
Here we match sip:00 in the original header and replace it with sip:. If the original header did not contain a number starting with 00, then regex would not match and nothing is replaced.
Additionally, the replacement can contain \n (n is a number from 1 to 9, inclusive) references, which refer to the portion of the match which is contained between parentheses ( ). References are numbered by counting their opening parentheses from left to right.
A regex:
(.*) <sip:(.*)@(.*)>(.*)
applied on a header:
"John" <sip:00370123456789@example.sip>;user=phone
would produce the following references:
- \1 - "John"
- \2 - 00370123456789
- \3 - example.sip
- \4 - ;user=phone
Using these references you can construct your own header:
A Transformation:
/(.*) <sip:(.*)@(.*)>(.*)/\2 <sip:\2@myhost.sip>\4/
applied on a header:
"John" <sip:00370123456789@example.sip>;user=phone
would result in:
00370123456789 <sip:00370123456789@myhost.sip>;user=phone
Here we construct a new header and set the name part to \2 (which in our case is a number) and set static text as a host.
Kamailio variables
Replacement Expression accepts Kamailio variables.
As an example, let's replace the URI username (number part) in the PAI header with URI username from FROM header:
A Transformation:
/sip:(.*)@/sip:$fU@/
applied on a PAI header:
From: <1111111@myhost.sip> P-Asserted-Identity: <anonymous@myhost.sip>
would result in:
From: <1111111@myhost.sip> P-Asserted-Identity: <1111111@myhost.sip>
Here we are using the $fU Kamailio variable which refers to FROM URI username. PAI number anonymous is replaced with number 1111111.
Custom variables
In addition to Kamailio variables, you can use custom M4 variables:
- $src - localized source number (number that will be sent to Termination Point)
Testing
Before putting Transformations to production, it is advisable to test them on various values.
Test in Linux console
Execute sed command (add s before transformation s/regex/replacement/flags):
echo '<sip:00370123456789@myhost.sip>' | sed -E 's/sip:00/sip:/'
Test in online sed live editor
If you do not have access to the Linux console, use https://sed.js.org/ (or any other online sed editor).
Validate regex
The Regex part of a Transformation can be validated using https://regexr.com/ (or any other online regex editor).
Quick notes
- Header must be present in order to apply Transformations
- In case of error, no changes will be applied
- Only POSIX regex is allowed
- If a Transformation was applied by OP settings, then TP Transformations will be applied on top of the already modified header
- Destination Transformation uses a different syntax, please refer to Destination Transformation
Examples
Transformation | Original header | Modified header | Comment |
/sip:00/sip:/ | <sip:003701234567@myhost.sip> | <sip:3701234567@myhost.sip> | Cut prefix 00 |
/sip:\+/sip:/ | <sip:+3701234567@myhost.sip> | <sip:3701234567@myhost.sip> | Cut + (here + is escaped by \ since it is special regex symbol) |
/sip:\+370/sip:86/ | <sip:+3701234567@myhost.sip> | <sip:861234567@myhost.sip> | Cut prefix +370, add prefix 86 |
/sip:\+?(.*)/sip:+\1/ | <sip:3701234567@myhost.sip> | <sip:+3701234567@myhost.sip> | Add + if it is not present already |
/sip:(.*)@/sip:$fU@/ | <sip:anonymous@myhost.sip> | <sip:3701234567@myhost.sip> | Using Kamailio variable $fU replace the original number with the number from SIP FROM header |
/sip:(\+|00)/sip:/ | <sip:003701234567@myhost.sip> | <sip:3701234567@myhost.sip> | Cut prefix 00 or + |
<tel:$fU;cpc=ordinary> | Overwriting current header or creating a new header | <tel:5557061219;cpc=ordinary> | Format header in the format requested by the Supplier: <tel:NUMBER;cpc=ordinary>/ (special PAI example here) |
/sip:(.*)@/sip:0\1123@/ | <sip:XXXXXXXX@myhost.sip> | <sip:0XXXXXXXX123@myhost.sip> | Add 0 in front and 123 at the end |
/"([^"]*)"[[:space:]]*<sip:(.*)@(.*)/"\1" <sip:\1@\3/ | "YYYYYYYY" <sip:XXXXXXXX@myhost.sip> | "YYYYYYYY" <sip:YYYYYYYY@myhost.sip> | Copy Callerid name part to Callerid number part (username) |