# Functions

## `allow_routing()`

Returns true if all pairs constructed as described in have appropriate permissions according to the configuration files. This function uses default configuration files specified in `default_allow_file` and `default_deny_file`.

### `allow_routing` usage

    ...
    if (allow_routing()) {
        t_relay();
    };
    ...

## `allow_routing(basename)`

Returns true if all pairs constructed as described in have appropriate permissions according to the configuration files given as parameters.

Meaning of the parameters is as follows:

- basename - Basename from which allow and deny filenames will be created by appending contents of `allow_suffix` and `deny_suffix` parameters.

  If the parameter doesn't contain full pathname then the function expects the file to be located in the same directory as the main configuration file of the server.

### `allow_routing(basename)` usage

    ...
    if (allow_routing("basename")) {
        t_relay();
    };
    ...

## `allow_routing(allow_file, deny_file)`

Returns true if all pairs constructed as described in have appropriate permissions according to the configuration files given as parameters.

Meaning of the parameters is as follows:

- allow_file - File containing allow rules.

  If the parameter doesn't contain full pathname then the function expects the file to be located in the same directory as the main configuration file of the server.

- deny_file - File containing deny rules.

  If the parameter doesn't contain full pathname then the function expects the file to be located in the same directory as the main configuration file of the server.

### `allow_routing(allow_file, deny_file)` usage

    ...
    if (allow_routing("rules.allow", "rules.deny")) {
        t_relay();
    };
    ...

## `allow_register(basename)`

The function returns true if all pairs constructed as described in have appropriate permissions according to the configuration files given as parameters.

Meaning of the parameters is as follows:

- basename - Basename from which allow and deny filenames will be created by appending contents of `allow_suffix` and `deny_suffix` parameters.

  If the parameter doesn't contain full pathname then the function expects the file to be located in the same directory as the main configuration file of the server.

### `allow_register(basename)` usage

    ...
    if (method=="REGISTER") {
        if (allow_register("register")) {
            save("location");
            break;
        } else {
            sl_send_reply("403", "Forbidden");
        };
    };
    ...

## `allow_register(allow_file, deny_file)`

The function returns true if all pairs constructed as described in have appropriate permissions according to the configuration files given as parameters.

Meaning of the parameters is as follows:

- allow_file - File containing allow rules.

  If the parameter doesn't contain full pathname then the function expects the file to be located in the same directory as the main configuration file of the server.

- deny_file - File containing deny rules.

  If the parameter doesn't contain full pathname then the function expects the file to be located in the same directory as the main configuration file of the server.

### `allow_register(allow_file, deny_file)` usage

    ...
    if (method=="REGISTER") {
        if (allow_register("register.allow", "register.deny")) {
            save("location");
            break;
        } else {
            sl_send_reply("403", "Forbidden");
        };
    };
    ...

## `allow_refer_to(basename)`

The function returns true if all pairs constructed as described in have appropriate permissions according to the configuration files given as parameters.

Meaning of the parameters is as follows:

- basename - Basename from which allow and deny filenames will be created by appending contents of `allow_suffix` and `deny_suffix` parameters.

  If the parameter doesn't contain full pathname then the function expects the file to be located in the same directory as the main configuration file of the server.

### `allow_register(basename)` usage

    ...
    if (method=="REGISTER") {
        if (allow_register("register")) {
            save("location");
            break;
        } else {
            sl_send_reply("403", "Forbidden");
        };
    };
    ...

## `allow_refer_to(allow_file, deny_file)`

The function returns true if all pairs constructed as described in Section 1.1.2 have appropriate permissions according to the configuration files given as parameters.

Meaning of the parameters is as follows:

- allow_file - File containing allow rules.

  If the parameter doesn't contain full pathname then the function expects the file to be located in the same directory as the main configuration file of the server.

- deny_file - File containing deny rules.

  If the parameter doesn't contain full pathname then the function expects the file to be located in the same directory as the main configuration file of the server.

### `allow_register(allow_file, deny_file)` usage

    ...
    if (method=="REFER") {
        if (allow_register("refer.allow", "refer.deny")) {
           ...
        } else {
            sl_send_reply("403", "Forbidden");
        };
    };
    ...

## `ipmatch (string/AVP/select, [avp])`

The function tries to find an IP address and port pair (defined by the first function parameter) in the cached database table. Port is optional, it is compared only if both the function parameter and the database entry contain it.

Meaning of the parameters is as follows:

- string/AVP/select - File containing allow rules.

  - string:

    "src": the source address of the packet is used "via2": the ip address of the 2nd via line is used other values are not defined currently

  - AVP:

    e.g. "$myavp"

  - select call:

    e.g. "@via[0].host"

