AppPorts.pm - 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 $app_port_obj->clear();
# Load in a rule file. $app_port_obj->load_rules($rules_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. $app_port_obj->dump_rules();
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 optional fields are:
sport: 123, 200-300, 4567 dport: *
If ports_ok == 1, both sport and dport must be defined, or the rule will never match.
number(s)
to match. Multiple protocols are separated by
commas. No ranges are currently supported, but * can be used to
indicate all protocols.
An example entry for the World Wide Web would be:
description: World Wide Web name: WWW group: WWW srcnet: 0.0.0.0/0 dstnet: 0.0.0.0/0 ports_ok: 1 sport: 80,8080 dport: * sym: 1 protocol: 6 priority: 50 contributor: bigj date: 1999-07-08 notes: reference: IANA Port assignments url: http://www.iana.org/assignments/port-numbers
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 srcnet: 10.0.0.0/8 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
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.
CAIDA::AppPorts from CoralReef < 3.5.0 had a different API. The primary differences are:
match_rule
. Note: The order of the arguments are different.
get_rule
, except that the entire rule is
returned and not just the description.
clear
.
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 <coral-info@caida.org>