## SafeFire PPP

### v1.1

# Concepts Guide

## Introduction

SafeFire PPP was designed to become the most powerfull communication suite. So its internal architecture was carefully designed to implement high flexibility and extendability. To achieve this goal its structure was divided into multiple modules. Following module types are used in SafeFire PPP:

1. User interface module (usually .exe file). Provides local user interface. Simple change of the module can give you new UI. At present time SFPPP.EXE implements OS/2 command line UI and PMPPP.EXE implements PM GUI.
2. Manager module. Connects and manages all other module types.
3. Plugin Libraries (usually pl_*.dll files). Plugin libraries implement muliple plugins, in most cases of the same functional category (See section about plugins below and SafeFire PPP Plugin Reference for more details).
4. REXX modules. They can be used by any of the modules. Manager provides basic REXX SFPPP API. Other plugins may extend this API with new functions. (See SafeFire PPP REXX API Extension book for more details)
5. PPP security submodules (usually pla_*.dll files). This modules are intented to provide different authorization and authentication sources for PPP plugins. Three modules are available for now:
   - pla_rexx.dll

     > allows REXX module to be used for security functions. Some REXX modules provided to make an example and be used in simple cases.

   - pla_upm.dll

     > Uses OS/2 User Profile Magement for security checks.
     > Note: It can't be used with CHAP authentication due to certain UPM limitations.

   - pla_rad.dll

     > Basic radius authentication and accounting

Configuration file is used by manager to load, bind (connect) and configure Plugins. Single configuration file can be used to load multiple different configuration by specifying "starting section" parameter.

## Plugins

SafeFire PPP are to be used to input, process and output network packet streams. Modules are used to perform this task.

Module is fully independent piece of software that has some Stream Packs ("input/output" plugs) to peform module function. Each module performs its own data processing.

There are two main module types:

1. Filter modules

   > They provides some data transformation and usually has two or more Stream Packs. The examples are: PPP NCPs (like CCP), Filter, NAT, etc.

2. Gateway modules

   > They provide gateway for SafeFire to external packet sources. Gateways can be divided into two groups: Exteral device gateways and Internal stack gateways.

External device gateways give access to external computer network hardware like Eternet cards, Serial ports or ISDN adapters.

Internal stack gateways make connections to internal protocol stack. They are identified by stack as virtual adapters (i.e. lanXX for Eternet or pppXX for Serial PPP connection in TCPIP stack).

Usually binding route from Device gateway must lead to Stack gateway (only if you has 'Stack-like' filter module that can implement partial or full Protocol Stack functionality you can connect Device <-> 'Stack-like' <-> Device).

Modules are grouped by its categories into Module Libraries. You can find the following Module Libraries in the SafeFire PPP 1.1 package:

Library | Name | Type | Comment
pl_ppp.dll |  |  | Provides PPP External and internat gateways plus some PPP NCPs
| PPPPort | External device gateway | Used to establish PPP connection over serial device (Modem, NullModem, ISDN emulated com ports)
| PPPOE | Filter | Used to make PPP connection over Ethernet LAN
| PPPSTACK | Internal stack gateway | Makes up a Point-to-Point OS/2 TCPIP stack adapter (i.e. pppXX)
| CCP | Filter | Implements CCP NCP (Compression protocol)
pl_alias.dll | NAT | Filter | Implements Network Address Translation (NAT) functions
pl_flt.dll | FILTER | Filter | TCP/IP Packet filter module
pl_lan.dll | PROTOCOL | External device gateway | Attaches SafeFire PPP to NDIS MAC driver (network card)
pl_serv.dll | SERVICE | Filter | Implements different utility functions
pl_templ.dll | PL_TEMPL | Filter | Sample filter. Does no processing. Can be used when "null" plugin needed

## Configuration

SafeFire PPP is fully configured by a special configuration file. This file describes what plugins to load and its configuration. Configuration file consists of sections and each section can have multiple "parameter=value" lines that makes up configuration.

## Plugin Instances