- The second parameter is optional, it is used to set an AVP value from the database. Suitable for assigning logical identifiers to gateways.

Note that IPv6 addresses must be enclosed in square brackets in case of port is defined: [1111:2222::3333]:5060

## `ipmatch_onsend (string)`

`ipmatch()` function replacement for onsend_route block.

The function accepts only string parameter, because even AVP reading is unsafe in onsend_route.

Meaning of the parameter:

- "dst":

  the destination address is used

- "ruri":

  the ip:port pair is extracted from the Request URI

The function can be used for example to catch unauthorized requests going to gateways: Use a flag to mark the call as PSTN either in request or in failure_route, and do not touch it in onreply_route. See the examples below.

## `ipmatch_filter (unsigned int)`

Entries in the database can be marked to group the different kind of network elements. The function sets the filter which is used on the mark while comparing the IP addresses. The mark must be the power of 2 in the database!

Note that ipmatch() and ipmatch_onsend() functions reset the filter!

### `ipmatch_filter (unsigned int)` usage

    +-----------------+-------------------+------+------+
    | ip              | avp_val           | mark | flag |
    +-----------------+-------------------+------+------+
    | 1111:2222::1001 | first_gw          |    1 |    1 |
    | 10.38.2.10:5060 | second_gw         |    1 |    1 |
    | 10.0.0.10       | first_peering     |    2 |    1 |
    +-----------------+-------------------+------+------+

    route[0] {
      # is this a request from a GW?
      ipmatch_filter("1");
      if (ipmatch("src", "$gw_id")) {
        # yes, it is from a GW
        ...
      } else {
        # is this a request from a peering partner?
        ipmatch_filter("2");
        if (ipmatch("src", "$peering_id")) {
           # yes, it is from a peering partner
           ...
        };
      }
      ...
      # request goes to PSTN
      setflag(PSTN);
    }

    onsend_route[0] {
      if (method == "INVITE" && (!isflagset(PSTN))) {
         # is this a request to a GW?
         ipmatch_filter("1");
         if (ipmatch_onsend("dst")) {
            # request is not marked with PSTN flag, but it goes to a gateway
            drop;
         }
      }
      ...
    }

## `ip_is_trusted(ip_set, ip)`

The function returns true if ip is contained in ip_set. Both IPv4 and IPv6 are supported.

Meaning of the parameters is as follows:

- ip_set is identified by comma/space/semicolon delimited list of IP addresses or subnet masks. The subnet mask is written in IP_slash_number form or as IP. If the mask is not mentioned then default value is taken, the default value is number of bits of particular IP address, i.e. 32 in case of IPv4, 128 in case of IPv6.

  Besides list also ip set identifier declared by `declare_ipset` may be provided. In this case ip is checked against set maintainded by RPC commands.

- ip to test. Besides direct address in string form there are extra identifiers to force IP related to current message: Source, Destination, Received. Note that only the first character is essential.

