diff options
author | jim-p <jimp@pfsense.org> | 2017-02-28 12:35:08 -0500 |
---|---|---|
committer | jim-p <jimp@pfsense.org> | 2017-02-28 12:35:08 -0500 |
commit | 6aa85955fc074d9d35de782c32f7363391b945df (patch) | |
tree | 0cbeaacb6ce8fe15d05a02c52dadd5f8f31cdfeb /src/usr/local/www/diag_packet_capture.php | |
parent | 9eb0a09cec2a03e803fe9e8f9435267bd051569c (diff) | |
download | pfsense-6aa85955fc074d9d35de782c32f7363391b945df.zip pfsense-6aa85955fc074d9d35de782c32f7363391b945df.tar.gz |
Finish MAC address matching for packet capture. Implements #6743
Diffstat (limited to 'src/usr/local/www/diag_packet_capture.php')
-rwxr-xr-x | src/usr/local/www/diag_packet_capture.php | 35 |
1 files changed, 32 insertions, 3 deletions
diff --git a/src/usr/local/www/diag_packet_capture.php b/src/usr/local/www/diag_packet_capture.php index 010f6d6..f0868ab 100755 --- a/src/usr/local/www/diag_packet_capture.php +++ b/src/usr/local/www/diag_packet_capture.php @@ -72,8 +72,28 @@ function fixup_host($value, $position) { return "{$andor}host {$not}" . $host; } elseif (is_subnet($host)) { return "{$andor}net {$not}" . $host; - } elseif (is_macaddr($host)) { + } elseif (is_macaddr($host, false)) { return "{$andor}ether host {$not}" . $host; + } elseif (is_macaddr($host, true)) { + /* Try to match a partial MAC address. tcpdump only allows + * matching 1, 2, or 4 byte chunks so enforce that limit + */ + $searchmac = "0x"; + $partcount = 0; + /* is_macaddr will fail a partial match that has empty sections + * but sections may only have one digit (leading 0) so add a + * left 0 pad. + */ + foreach (explode(':', $host) as $mp) { + $searchmac .= str_pad($mp, 2, "0", STR_PAD_LEFT); + $partcount++; + } + if (!in_array($partcount, array(1, 2, 4))) { + return ""; + } + $eq = has_not($value) ? "!=" : "=="; + // ether[0:2] == 0x0090 or ether[6:2] == 0x0090 + return "{$andor} ( ether[0:{$partcount}] {$eq} {$searchmac} or ether[6:{$partcount}] {$eq} {$searchmac} )"; } else { return ""; } @@ -159,9 +179,17 @@ if ($_POST) { } foreach ($hosts as $h) { - if (!is_subnet(strip_host_logic($h)) && !is_ipaddr(strip_host_logic($h)) && !is_macaddr(strip_host_logic($h))) { + $h = strip_host_logic($h); + if (!is_subnet($h) && !is_ipaddr($h) && !is_macaddr($h, true)) { $input_errors[] = sprintf(gettext("A valid IP address, CIDR block, or MAC address must be specified. [%s]"), $h); } + /* Check length of partial MAC */ + if (!is_macaddr($h, false) && is_macaddr($h, true)) { + $mac_parts = explode(':', $h); + if (!in_array(count($mac_parts), array(1, 2, 4))) { + $input_errors[] = gettext("Partial MAC addresses can only be matched using 1, 2, or 4 MAC segments (bytes)."); + } + } } } @@ -316,9 +344,10 @@ $section->addInput(new Form_Input( 'Host Address', 'text', $host -))->setHelp('This value is either the Source or Destination IP address or subnet in CIDR notation. The packet capture will look for this address in either field.%1$s' . +))->setHelp('This value is either the Source or Destination IP address, subnet in CIDR notation, or MAC address.%1$s' . 'Matching can be negated by preceding the value with "!". Multiple IP addresses or CIDR subnets may be specified. Comma (",") separated values perform a boolean "AND". ' . 'Separating with a pipe ("|") performs a boolean "OR".%1$s' . + 'MAC addresses must be entered in colon-separated format, such as xx:xx:xx:xx:xx:xx or a partial address consisting of one (xx), two (xx:xx), or four (xx:xx:xx:xx) segments.%1$s' . 'If this field is left blank, all packets on the specified interface will be captured.', '<br />'); |