While Plugin is piece of software, Plugin Instance is loaded and configured plugin. It is possible to have multiple instances of the same plugin loaded at one time. Each Plugin Instance identified by a section in configuration file. Section name is Instance's name. "LOAD" parameter tells SafeFire PPP what Plugin to load to make up this Instance. All the other parameters identifies Instance's configuration.

Here is format of "LOAD" parameter:
`LOAD=<Plugin Library>:<Plugin Name>`

Example: "`LOAD=PL_PPP:PPPPort`".

## Binding

To allow plugins to perform tasks they are designed for, all plugins should be connected to each other. Connecting process is called binding.

Each module has one or more named connection "plugs" to make connection to it. They are called Stream Packs. Each Stream Pack defines functionality or type of the data that will be passed to or from it.

Example: CCP Plugin has two Stream Packs: "DATA" and "COMPRESSED". It defines that all the data from "DATA"-connected stream will be compressed and put to "COMPRESSED"-connected stream. And visa versa - all the data from "COMPRESSED"-connected stream will be identified as compressed: CCP will try to uncompress it and put to "DATA"-connected stream.

It is possible to connect multiple streams to a single Stream Pack. Each stream must be connected to its unique connection index. You can connect up to 65535 streams (with connection indexes from 0 to 65534) to a single Stream Pack.

Note: Support and Processing of multiple-connect feature are fully dependant of the Plugin itself. You must check Plugin's documentation to find out if you can connect multiple streams to a single Stream Pack and how Plugin will process this connections. If not otherwise specified you must not make connection to the index other than 0.

All bindings are configured by a "BIND" parameter in configuration. Each plugin section may have multiple "BIND" parameters and all of them will be processed as distinct binding definition.

Here is format of "BIND" parameter:
`BIND=<name>[<startidx>]:<bindinstance>.<bindname>[<startbind>,<bindnum>];...`
where:

Element | Optionality | Default value | Description
<name> | required |  | This instance's Stream Pack name
[<startidx>] | optional | 0 | This instance's starting connection index
<bindinstance> | required |  | Connected instance's name
<bindname> | required |  | Connected instance's Stream Pack name
<startbind> | optional | 0 | Connected instance's starting connection index
,<bindnum> | optional | 1 | Number of sequental connections to make.
[<startbind>,<bindnum>] | optional | [0,1]

It is possible to have multiple "`<bindinstance>.<bindname>[<startbind>,<bindnum>]`" parts divided by ";".

This complex rule will be documented in two steps:

1. Transforming fully specified rule into multiple "BIND=<name>[<startidx>]:<bindinstance>.<bindname>[<startbind>]" rules.
   - Transform
     `BIND=<name>[<startidx>]:<bindinstance>.<bindname>[<startbind>,<bindnum>];...`
     rule into multiple
     `BIND=<name>[<startidx>]:<bindinstance>.<bindname>[<startbind>,<bindnum>]`
     rules:

     > `BIND=<name>[<startidx>]:<bindinstance>.<bindname>[<startbind>,<bindnum>];X`
     > (where X is any number of "`<bindinstance>.<bindname>[<startbind>,<bindnum>]`" parts) is equal to the following two rules: `
     > 1. BIND=<name>[<startidx>]:<bindinstance>.<bindname>[<startbind>,<bindnum>]
     > 2. BIND=<name>[<startidx>+<bindnum>]:X
     > ` By performing this recursively we will get multiple
     > `BIND=<name>[<startidx>]:<bindinstance>.<bindname>[<startbind>,<bindnum>]`
     > rules.

     > Example:

     > > `BIND=DATA[15]:stack.port[23,4];filt.stack[13,10];cpp.compressed[1,5]`
     > > will be transferend into

     > > `BIND=DATA[15]:stack.port[23,4]
     > > BIND=DATA[19]:filt.stack[13,10]
     > > BIND=DATA[29]:ccp.compressed[1,5]`

     > > where 19 = 15 + 4 and 29 = 19 + 10.

   - Transform
     `BIND=<name>[<startidx>]:<bindinstance>.<bindname>[<startbind>,<bindnum>]`
     rule into multiple
     `BIND=<name>[<startidx>]:<bindinstance>.<bindname>[<startbind>]`
     rules:

     > `BIND=<name>[<startidx>]:<bindinstance>.<bindname>[<startbind>,<bindnum>]`
     > is equal to the following series of <bindnum> simplier rules:

     > 1 | `BIND=<name>[<startidx>]:<bindinstance>.<bindname>[<startbind>]`
     > 2 | `BIND=<name>[<startidx>+1]:<bindinstance>.<bindname>[<startbind>+1]`
     > ...
     > <bindnum>-1 | `BIND=<name>[<startidx>+<bindnum>-2]:<bindinstance>.<bindname>[<startbind>+<bindnum>-2]`
     > <bindnum> | `BIND=<name>[<startidx>+<bindnum>-1]:<bindinstance>.<bindname>[<startbind>+<bindnum>-1]`

     > Example:

     > > `BIND=DATA[15]:stack.port[23,4]`

     > will be transfered into

     > > `BIND=DATA[15]:stack.port[23]
     > > BIND=DATA[16]:stack.port[24]
     > > BIND=DATA[17]:stack.port[25]
     > > BIND=DATA[18]:stack.port[26]`

