How To Guide Generic Header Manipulation & Regular Expressions
How To Guide Generic Header Manipulation & Regular Expressions
28/05/2018
Revision History:
Revision Date Author Comments
1 2010-11-03 Scott Beer
2 2010-11-16 SB and KES First Release
3 2012-05-23 Scott Beer 4.10 updates
4 2012-05-23 KES Front page only
5 2015-07-10 RN Major rewrite and 5.0.4 updates
6 2015-09-24 KES Renamed to reflect RegExp also
7 2016-01-19 PD Minor content updates
8 2016-02-23 PD / AG Add $([syntax])
9 2016-11-21 PD Minor updates
10 2016-12-19 PD Errata bug catch, minor fixes
11 2017-04-16 PD / AG Add 6.0.x GHM variable
12 2017-10-26 PD Modifications to CVS/CHM
13 2018-05-28 PD New regexps, some rewrites
Page 1 of 35
Table of Contents
Errata ............................................................................................................................................ 4
1 Introduction ........................................................................................................................... 5
1.1 Example of Generic Header Manipulation .......................................................................................... 5
2 General about Generic Header Manipulation (GHM) .............................................................. 6
2.1 Where to configure GHM .................................................................................................................... 6
2.2 Incoming messages ............................................................................................................................. 9
2.3 Outgoing messages ........................................................................................................................... 10
3 Regular Expressions .............................................................................................................. 12
3.1 Industry-standard regular expressions notation ............................................................................... 12
3.2 Routing of calls using the Dial Plan and the SIP trunk Page .............................................................. 13
3.3 Examples of Basic Regular Expressions ............................................................................................. 17
3.4 183 to 180 conversion ....................................................................................................................... 18
3.5 Do not REGISTER to trunk server(s) ................................................................................................... 18
3.6 Do not automatically monitor trunk server(s) with SIP OPTIONS ..................................................... 18
3.7 B2bua with media via the main dial plan .......................................................................................... 18
3.8 Explicitly stating transport ................................................................................................................. 19
3.9 Specifying Escape Characters (dial string) for e.g. Telia SIP trunk ..................................................... 19
3.10 Additional information ...................................................................................................................... 19
4 Conditional Regular Expressions (CRE) .................................................................................. 20
4.1 Example CRE - Sweden Number Reduction ....................................................................................... 20
4.2 Example CRE - USA Number Reduction ............................................................................................. 20
4.3 Generic Number Reduction to + prefix for phone numbers 8-12 digits long .................................... 21
5 Variable Substitution ............................................................................................................ 22
5.1 Port and Password ............................................................................................................................. 23
5.2 Examples ........................................................................................................................................... 25
6 Generic Header Manipulation (GHM) ................................................................................... 26
6.1 Adding or Replacing a Header ........................................................................................................... 26
6.2 Removing a header ............................................................................................................................ 27
6.3 Generic Header Manipulation (GHM) for Responses ........................................................................ 27
6.4 Multiple Occurrences of Headers ...................................................................................................... 28
6.5 Variable substitution ......................................................................................................................... 28
7 Conditional Variable substitution (CVS) ................................................................................ 30
7.1 Conditional Header Manipulation (CHM) .......................................................................................... 30
7.2 URI Parameter Chaining .................................................................................................................... 33
8 Keyword / Grammar Summary – CVS, CHM and CRE ............................................................. 35
8.1 Tests .................................................................................................................................................. 35
8.2 Results ............................................................................................................................................... 35
8.3 RegExp ............................................................................................................................................... 35
File name: How_To_use_Generic_Header_Manipulation.pdf
Abbreviation Term
GHM Generic Header Manipulation
CRE Conditional Regular Expressions
CVS Conditional Variable Substitution
CHM Conditional Header Manipulation
B2BUA Back to Back User Agent
ITSP Internet Telephony Service Provider
Errata:
Note: In firmware versions <= 5.0.11 you cannot use $1?From=$(......$1...) – i.e. regexp capture
result groups (on the trunk page i.e. where $1 is before and after the “?”), and $REGMATCH
expressions which also contain their own $1 capture groups. The workaround is to use
$0?From=$(....$1…).
$0 evaluates to the whole user portion of the RURI on the trunk page.
If a fix is necessary e.g. you must forward trunk captures to a host which differs from the PBX
configured on the trunk page, write to support@ingate.com for a patch for your current firmware
version <= 5.0.11, or upgrade your firmware > 5.0.11
1 Introduction
This document describes how to use Generic Header Manipulation (GHM) in an Ingate
SIParator/Firewall. With the GHM feature it is possible to Add, Change or Remove any SIP Header
of incoming or outgoing SIP messages, both Requests and Responses.
The purpose of this feature is to enhance the interoperability between different vendor equipment, as
many IP-PBX, Service Providers, and overall SIP devices require different usage of various SIP
Headers. Different vendors interpret the SIP standard in a non-conformant way and by using GHM
can SIP protocol variances be resolved.
Rules are configured in the Dial Plan and SIP Trunk Page GUIs. The rules are configured in the same
fields as regular expressions are written. With regular expressions, it is possible to match substrings
and variables from SIP messages. When forwarding SIP messages, they can be rewritten according to
your wishes. By variable substitutions it is also possible to take information from one header and put
it in another header.
Note: Text written in a Monospace Font signifies regular expression code i.e. GHM, CHM,
CRE, CVS or processing result.
Note: Result samples are not intended to be protocol-accurate or compliant; they are intended for
demonstration only and reduced for simplicity.
The following list summarizes the supported GHM actions for a SIP header:
• Add a header to the message, if the header doesn’t exist
• Replace header content
• Pass a header unchanged
• Remove a header
• Replace an instance of a header
All listed actions can be done conditionally – i.e. check for a matching condition, and then act.
Header manipulation for requests are performed after routing of calls, while responses are modified
prior to routing.
PBX Lines – From PBX Number/User and PBX Lines – Username and Forward To PBX
Incoming Trunk Match Account
SIP Lines – From SIP Number/User and SIP Lines – Username and Forward To SIP
Incoming Trunk Match Account
SIP Traffic – Dial Plan
The purpose of the Matching From Header is to provide source SIP URI matching, as well as source
Transport and Network Address. In the Regular Expression, you create criteria for the From Header
SIP URI of the SIP messages. This is used when matching requests in the Dial Plan. For a request to
match, all criteria must be fulfilled.
The purpose of the Matching Request URI is to match on incoming Request URI Header of the SIP
messages being sent to the Ingate. Typically, the “domain” portion of the URI is the Ingate IP
Address or FQDN. In the Regular Expression, you create criteria for the Request-URI of the SIP
messages. This is used when matching requests in the Dial Plan. For a request to match, all criteria
must be fulfilled.
Port and Transport can be used but it only matches if there's both a port and a transport parameter
contained in the SIP URI
The purpose of the Forward To attribute of the Dial Plan is to define where to send the SIP traffic. A
specific destination SIP URI address is defined to forward the call to. Here you may enter Regular
Expressions for the Dial Plan, used to define where and how the firewall should forward the request
using the Dial Plan. Here you may also enter rules for GHM and variable substitution.
SIP Traffic – Routing
With Static Registrations you can specify that calls to a certain user address should also be redirected
to another address, or that calls to a non-person user name (like support@company.com) should be
redirected to one or more other addresses. Even if a call should be forwarded, the SIParator will try to
put it through to the original addressee.
The User Routing table makes it possible to allow advanced routing options to be enabled per user.
You may enter aliases that are used to match incoming request to a specific user. Additionally you
may define that the request should be forwarded to other users, and also set up connections to voice
mail.
In respective Forward to field you may use Variable substitution and GHM, but not regular
expressions.
SIP Trunk – Trunk 1-n
From PBX/SIP Number/User - Can contain a number/name or regular expression. For outgoing
calls, this field is matched to the calling user's user name in the From SIP URI (often a number but
can also be a name). If there is a match, this line is selected for usage for the outgoing call.
User Name - The SIP user name to use in the From SIP URI for outgoing calls and registrations.
This is usually the telephone number of the ITSP SIP account and usually the number displayed as
caller ID on the PSTN. In this field you can use the result of a sub-expression from a match in a
regular expression defined in the "From Number/User" field on the same row.
ITSP
LAN WAN
PBX lines
SIP lines
Lines, are gone through row for row until match. In case of no match the values from Main Trunk
Line are used.
When there is a match in Incoming Trunk Match field, the call will be forwarded according to the
values in respective Forward to field at the same row. For PBX Lines, this is the number an
incoming call will be forwarded to on the PBX. For SIP Lines, this is the SIP address (complete SIP
URI or a SIP user name/number on this unit's SIP Server) an incoming call will be forwarded to.
Regular expressions can be used in the Incoming Trunk Match field to catch information from the
R-URI to be used in the Forward to field, where also variable substitution and GHM can be made.
Outgoing calls are processed through the Dial Plan. The Dial Plan table is searched line by line from
the top for a match from the PBX of the dialed number where after it is forwarded to the SIP Trunk
page.
At the SIP Trunk Page, the caller’s number (the user part of the From header) will - row by row, from
ITSP
LAN WAN
Dial Plan
From header Request URI Forward to
PBX lines
SIP lines
top to bottom - be checked against the numbers or regular expressions entered in the column From
PBX/SIP Number/User. A match will cause the trunk account under User Name to be used for the
outgoing call.
The results of subexpressions from a match in the column From PBX/SIP Number/User can be used in
the columns Display Name, User Name and Identity.
To understand how GHM works it is first necessary to understand how regular expressions are used,
see next chapter.
3 Regular Expressions
Within the SIP Protocol (RFC 3261), a SIP URI identifies a communications resource. Like all URIs,
SIP URIs may be placed in web pages, email messages, or printed literature. They contain sufficient
information to initiate and maintain a communication session with the resource. In its simplest form a
SIP URI looks like sip:user@host, where the "user" is the identifier of a particular client resource
at the host being addressed. The term "host" in this context frequently refers to a domain, a
network location.
When using Regular Expressions to define a SIP URI, these expressions allow for the customization
and flexibility to define SIP URIs as variables. Regular expressions can increase the capabilities of
the Ingate Dial Plan and SIP trunk pages as it further increases the definitions of the SIP URIs used to
route calls. The Regular Expression can be used to define both the user and host portion of the SIP
URI.
3.1.1 Examples
(.*) Stores any amount of characters in $1
sip:(.*)@(.*) Stores user in $1 and host in $2 if applied to sip:user@host
Sub-expressions are numbered in the order of their starting parenthesis and referred to as $number. In
the expression sip:(.*)@(.*) which matches any Request-URl like sip:user@ingate.com, there
are two referable sub-expressions: user, which is referred to as $1, and ingate.com, which is
referred to as $2.
Sub-expression can also be nested, as in the expression (sip:(.*))@ingate.com, which matches
any Request-URI like sip:user@ingate.com, there are two referable sub-expressions:
sip:user, which is referred to as $1, and user, which is referred to as $2.
3.2 Routing of calls using the Dial Plan and the SIP trunk Page
The dial plan and the SIP Trunk pages are used to instruct the Ingate SIP Proxy or B2BUA about
how to route calls. Who to accept calls from, match on where calls are going to, and where to send
calls. Adding regular expressions into the dial plan and the SIP trunk page allows you to specify a
range of numbers, range of domains, or other set of specific digits.
Regular expressions are a flexible way of delivering patterns that match a unique set of criteria. For
example, if you specify the regular expression [0-9]{7,} Ingate Firewall/SIParator recognizes any
digits from zero to nine, repeated seven or more times, in other words, a telephone number.
sip:+$1@example.com sip:$1@example.com;from="sip:$(from.user)@1.2.3.4"
Adding Any Combination (This is an example of adding Transport, Port, B2BUA and From
Header)
sip:$1@192.168.1.1:5060;transport=TCP;b2bua;from="sip:$(from.user)@1.2.3.4"
sip:$1@example.com:5060;transport=TCP;b2bua;from="sip:$(from.user)@1.2.3.4"
Note: the Adding From Header parameter includes an example of Variable Substitution. See
chapter 5 Variable Substitution for clarification.
Note: the From Header is the only header that can be added in this way i.e. using the ;uriparams
format. All headers can be added through GHM, including the From header. See chapter 6 Generic
Header Manipulation (GHM).
Note that RFC3261 deprecates the use of transport=tls although its use on an Ingate is still possible
for compatibility. If an ITSP Contact: header contains the transport parameter “transport=tcp” in
one response, but removes it in another response – implying “transport=udp” – the transport will be
deemed to have changed on the ITSP side, and the Ingate will contact the new destination. If the
ITSP cannot handle this transport change (where two separate daemons listen for traffic via the two
different transports which may be unaware of each other), this is an error that the ITSP must correct.
3.9 Specifying Escape Characters (dial string) for e.g. Telia SIP trunk
Reg Expr:
;escape-chars=*#
...$(REGMATCH_123_REGMOD_456_REGELSE_(.*)_REGMOD_789_REGEND.from.user)...
first takes the user portion of the From: header, and then performs the regular match/replace which
must be enclosed by the tags “REGMATCH_” and “_REGEND” as above;
• the user portion of the From: header is compared with 123. If the user portion contains 123, then the
result is modified to 456.
• else, the user portion of the From: header is compared with (.*) which greedily matches everything,
so the result of the above expression would be 789.
This was a simplified example just to show the basic logic. In practice this can be much more
complex. Note: the examples here are to be embedded in a GHM like:
$0?From=$(REGMATCH_123_... and must contain %40 (an @ symbol). See later examples
Note: The result from the match from each “REGMATCH_” tag respective “REGELSE_” tag is
valid only for a replacement in the respectively immediately following “REGMOD_” tag.
4.3 Generic Number Reduction to + prefix for phone numbers 8-12 digits long
Rule
Regexp
Expression
Match Modify
REGMATCH_ ^00([0-9]{8,12})$ _REGMOD_ +$1 _REGELSE_
^0([0-9]{8,12})$ _REGMOD_ +31$1 _REGELSE_
^+([0-9]{8,12})$ _REGMOD_ +$1 _REGELSE_
^(.*)$ _REGMOD_ +$1 _REGEND
Encoded expression producing a valid From header, operating on user portion of From header
?From=%3csip%3a$(REGMATCH_^00([0-9]{8,12})$_REGMOD_+$1_REGELSE_^0([0-
9]{8,12})$_REGMOD_+31$1_REGELSE_^+(.*)$_REGMOD_+$1_
REGELSE_^(.*)$_REGMOD_+$1_REGEND.from.user)%40$(from.host)$([from.uriparams])%3e$
(from.params)
Note: In firmware versions <= 5.0.11 you cannot use $1?From=$(......$1...) – i.e. capture groups on
the trunk page (i.e. where $1 is before and after the “?”), and $REGMATCH expressions which also
contain $1. The workaround is to use $0?From=$(....$1…). See Errata.
5 Variable Substitution
The Ingate firmware has a range of variables to access all headers and URIs.
Where a SIP URI could be:
dname <sip:user:password@host:port;uriparams>;params
Below is a list of the variables used to access URI and header portions for use in substitution:
Variable Explanation
cfg.user The user part of the Local registrar account matched (if any) by a
request
cfg.host The host part of the Local registrar account matched (if any) by a
request
ruri.user User portion of Request-URI
ruri.host Host portion of Request-URI
ruri.uriparams URI parameters of Request-URI
header_name.user User of header "header_name" (e.g. to.user)
header_name.userinfo The whole user portion, containing password, up to the @ symbol.
header_name.password Password of header "header_name" (e.g. to.password)
2
header_name.cpassword As password; but prepended with colon (“:password”) 2. Will only
expand if header_name .userinfo contains a password.
header_name.userinfo User, Password and Parameters of user portion e.g. “joe:123”, or
“joe;tgrp=1…”. In effect, everything between sip(s): and @
header_name.userinfoat As above, but includes the final @ symbol – eases creation of valid
2
URI. E.g. ?foo=$([from.userinfoat])example.com
will only expand to "userinfo@" if the header_name contains userinfo.
header_name.host Host portion of header "header_name" (e.g. contact.host)
header_name.port Port portion of header "header_name" (e.g. contact.port)
2
header_name.cport As port, but prepended with a colon “:”.
E.g. ?foo=example.com$([from.cport]) Note: Only expands if
header_name contains a port param.
header_name.dname Display name of header "header_name" (e.g. from.dname)
header_name.uqdname Unquoted display name of header "header_name" (e.g. from.uqdname)
header_name.params Header parameters of header "header_name" (e.g. contact.params)
header_name.uriparams URI parameters of header "header_name" (e.g. contact.uriparams)
header_name.telnum Tel-URI telephone number of header "header_name" (e.g.
from.telnum)
header_name.uri Complete URI of header "header_name" (e.g. contact.uri)
hdr.header_name The complete header value of header "header_name"
hdr.header_name[2] The complete header value of 2nd occurrence of header
“header_name”
rawhdr.header_name The complete header value of header "header_name" (not escaped)
ip.interface The IP address of physical network interface "interface", (e.g. ip.eth1)
header_name.dnameu Display name and complete URI of header "header_name" (e.g.
ri1 from.dnameuri)
1 2
(Available from SW version 5.0.4) (Available from SW > 6.0.0)
Where a SIP URI is:
dname <sip:user:password@host;uriparams>;params
And may be formed by:
$(x.dname) <sip:$(x.user):$(x.password)@$(x.host)$(x.uriparams)>$(x.params)
Or may be formed by:
$([x.dname]) <sip:$([x.user]):$([x.password])@$([x.host])$([x.uriparams])>$([x.params])
which may be formed by the encoded string:
$([x.dname])%20%3Csip:$([x.user]):$([x.password])%40$([x.host])$([x.uriparams])%3E$([x.params])
All variables are invoked by using the $(variable) syntax. The same is achieved by using
$([variable]) – the difference being that, if the content of $([variable]) is empty, then
the result is not inserted. If $(variable) syntax is empty, the literal string $(variable) is inserted.
The $([variable]) syntax is available from firmware >= 4.10.1.
Note: To use any variables, a regular expression match must have been done, together with a regular
expression substitution. E.g. $1?header=…
If you just want to rewrite the From header, use the Forward To Reg Expr field and append a
";from=" parameter. The from parameter value may contain references to Reg Expr sub-strings. It
may reference both sub-strings in the Matching From Header, and the Matching Request-URI Reg
Expr fields. Sub-strings of the From header are referenced as $fx (where x is an integer, 0 or
greater). And Request-URI sub-strings are referenced as $rx.
Parameters password and port are always prepended by a semicolon. If you write an expression
…$(from.user)%40(from.host)%3a(from.port)… where the from header contained no port
parameter, your string evaluates to 123@192.168.1.1: which is an invalid URI, since there is no
port value after the colon. If it is unknown in advance whether port or password would be found in a
URI of an incoming SIP message, the following CHMs (which require firmware >= 5.0.4) can work
around whether or not to insert a semicolon dependent upon the respective parameters’ existence:
$(CONDIF.from.port)$(CONDYES.PLAIN.%3A)$(CONDYES.from.port)
or
$(CONDIF.from.password)$(CONDYES.PLAIN.%3A)$(CONDYES.from.password)
Convenience variables for the above are provided in Ingate firmware >= v6.0:
header_name.cport yields e.g. :5060
header_name.cpassword yields e.g. :p@$$word
5.2 Examples
sip:$1@192.168.1.1?Diversion=%3csip%3a7202839130%40192.168.1.1%3e
P-Asserted Identity
sip:$1@192.168.1.1?P-Asserted-Identity=%3csip%3a7202839130%40192.168.1.1%3e
sip:$1@example.com?P-Asserted_Identity=%3csip%3a7202839130%40192.168.1.1%3e
Diversion
sip:$1@192.168.1.1?Diversion=%3csip%3a7202839130%40192.168.1.1%3e
sip:$1@example.com?Diversion=%3csip%3a7202839130%40192.168.1.1%3e
Privacy
sip:$1@192.168.1.1?Diversion=<url-encoded_string>
sip:$1@example.com?Diversion=<url-encoded_string>
Multiple
sip:$1@192.168.1.1?P-Asserted-Identity=<url-encoded>&Diversion=<url-encoded>
sip:$1@example.com?P-Asserted-Identity=<url-encoded>&Diversion=<url-encoded>
Used in combination with regular expression
sip:$1@192.168.1.1;b2bua;from="Anonymous@10.182.0.178"
?P-Asserted-Identity=<url-encoded_string>&Privacy=id
Note: Replace <url-encoded_string> with the new header value.
Reduce the From header prefix to USA +1, pass any other URI parameters
sip:$0?From=%3Csip%3a$(REGMATCH_^001([0-9]{10})$_REGMOD_+1$1_REGELSE_^1([0-
9]{10})$_REGMOD_+1$1_REGELSE_([0-
9]{10})$_REGMOD_+1$1_REGEND.from.user)%40$(from.host)$(CONDIF.from.uriparams)$
(CONDYES.from.uriparams)%3E$(from.params)
Reduce the From header prefix to USA +1, pass any other URI parameters (alternative)
sip:$0?From=%3Csip%3a$(REGMATCH_^001([0-9]{10})$_REGMOD_+1$1_REGELSE_^1([0-
9]{10})$_REGMOD_+1$1_REGELSE_([0-
9]{10})$_REGMOD_+1$1_REGEND.from.user)%40$(from.host)$([from.uriparams]) %3E$(
from.params)
Strip the Display name portion out of the From header
sip:$1@192.168.1.1?From=$(from.uri)
?from=$(CONDIF.diversion.user)$(CONDYES.PLAIN.%3csip%3a12345678%40company.com%3
e)$(CONDNO.PLAIN.%3csip%3aABCDEFGH%40company.com%3e)
When there is a user portion of a Diversion: header, then the From: header produced will be
<sip:12345678@company.com>, otherwise it will be <sip:ABCDEFGH@company.com>
Resulting in either:
(CONDYES) ...
Diversion: joe@domain
From: <sip:12345678@company.com>
or
(CONDNO) ...
Diversion: empty or non-existent URI
From: <sip:ABCDEFGH@company.com>
Contact: <sip:E4F0pr9vEUD3axDnp@192.0.2.2>
Supported: timer, replaces, path, histinfo
Allow: ACK, CANCEL, INVITE, BYE, NOTIFY, INFO, OPTIONS, PRACK, REFER, UPDATE
Max-Forwards: 15
Content-Type: application/sdp
Content-Length: ...
Will also evaluate to NO (because no Diversion header exists - a ‘Divresion’ header exists, however),
thus producing:
%3csip%3aABCDEFGH%40company.com%3e
The expression again becomes:
?from=%3csip%3aABCDEFGH%40company.com%3e
A note about parameters: we have not included any parameters in our expression. The b2bua will add
its own special ;tag parameter separately to the new From header. Any ;tag parameter you copy
from the source through the use of a $(from.params) expression will be updated separately by the
b2bua, but other parameters will remain unchanged. If you want to include any parameters found
after <sip:…> in your result, add $(from.params) to your expression:
?from=$(CONDIF.diversion.user)$(CONDYES.PLAIN.%3csip%3a12345678%40company.com%3e)
$(CONDNO.PLAIN.%3csip%3aABCDEFGH%40company.com%3e)$(from.params)
?from=$(CONDIF.diversion.user)$(CONDYES.PLAIN.%3csip%3a)$(CONDYES.REGMATCH_^\+([0-9]+)
$_REGMOD_+$1_REGELSE_^00([0-9]+)$_REGMOD_+$1_REGELSE_^0([0-9]+)
$_REGMOD_+46$1_REGELSE_(.*)_REGMOD_$1_REGEND.from.user)$(CONDYES.PLAIN.%40company.com%3e
)$(CONDNO.PLAIN.%3csip%3aABCDEFGH%40company.com%3e)
This does the following:
1. Where the message from the PBX contains a Diversion: header, then the username portion in the
From: header (appended with “company.com”) replaces the From: header of the message sent out,
after applying the Sweden number Reduction example.
2. Where the message from the PBX does not contain a Diversion: header, no header manipulation is
performed.
Resulting in either:
(CONDYES) ...
Diversion: mike@domain
From: <sip:+46812345678@company.com>
or an unmodified from header:
(CONDNO) ...
From: <sip:0812345678@company.com>
?from=$(CONDIF.history-info[-1].user)$(CONDYES.PLAIN.%3csip%3a)
$(CONDYES.REGMATCH_^\+([0-9]+)$_REGMOD_+$1_REGELSE_^00([0-9]+)$_REGMOD_+
$1_REGELSE_^0([0-9]+)$_REGMOD_+46$1_REGELSE_(.*)_REGMOD_$1_REGEND.from.user)
$(CONDYES.PLAIN.%40company.com%3e)
Note: that history-info[-1] refers to the last history-info header present in the SIP message from the
PBX.
Resulting in either:
(CONDYES) ...
History-Info: qwerty
From: <sip:+46812345678@company.com>
or an unmodified from header:
(CONDNO) ...
From: <sip:0812345678@company.com>
?from=$(CONDIF.REGMATCH_^911$_REGEND.to.user)$(CONDYES.PLAIN.%3csip%3a5557778888%40192.0
.2.2%3e)$(CONDNO.PLAIN.%3csip%3a5551012001%40192.0.2.2%3e)
Resulting in either (911 is being called):
(CONDYES) ...
From: <sip:5556668888@192.0.2.2>
Or (911 is not being called):
(CONDNO) ...
From: <sip:5551012001@192.0.2.2>
?from=$(CONDIF.diversion.user)$(CONDYES.PLAIN.%3csip%3a)
$(CONDYES.REGMATCH_^\+([0-9]+)$_REGMOD_+$1_REGELSE_^00([0-9]+)$_REGMOD_+
$1_REGELSE_^0([0-9]+)$_REGMOD_+46$1_REGELSE_(.*)_REGMOD_$1_REGEND.from.user)
$(CONDYES.PLAIN.%40company.com%3e)&P-Preferred-
Identity=%3csip%3aanother_id%40shop.com%3e
Resulting in either:
(CONDYES) ...
Diversion: mike@domain
From: <sip:+46812345678@company.com>
P-Preferred-Identity: <sip:another_id@shop.com>
or an unmodified from header:
(CONDNO) ...
From: <sip:0812345678@company.com>
P-Preferred-Identity: <sip:another_id@shop.com>
Note: If you want to add a header (which did not already exist in the message) only under certain
circumstances e.g.: Replace a possibly existing Referred-By: header with a Diversion: header
?Diversion=$(CONDIF.Referred-By.user)$(CONDNO.ABORT)$(CONDYES.PLAIN.%3csip%3a)
$(CONDYES.Referred-By.user)$(CONDYES.PLAIN.%40)$(CONDYES.ReferredBy.host)
$(CONDYES.PLAIN.%3e)&Referred-By=__remove
If no Referred-By header is present then without the $(CONDNO.ABORT) the following string for
header manipulation would remain:
?Diversion=
&Referred-By=__remove
which would result in an empty diversion header in the resulting message. But with the
$(CONDNO.ABORT), the resulting header manipulation string becomes
?Diversion=$(ABORT)&Referred-By=__remove
and since header manipulations with unresolved variables will be skipped, no empty diversion header
will be added. In effect becoming just:
?Referred-By=__remove
?from=$(CONDIF.diversion.user)
$(CONDYES.PLAIN.%3csip%3a&P-Preferred-Identity=%3csip%3aanother_id%40shop.com%3e)
For the above example to compile, it must be corrected – note the closing parenthesis:
?from=$(CONDIF.diversion.user)
$(CONDYES.PLAIN.%3csip%3a)&P-Preferred-Identity=%3csip%3aanother_id%40shop.com%3e
Summary: Parameter chaining only works outside of the regular expression $() context, and cannot
be chained conditionally.
8.1 Tests
$(
[ CONDIF(.REGMATCH…) |
CONDIFNOT |
CONDANDIF |
CONDANDIFNOT |
CONDORIF |
CONDORIFNOT ].Header.Portion
)
8.2 Results
$(
CONDYES
.PLAIN.Text |
.Header.Portion |
.ABORT
| CONDNO
.PLAIN.Text |
.Header.Portion |
.ABORT
)
8.3 RegExp
$(
REGMATCH_
_REGMOD_
_REGELSE_
_REGMOD_
…
_REGEND.Header.Portion
)
Note: Keywords and expressions are evaluated from left to right, i.e. forwards in their construction.