### `ip_is_trusted` usage

    modparam("permissions", "declare_ipset", "my_ipset1");
    modparam("permissions", "declare_ipset", "my_ipset2=127.0.0.0/24;10.0.0.0/255.255.255.0");

    route[TT2] {
    	if (ip_is_trusted("$net", "$ip")) {
    		xplog("L_E", "'%$ip' - TRUE\n");
    	} else {
    		xplog("L_E", "'%$ip' - FALSE\n");
    	}
    }

    route[TT1] {
    	xplog("L_E", "Testing netmask '%$net'\n");

    	$ip = "s";   # source address
    	route(TT2);

    	$ip = "127.0.0.1";
    	route(TT2);

    	$ip = "127.0.0.2";
    	route(TT2);

    	$ip = "10.0.0.1";
    	route(TT2);

    	$ip = "11.0.0.1";
    	route(TT2);

    	$ip = "172.1.8.1";
    	route(TT2);

    	$ip = "192.168.1.1";
    	route(TT2);

    	$ip = "192.168.1.255";
    	route(TT2);

    	$ip = "192.168.2.1";
    	route(TT2);

    	$ip = "192.168.3.1";
    	route(TT2);

    	$ip = "192.168.4.97";
    	route(TT2);

    	$ip = "192.168.4.100";
    	route(TT2);

    	$ip = "[0:2:4:A:B:D:E:F301]";
    	route(TT2);

    	$ip = "[0:2:4:A:B:D:E:F401]";
    	route(TT2);

    	$ip = "[0:0:0:0:0:0:0:0]";
    	route(TT2);
    }

    route[TEST] {
    	$net = "0.0.0.0 128.2.3.4/1 127.0.128.16 [0:2:4:A:B:D:E:F301]";
    	route(TT1);

    	$net = "255.255.255.255/0"; # all IPv4 addresses, dentical to 0.0.0.0/0
    	route(TT1);

    	$net = "127.0.0.1/255.255.255.0";
    	route(TT1);

    	$net = "10.0.0.0/8";  # All type A addresses
    	route(TT1);

    	$net = "192.168.1.0/24";
    	route(TT1);

    	$net = "192.168.4.96/27";
    	route(TT1);

    	$net = "192.168.1.1/32"; # only one IP matches
    	route(TT1);

    	$net = "192.168.1.0/24,192.168.2.0/24";
    	route(TT1);

    	$net = "192.168.1.0/24,192.168.2.0/24,127.0.0.1/31";
    	route(TT1);

    	$net = "[0:0:0:0:0:0:0:0]/0";  # all IPv6 addresses
    	route(TT1);

    	$net = "[0:2:4:A:B:D:E:f300]/120";
    	route(TT1);

    	$net = "my_ipset1";
    	route(TT1);

    }
    # the result is:

    Testing netmask '0.0.0.0 128.2.3.4/1 127.0.128.16 [0:2:4:A:B:D:E:F301]'
    's' - FALSE
    '127.0.0.1' - FALSE
    '127.0.0.2' - FALSE
    '10.0.0.1' - FALSE
    '11.0.0.1' - FALSE
    '172.1.8.1' - TRUE
    '192.168.1.1' - TRUE
    '192.168.1.255' - TRUE
    '192.168.2.1' - TRUE
    '192.168.3.1' - TRUE
    '192.168.4.97' - TRUE
    '192.168.4.100' - TRUE
    '[0:2:4:A:B:D:E:F301]' - TRUE
    '[0:2:4:A:B:D:E:F401]' - FALSE
    '[0:0:0:0:0:0:0:0]' - FALSE
    Testing netmask '255.255.255.255/0'
    's' - TRUE
    '127.0.0.1' - TRUE
    '127.0.0.2' - TRUE
    '10.0.0.1' - TRUE
    '11.0.0.1' - TRUE
    '172.1.8.1' - TRUE
    '192.168.1.1' - TRUE
    '192.168.1.255' - TRUE
    '192.168.2.1' - TRUE
    '192.168.3.1' - TRUE
    '192.168.4.97' - TRUE
    '192.168.4.100' - TRUE
    '[0:2:4:A:B:D:E:F301]' - FALSE
    '[0:2:4:A:B:D:E:F401]' - FALSE
    '[0:0:0:0:0:0:0:0]' - FALSE
    Testing netmask '127.0.0.1/24'
    's' - FALSE
    '127.0.0.1' - TRUE
    '127.0.0.2' - TRUE
    '10.0.0.1' - FALSE
    '11.0.0.1' - FALSE
    '172.1.8.1' - FALSE
    '192.168.1.1' - FALSE
    '192.168.1.255' - FALSE
    '192.168.2.1' - FALSE
    '192.168.3.1' - FALSE
    '192.168.4.97' - FALSE
    '192.168.4.100' - FALSE
    '[0:2:4:A:B:D:E:F301]' - FALSE
    '[0:2:4:A:B:D:E:F401]' - FALSE
    '[0:0:0:0:0:0:0:0]' - FALSE
    Testing netmask '10.0.0.0/8'
    's' - FALSE
    '127.0.0.1' - FALSE
    '127.0.0.2' - FALSE
    '10.0.0.1' - TRUE
    '11.0.0.1' - FALSE
    '172.1.8.1' - FALSE
    '192.168.1.1' - FALSE
    '192.168.1.255' - FALSE
    '192.168.2.1' - FALSE
    '192.168.3.1' - FALSE
    '192.168.4.97' - FALSE
    '192.168.4.100' - FALSE
    '[0:2:4:A:B:D:E:F301]' - FALSE
    '[0:2:4:A:B:D:E:F401]' - FALSE
    '[0:0:0:0:0:0:0:0]' - FALSE
    Testing netmask '192.168.1.0/24'
    's' - FALSE
    '127.0.0.1' - FALSE
    '127.0.0.2' - FALSE
    '10.0.0.1' - FALSE
    '11.0.0.1' - FALSE
    '172.1.8.1' - FALSE
    '192.168.1.1' - TRUE
    '192.168.1.255' - TRUE
    '192.168.2.1' - FALSE
    '192.168.3.1' - FALSE
    '192.168.4.97' - FALSE
    '192.168.4.100' - FALSE
    '[0:2:4:A:B:D:E:F301]' - FALSE
    '[0:2:4:A:B:D:E:F401]' - FALSE
    '[0:0:0:0:0:0:0:0]' - FALSE
    Testing netmask '192.168.4.96/27'
    's' - FALSE
    '127.0.0.1' - FALSE
    '127.0.0.2' - FALSE
    '10.0.0.1' - FALSE
    '11.0.0.1' - FALSE
    '172.1.8.1' - FALSE
    '192.168.1.1' - FALSE
    '192.168.1.255' - FALSE
    '192.168.2.1' - FALSE
    '192.168.3.1' - FALSE
    '192.168.4.97' - TRUE
    '192.168.4.100' - TRUE
    '[0:2:4:A:B:D:E:F301]' - FALSE
    '[0:2:4:A:B:D:E:F401]' - FALSE
    '[0:0:0:0:0:0:0:0]' - FALSE
    Testing netmask '192.168.1.1/32'
    's' - FALSE
    '127.0.0.1' - FALSE
    '127.0.0.2' - FALSE
    '10.0.0.1' - FALSE
    '11.0.0.1' - FALSE
    '172.1.8.1' - FALSE
    '192.168.1.1' - TRUE
    '192.168.1.255' - FALSE
    '192.168.2.1' - FALSE
    '192.168.3.1' - FALSE
    '192.168.4.97' - FALSE
    '192.168.4.100' - FALSE
    '[0:2:4:A:B:D:E:F301]' - FALSE
    '[0:2:4:A:B:D:E:F401]' - FALSE
    '[0:0:0:0:0:0:0:0]' - FALSE
    Testing netmask '192.168.1.0/24,192.168.2.0/24'
    's' - FALSE
    '127.0.0.1' - FALSE
    '127.0.0.2' - FALSE
    '10.0.0.1' - FALSE
    '11.0.0.1' - FALSE
    '172.1.8.1' - FALSE
    '192.168.1.1' - TRUE
    '192.168.1.255' - TRUE
    '192.168.2.1' - TRUE
    '192.168.3.1' - FALSE
    '192.168.4.97' - FALSE
    '192.168.4.100' - FALSE
    '[0:2:4:A:B:D:E:F301]' - FALSE
    '[0:2:4:A:B:D:E:F401]' - FALSE
    '[0:0:0:0:0:0:0:0]' - FALSE
    Testing netmask '192.168.1.0/24,192.168.2.0/24,127.0.0.1/31'
    's' - FALSE
    '127.0.0.1' - TRUE
    '127.0.0.2' - FALSE
    '10.0.0.1' - FALSE
    '11.0.0.1' - FALSE
    '172.1.8.1' - FALSE
    '192.168.1.1' - TRUE
    '192.168.1.255' - TRUE
    '192.168.2.1' - TRUE
    '192.168.3.1' - FALSE
    '192.168.4.97' - FALSE
    '192.168.4.100' - FALSE
    '[0:2:4:A:B:D:E:F301]' - FALSE
    '[0:2:4:A:B:D:E:F401]' - FALSE
    '[0:0:0:0:0:0:0:0]' - FALSE
    Testing netmask '[0:0:0:0:0:0:0:0]/0'
    's' - FALSE
    '127.0.0.1' - FALSE
    '127.0.0.2' - FALSE
    '10.0.0.1' - FALSE
    '11.0.0.1' - FALSE
    '172.1.8.1' - FALSE
    '192.168.1.1' - FALSE
    '192.168.1.255' - FALSE
    '192.168.2.1' - FALSE
    '192.168.3.1' - FALSE
    '192.168.4.97' - FALSE
    '192.168.4.100' - FALSE
    '[0:2:4:A:B:D:E:F301]' - TRUE
    '[0:2:4:A:B:D:E:F401]' - TRUE
    '[0:0:0:0:0:0:0:0]' - TRUE
    Testing netmask '[0:2:4:A:B:D:E:f300]/120'
    's' - FALSE
    '127.0.0.1' - FALSE
    '127.0.0.2' - FALSE
    '10.0.0.1' - FALSE
    '11.0.0.1' - FALSE
    '172.1.8.1' - FALSE
    '192.168.1.1' - FALSE
    '192.168.1.255' - FALSE
    '192.168.2.1' - FALSE
    '192.168.3.1' - FALSE
    '192.168.4.97' - FALSE
    '192.168.4.100' - FALSE
    '[0:2:4:A:B:D:E:F301]' - TRUE
    '[0:2:4:A:B:D:E:F401]' - FALSE
    '[0:0:0:0:0:0:0:0]' - FALSE
    }