2. `BIND=<name>[<startidx>]:<bindinstance>.<bindname>[<startbind>]`
   rule in <instname> Plugin Instance makes connection between <startidx> stream of the <name> Stream Pack of the <instname> instance to <startbind> stream of the <bindname> Stream Pack of the <bindinstance> Instance.

## Postbinding

It is also possible to quickly insert a filter plugin into main plugin chain with INSERTBIND statement in the [plugman] section without having to rewrite two BINDs in corresponding plugins sections. But this statement doesn't allow to bind several streams by one line. Syntax:
`INSERTBIND=priority,insert_point_plugin.insert_point_plugpack[insert_point_idx]:bindinstance.bindname[bindidx],othername[otheridx]`
where:

- `priority` is a number which determines the sequence of INSERTBIND processing. Lines are processed in increasing of this number order. Lines with te same priority are processed in order of appearing in the config file;
- `insert_point_plugin.insert_point_plugpack[insert_point_idx]` - an existing plugin to connect. `[insert_point_idx]` is optional and defaults to 0;
- `bindinstance.bindname[bindidx]` - the inserting instance and its stream to connect to `insert_point_plugpack`. `[bindidx]` is optional and defaults to 0;
- `othername[otheridx]` - the second stream of the inserting instance. It is connected to the stream which was previously bound to `insert_point_plugpack`. `[otheridx]` is optional and defaults to 0;

## Loading

As you can see, there are two possible bind statements that makes connection from A to B:
`BIND=APACK[AIDX]:B.BPACK[BIDX]` in section A or
`BIND=BPACK[BIDX]:A.APACK[AIDX]` in section B.

This two statemets produces equal connection (A.APACK[AIDX]<->B.BPACK[BIDX]). The only thing that makes difference is Loading.

During loading of Instances not all Instances in the configuration file will be loaded. The algorithm of loading composed from the following steps:

1. Load Starting Instance as specified by UI module parameters (sfppp.exe default Starting Instance name is "PPP")
2. Load all Instances that are bound using binding statements from Starting Instance section.
3. Repeat loading Instances that are bound to already loaded Instances from its section.

Example:

> If we have the following configuration file (Only section names and binding statements provided):

> `[A]
> BIND=AOUT:B.BPACK
> [B]
> BIND=BOUT:C.CPACK1
> [C]
> [D]
> BIND=DOUT:C.CPACK2
> [E]
> BIND=EOUT:B.BPACK
> [F]
> BIND=FOUT1:D.DPACK
> BIND=FOUT2:A.APACK`

> We can load the following configurations:

> Starting Instance | Loaded Instances
> --- | ---
> A | A,B,C
> B | B,C
> C | C
> D | D,C
> E | E,B,C
> F | F,D,C,A,B

Note: It is not possible to bind two times to a single Connection Index. I.E. in the example above you can not load both A and E because this will produce duplicate connection to B.BPACK[0].

Return to documentation index | SafeFire PPP (C) Link Guard Solutions 1999, 2000