NAME - Application name lookup from port numbers


    # Use module
    use CAIDA::AppPorts;
    # Create a new AppPort object.
    my $app_port_obj = new CAIDA::AppPorts;
    # Clear the contents of the rules list
    # Load in a rule file.
    # Match some rule.
    my $match = $app_port_obj->match_rule($src_ip, $dst_ip, $ip_proto,
                                            $ports_ok, $sport, $dport);
    my $other = $app_port_obj->match_rule($ip_proto, $ports_ok, $sport, $dport);
    print $match->desc, "\n";
    foreach my $proto ($match->protocols) {
        print $proto, "\n";
    ... etc
    # Dump rules for debugging purposes.


AppPorts is a module that reads in a formatted text file of application rules, and then uses those rules to convert application port numbers and protocols to application names.

The module consists of methods to manage the rules and to search the rules for matching applications to the protocol, and source and destination ports. The rule format and module architecture is extensible so that this module can be used in a wide variety of settings.


NOTE: Prior to CoralReef 3.5.0, the file format was different. Most importantly, any strings with spaces requires double quotes around them, and the rule priority was implicit in their ordering. If you want to use an older rule file with the current module, you should strip out extra double quotes, and add some explicit priorities. With no priorities set, the chance of conflicting rule matching is increased greatly.

AppPorts expects a file with entries defining the characteristics of an application. The required fields are:

The full name of the application.

A unique name to identify the application. Must be able to be used as a UNIX filename.

The optional fields are:

A category for organizing applications, possibly in directory structures, or for aggregating similar applications, etc. Must be able to be used as a UNIX filename.

IP subnets to match (source and destination, respectively). Written in the form x.x.x.x/x; multiple subnets can be separated by commas. Defaults to matching all subnets (can also be defined explicitly with

0 or 1, indicates whether the data has valid ports or not. Matches exactly; for instance, if ports_ok == 0 and the data's ports are valid, the rule will NOT match. Defaults to 1.

The source and destination TCP/UDP/ICMP ports, respectively, to match. In the case of ICMP, 'sport' means 'type' and 'dport' means 'code'. Defined as a list of ports or port ranges, separated by commas. The special character * indicates all ports, and a port range is specified with a hyphen. For example:
        sport: 123, 200-300, 4567
        dport: *

If ports_ok == 1, both sport and dport must be defined, or the rule will never match.

0 or 1, indicates whether the source and destination ports and subnets are symmetric. Defaults to 0 (false).

The IP protocol number(s) to match. Multiple protocols are separated by commas. No ranges are currently supported, but * can be used to indicate all protocols.

Used for resolving two or more matching rules. 1 is highest priority; defaults to 50. If two or more matching rules with equal priority exist, only one will be returned. which one of the matching rules is returned is undefined.

Who added this rule.

When the rule was last updated.

Extra information.

Source of information for the rule.

URL with the most definitive source for the rule.

An example entry for the World Wide Web would be:

        description:    World Wide Web
        name:           WWW
        group:          WWW
        ports_ok:       1
        sport:          80,8080
        dport:          *
        sym:            1
        protocol:       6
        priority:       50
        contributor:    bigj
        date:           1999-07-08
        reference:      IANA Port assignments

Note that srcnet and dstnet can (and should) be omitted, since they default to matching all subnets. The notes and priority are similarly the same as the default.

If one wanted to override this rule with a domain specific application, such a rule might look like:

        description:    Our non-web app
        name:           APPFOO
        group:          INTERNAL
        sport:          8080
        dport:          *
        sym:            1
        protocol:       6
        priority:       10

It is possible to create a rule to match all cases, as a fall-through. It should have a low priority in order to be useful, however:

        description:    Unknown TCP
        name:           UNKNOWN_TCP
        sport:          *
        dport:          *
        protocol:       6
        priority:       90
        description:    Unknown
        name:           UNKNOWN
        sport:          *
        dport:          *
        protocol:       *
        priority:       100


new ()
Creates a new AppPorts object.

clear ()
Removes all entries from the AppPorts object. Good to do before re-loading a rules file.

load_rules (FILENAME)
Takes a path to a rules file and converts it into rules that can be applied to application port numbers.

Does the application matching for the flow data. If the source and destination IP addresses are omitted, no rules with subnets will match. If no match occurs, it returns undef, otherwise it returns a reference to an object with accessor members for each field:

Note that srcnet, dstnet, sport and dport are arrays of strings. The port ranges and wildcards are in the same form as the config file.

get_rule (NAME)
Returns the first rule that has the name NAME.

dump_rules ()
A debugging method that outputs the rules in the same format as the input file. Presently just dumps to standard out.


CAIDA::AppPorts from CoralReef < 3.5.0 had a different API. The primary differences are:

Removed functions

Changed return type

match_rule now returns an opaque object, whereas match_first_rule would return an array reference. To access the fields of a rule, we now use accessor functions instead of reading the array directly. For example, the old way was:

        $match = $obj->match_first_rule($sport, $dport, $proto);
        $name = $match->[NAME];

The current way is:

        $match = $obj->match_rule($proto, $ok, $sport, $dport);
        $name = $match->name;


CoralReef Development team, CAIDA <>