wireshark/tools/checkfiltername.pl

789 lines
27 KiB
Perl
Raw Normal View History

#!/usr/bin/perl
my $debug = 0;
# 0: off
# 1: specific debug
# 2: full debug
#
# verify that display filter names correspond with the PROTABBREV of
# of the dissector. Enforces the dissector to have a source
# filename of format packet-PROTABBREV.c
#
# Usage: checkfiltername.pl <file or files>
#
# Copyright 2011 Michael Mann (see AUTHORS file)
#
# Wireshark - Network traffic analyzer
# By Gerald Combs <gerald@wireshark.org>
# Copyright 1998 Gerald Combs
#
# SPDX-License-Identifier: GPL-2.0-or-later
#
# Example:
# ~/work/wireshark/trunk/epan/dissectors> ../../tools/checkfiltername.pl packet-3com-xns.c
# packet-3com-xns.c (2 (of 2) fields)
# 102 3comxns.type doesn't match PROTOABBREV of 3com-xns
# 106 3comxns.type doesn't match PROTOABBREV of 3com-xns
#
# or checkfiltername.pl packet-*.c, which will check all the dissector files.
#
#
use warnings;
use strict;
use Getopt::Long;
my @elements;
my @elements_dup;
my @protocols;
my %filters;
my %expert_filters;
my @acceptedprefixes = ("dcerpc-");
my @asn1automatedfilelist;
my @dcerpcautomatedfilelist;
my @idl2wrsautomatedfilelist;
my @filemanipulationfilelist;
my @prefixfilelist;
my @nofieldfilelist;
my %unique;
my @uniquefilelist;
my @noregprotocolfilelist;
my @periodinfilternamefilelist;
my $showlinenoFlag = '';
my $showautomatedFlag = '';
my $state = "";
# "s_unknown",
# "s_start",
# "s_in_hf_register_info",
# "s_hf_register_info_entry",
# "s_header_field_info_entry",
# "s_header_field_info_entry_start",
# "s_header_field_info_entry_name",
# "s_header_field_info_entry_abbrev",
# "s_header_field_info_entry_abbrev_end",
# "s_start_expert",
# "s_in_ei_register_info",
# "s_ei_register_info_entry",
# "s_ei_register_info_entry_start",
# "s_ei_register_info_entry_abbrev_end",
# "s_nofields"
my $restofline;
my $filecount = 0;
my $currfile = "";
my $protabbrev = "";
my $protabbrev_index;
my $PFNAME_value = "";
my $linenumber = 1;
my $totalerrorcount = 0;
my $errorfilecount = 0;
my $onefield = 0;
my $nofields = 0;
my $noperiod = 0;
my $noregprotocol = 1;
my $automated = 0;
my $more_tokens;
my $showall = 0;
my $comment = 0;
sub checkprotoabbrev {
my $abbrev = "";
my $abbrevpos;
my $proto_abbrevpos1;
my $proto_abbrevpos2;
my $afterabbrev = "";
my $check_dup_abbrev = "";
my $modprotabbrev = "";
my $errorline = 0;
my $prefix;
if (($automated == 0) || ($showall == 1)) {
$abbrevpos = index($_[0], ".");
if ($abbrevpos == -1) {
$abbrev = $_[0];
}
else {
$abbrev = substr($_[0], 0, $abbrevpos);
$afterabbrev = substr($_[0], $abbrevpos+1, length($_[0])-$abbrevpos);
$check_dup_abbrev = $afterabbrev;
$afterabbrev = substr($afterabbrev, 0, length($abbrev));
}
if ($abbrev ne $protabbrev) {
$errorline = 1;
#check if there is a supported protocol that matches the abbrev.
#This may be a case of filename != PROTOABBREV
foreach (@protocols) {
if ($abbrev eq $_) {
$errorline = 0;
} elsif (index($_, ".") != -1) {
#compare from start of string for each period found
$proto_abbrevpos1 = 0;
while ((($proto_abbrevpos2 = index($_, ".", $proto_abbrevpos1)) != -1) &&
($errorline == 1)) {
if ($abbrev eq substr($_, 0, $proto_abbrevpos2)) {
$errorline = 0;
}
$proto_abbrevpos1 = $proto_abbrevpos2+1;
}
}
}
}
# find any underscores that preface or follow a period
if (((index($_[0], "._") >= 0) || (index($_[0], "_.") >= 0)) &&
#ASN.1 dissectors can intentionally generating this field name, so don't fault the dissector
(index($_[0], "_untag_item_element") < 0)) {
if ($showlinenoFlag) {
push(@elements, "$_[1] $_[0] contains an unnecessary \'_\'\n");
} else {
push(@elements, "$_[0] contains an unnecessary \'_\'\n");
}
}
if (($errorline == 1) && ($showall == 0)) {
#try some "accepted" variations of PROTOABBREV
#replace '-' with '_'
$modprotabbrev = $protabbrev;
$modprotabbrev =~ s/-/_/g;
if ($abbrev eq $modprotabbrev) {
$errorline = 0;
}
#remove '-'
if ($errorline == 1) {
$modprotabbrev = $protabbrev;
$modprotabbrev =~ s/-//g;
if ($abbrev eq $modprotabbrev) {
$errorline = 0;
}
}
#remove '_'
if ($errorline == 1) {
$modprotabbrev = $protabbrev;
$modprotabbrev =~ s/_//g;
if ($abbrev eq $modprotabbrev) {
$errorline = 0;
}
}
if ($errorline == 1) {
#remove any "accepted" prefix to see if there is still a problem
foreach (@acceptedprefixes) {
if ($protabbrev =~ /^$_/) {
$modprotabbrev = substr($protabbrev, length($_));
if ($abbrev eq $modprotabbrev) {
push(@prefixfilelist, "$currfile\n");
$errorline = 0;
}
}
}
}
else {
push(@filemanipulationfilelist, "$currfile\n");
}
#now check the acceptable "fields from a different protocol"
if ($errorline == 1) {
if (is_from_other_protocol_allowed($_[0], $currfile) == 1) {
$errorline = 0;
}
}
#now check the acceptable "fields that include a version number"
if ($errorline == 1) {
if (is_protocol_version_allowed($_[0], $currfile) == 1) {
$errorline = 0;
}
}
}
if ($errorline == 1) {
$debug>1 && print "$_[1] $_[0] doesn't match PROTOABBREV of $protabbrev\n";
if ($showlinenoFlag) {
push(@elements, "$_[1] $_[0] doesn't match PROTOABBREV of $protabbrev\n");
} else {
push(@elements, "$_[0] doesn't match PROTOABBREV of $protabbrev\n");
}
}
if (($abbrev ne "") && (lc($abbrev) eq lc($afterabbrev))) {
# Allow ASN.1 generated files to duplicate part of proto name
if ((!(grep {$currfile eq $_ } @asn1automatedfilelist)) &&
# Check allowed list
(is_proto_dup_allowed($abbrev, $check_dup_abbrev) == 0)) {
if ($showlinenoFlag) {
push(@elements_dup, "$_[1] $_[0] duplicates PROTOABBREV of $abbrev\n");
} else {
push(@elements_dup, "$_[0] duplicates PROTOABBREV of $abbrev\n");
}
}
}
}
}
sub printprevfile {
my $totalfields = keys(%filters);
my $count_ele;
my $count_dup;
my $total_count;
foreach (sort keys %filters) {
checkprotoabbrev ($filters{$_}, $_);
}
foreach (sort keys %expert_filters) {
checkprotoabbrev ($expert_filters{$_}, $_);
}
$count_ele = @elements;
$count_dup = @elements_dup;
$total_count = $count_ele+$count_dup;
if ($noregprotocol == 1) {
#if no protocol is registered, only worry about duplicates
if ($currfile ne "") {
push(@noregprotocolfilelist, "$currfile\n");
}
if ($count_dup > 0) {
$errorfilecount++;
$totalerrorcount += $count_dup;
}
if (($showall == 1) || ($count_dup > 0)) {
print "\n\n$currfile - NO PROTOCOL REGISTERED\n";
if ($showall == 1) {
#everything is included, so count all errors
$totalerrorcount += $count_ele;
if (($count_ele > 0) && ($count_dup == 0)) {
$errorfilecount++;
}
foreach (@elements) {
print $_;
}
}
foreach (@elements_dup) {
print $_;
}
}
} else {
if ($total_count > 0) {
$errorfilecount++;
$totalerrorcount += $total_count;
}
if (($automated == 0) || ($showall == 1)) {
if ($total_count > 0) {
if ($automated == 1) {
if ($showall == 1) {
print "\n\n$currfile - AUTOMATED ($total_count (of $totalfields) fields)\n";
}
} else {
print "\n\n$currfile ($total_count (of $totalfields) fields)\n";
}
foreach (@elements) {
print $_;
}
foreach (@elements_dup) {
print $_;
}
}
if ((($nofields) || ($totalfields == 0)) && ($currfile ne "")) {
if ($showall == 1) {
print "\n\n$currfile - NO FIELDS\n";
}
push(@nofieldfilelist, "$currfile\n");
}
}
}
}
#--------------------------------------------------------------------
# This is a list of dissectors that intentionally have filter names
# where the second segment duplicates (at least partially) the name
# of the first. The most common case is in ASN.1 dissectors, but
# those can be dealt with by looking at the first few lines of the
# dissector. This list has been vetted and justification will need
# to be provided to add to it. Acknowledge these dissectors aren't
# a problem for the pre-commit script
#--------------------------------------------------------------------
sub is_proto_dup_allowed {
if (($_[0] eq "amf") && (index($_[1], "amf0") >= 0)) {return 1;}
if (($_[0] eq "amf") && (index($_[1], "amf3") >= 0)) {return 1;}
if (($_[0] eq "amqp") && (index($_[1], "amqp") >= 0)) {return 1;}
if (($_[0] eq "bat") && (index($_[1], "batman") >= 0)) {return 1;}
if (($_[0] eq "browser") && (index($_[1], "browser_") >= 0)) {return 1;}
if (($_[0] eq "data") && (index($_[1], "data") >= 0)) {return 1;}
if (($_[0] eq "dlsw") && (index($_[1], "dlsw_version") >= 0)) {return 1;}
if (($_[0] eq "dns") && (index($_[1], "dnskey") >= 0)) {return 1;}
if (($_[0] eq "ecmp") && (index($_[1], "ecmp_") >= 0)) {return 1;}
if (($_[0] eq "exported_pdu") && (index($_[1], "exported_pdu") >= 0)) {return 1;}
if (($_[0] eq "fc") && (index($_[1], "fctl") >= 0)) {return 1;}
if (($_[0] eq "fcs") && (index($_[1], "fcsmask") >= 0)) {return 1;}
if (($_[0] eq "fmp") && (index($_[1], "fmp") >= 0)) {return 1;}
if (($_[0] eq "fr") && (index($_[1], "frame_relay") >= 0)) {return 1;}
if (($_[0] eq "lustre") && (index($_[1], "lustre_") >= 0)) {return 1;}
if (($_[0] eq "mac") && (index($_[1], "macd") >= 0)) {return 1;}
if (($_[0] eq "mac") && (index($_[1], "macis") >= 0)) {return 1;}
if (($_[0] eq "mih") && (index($_[1], "mihf") >= 0)) {return 1;}
if (($_[0] eq "mih") && (index($_[1], "mihcap") >= 0)) {return 1;}
if (($_[0] eq "ncp") && (index($_[1], "ncp") >= 0)) {return 1;}
if (($_[0] eq "nfs") && (index($_[1], "nfs") >= 0)) {return 1;}
if (($_[0] eq "oxid") && (index($_[1], "oxid") >= 0)) {return 1;}
if (($_[0] eq "rquota") && (index($_[1], "rquota") >= 0)) {return 1;}
if (($_[0] eq "pfcp") && (index($_[1], "pfcp") >= 0)) {return 1;}
if (($_[0] eq "sm") && (index($_[1], "sm_") >= 0)) {return 1;}
if (($_[0] eq "smpp") && (index($_[1], "smppplus") >= 0)) {return 1;}
if (($_[0] eq "spray") && (index($_[1], "sprayarr") >= 0)) {return 1;}
if (($_[0] eq "tds") && (index($_[1], "tds_") >= 0)) {return 1;}
if (($_[0] eq "time") && (index($_[1], "time") >= 0)) {return 1;}
if (($_[0] eq "tn3270") && (index($_[1], "tn3270e") >= 0)) {return 1;}
if (($_[0] eq "usb") && (index($_[1], "usb") >= 0)) {return 1;}
if (($_[0] eq "xml") && (index($_[1], "xml") >= 0)) {return 1;}
return 0;
}
#--------------------------------------------------------------------
# This is a list of dissectors that intentionally have filter names
# shared with other dissectors. This list has been vetted and
# justification will need to be provided to add to it.
# Acknowledge these dissectors aren't a problem for the pre-commit script
#--------------------------------------------------------------------
sub is_from_other_protocol_allowed {
my $proto_filename;
my $dir_index = rindex($_[1], "\\");
#handle directory names on all platforms
if ($dir_index < 0) {
$dir_index = rindex($_[1], "/");
}
if ($dir_index < 0) {
$proto_filename = $_[1];
}
else {
$proto_filename = substr($_[1], $dir_index+1);
}
# XXX - may be faster to hash this (note 1-many relationship)?
if (($proto_filename eq "packet-atalk.c") && (index($_[0], "llc") >= 0)) {return 1;}
if (($proto_filename eq "packet-awdl.c") && (index($_[0], "llc") >= 0)) {return 1;}
if (($proto_filename eq "packet-bpdu.c") && (index($_[0], "mstp") >= 0)) {return 1;}
if (($proto_filename eq "packet-bssap.c") && (index($_[0], "bsap") >= 0)) {return 1;}
if (($proto_filename eq "packet-caneth.c") && (index($_[0], "can") >= 0)) {return 1;}
if (($proto_filename eq "packet-cimetrics.c") && (index($_[0], "llc") >= 0)) {return 1;}
if (($proto_filename eq "packet-cipsafety.c") && (index($_[0], "cip") >= 0)) {return 1;}
if (($proto_filename eq "packet-cipsafety.c") && (index($_[0], "enip") >= 0)) {return 1;}
if (($proto_filename eq "packet-dcerpc-netlogon.c") && (index($_[0], "ntlmssp") >= 0)) {return 1;}
if (($proto_filename eq "packet-dcom-oxid.c") && (index($_[0], "dcom") >= 0)) {return 1;}
if (($proto_filename eq "packet-dvb-data-mpe.c") && (index($_[0], "mpeg_sect") >= 0)) {return 1;}
if (($proto_filename eq "packet-dvb-ipdc.c") && (index($_[0], "ipdc") >= 0)) {return 1;}
if (($proto_filename eq "packet-enip.c") && (index($_[0], "cip") >= 0)) {return 1;}
if (($proto_filename eq "packet-extreme.c") && (index($_[0], "llc") >= 0)) {return 1;}
if (($proto_filename eq "packet-fmp_notify.c") && (index($_[0], "fmp") >= 0)) {return 1;}
if (($proto_filename eq "packet-foundry.c") && (index($_[0], "llc") >= 0)) {return 1;}
if (($proto_filename eq "packet-glusterfs.c") && (index($_[0], "gluster") >= 0)) {return 1;}
if (($proto_filename eq "packet-h248_annex_e.c") && (index($_[0], "h248") >= 0)) {return 1;}
if (($proto_filename eq "packet-h248_q1950.c") && (index($_[0], "h248") >= 0)) {return 1;}
if (($proto_filename eq "packet-ieee1722.c") && (index($_[0], "can") >= 0)) {return 1;}
if (($proto_filename eq "packet-ieee80211.c") && (index($_[0], "eapol") >= 0)) {return 1;}
if (($proto_filename eq "packet-ieee80211-radio.c") && (index($_[0], "wlan") >= 0)) {return 1;}
if (($proto_filename eq "packet-ieee80211-wlancap.c") && (index($_[0], "wlan") >= 0)) {return 1;}
if (($proto_filename eq "packet-ieee802154.c") && (index($_[0], "wpan") >= 0)) {return 1;}
if (($proto_filename eq "packet-isup.c") && (index($_[0], "ansi_isup") >= 0)) {return 1;}
if (($proto_filename eq "packet-isup.c") && (index($_[0], "bat_ase") >= 0)) {return 1;}
if (($proto_filename eq "packet-isup.c") && (index($_[0], "nsap") >= 0)) {return 1;}
if (($proto_filename eq "packet-isup.c") && (index($_[0], "x213") >= 0)) {return 1;}
if (($proto_filename eq "packet-iwarp-ddp-rdmap.c") && (index($_[0], "iwarp_ddp") >= 0)) {return 1;}
if (($proto_filename eq "packet-iwarp-ddp-rdmap.c") && (index($_[0], "iwarp_rdma") >= 0)) {return 1;}
if (($proto_filename eq "packet-k12.c") && (index($_[0], "aal2") >= 0)) {return 1;}
if (($proto_filename eq "packet-k12.c") && (index($_[0], "atm") >= 0)) {return 1;}
if (($proto_filename eq "packet-m3ua.c") && (index($_[0], "mtp3") >= 0)) {return 1;}
if (($proto_filename eq "packet-mle.c") && (index($_[0], "wpan") >= 0)) {return 1;}
if (($proto_filename eq "packet-mpeg-dsmcc.c") && (index($_[0], "mpeg_sect") >= 0)) {return 1;}
if (($proto_filename eq "packet-mpeg-dsmcc.c") && (index($_[0], "etv.dsmcc") >= 0)) {return 1;}
if (($proto_filename eq "packet-mpeg1.c") && (index($_[0], "rtp.payload_mpeg_") >= 0)) {return 1;}
if (($proto_filename eq "packet-mysql.c") && (index($_[0], "mariadb") >= 0)) {return 1;}
if (($proto_filename eq "packet-ndps.c") && (index($_[0], "spx.ndps_") >= 0)) {return 1;}
if (($proto_filename eq "packet-pw-atm.c") && (index($_[0], "atm") >= 0)) {return 1;}
if (($proto_filename eq "packet-pw-atm.c") && (index($_[0], "pw") >= 0)) {return 1;}
if (($proto_filename eq "packet-scsi.c") && (index($_[0], "scsi_sbc") >= 0)) {return 1;}
if (($proto_filename eq "packet-sndcp-xid.c") && (index($_[0], "llcgprs") >= 0)) {return 1;}
if (($proto_filename eq "packet-wlccp.c") && (index($_[0], "llc") >= 0)) {return 1;}
if (($proto_filename eq "packet-wps.c") && (index($_[0], "eap") >= 0)) {return 1;}
if (($proto_filename eq "packet-wsp.c") && (index($_[0], "wap") >= 0)) {return 1;}
if (($proto_filename eq "packet-xot.c") && (index($_[0], "x25") >= 0)) {return 1;}
Fixed bug in ZigBee (zbee) decryption, added Key Establishment cluster and moved IAS, Thermostat and Poll clusters out of the ZCL foundation dissector. Removed attrID and cmdID ZCL cluster functions. Bug in ZCL HVAC attribute registration. Fixed bug in ZCL command ID field registration. Update Manufacturer Codes and Profile Ids to ZigBee-053874r26 Oct 2014 Fixed broken fragmented ZigBee packet collection and reassembly Use protocol fields for Thermostat schedule transitions. Added support for Key Establishment Cluster (CBKE) at SE 1.2a Updated Message cluster to SE 1.2a spec Added attribute reporting status which is common to all SE 1.2a clusters Added SE 1.2a tunnel cluster support ZigBee Smart Energy (SE) decryption appears to have been broken for some time. For SE you do not know the Link Key until after successful completion of Key Establishment and then manually enter it into preferences. Entry in preferences was broken such that when the new Link Key was entered all existing link keys would be lost. This lead to the loss of the Network Key as well when the Transport Key message was re-processed without the Pre-Configured Link Key. The Link Key 'key ring' has been moved to the UAT post-update callback so that it will always be updated correctly after changes to the link keys in preferences The attribute reporting status attribute which is common to all SE clusters was accidentally shared, now each cluster has it's own instance ZigBee security added key display for decrypted packets ZigBee Security Preferences fixed UAT type for Label so key label is editable again Added definition for Retail Service profile Added dissection for profile-wide (General Command Frame) commands when the profile is unknown Added zbee-zcl-misc.c to precommit check whitelist as it contains ias and hvac clusters avoiding proliferation of too many small files Change-Id: I53d85ba9d782db6a0e7e78c51b0bc7cdcdbca3ad Reviewed-on: https://code.wireshark.org/review/5565 Petri-Dish: Alexis La Goutte <alexis.lagoutte@gmail.com> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Anders Broman <a.broman58@gmail.com>
2014-11-07 22:11:02 +00:00
if (($proto_filename eq "packet-zbee-zcl-misc.c") && (index($_[0], "zbee_zcl_hvac") >= 0)) {return 1;}
if (($proto_filename eq "packet-zbee-zcl-misc.c") && (index($_[0], "zbee_zcl_ias") >= 0)) {return 1;}
#Understand why, but I think it could be prefixed with "dissector"
#prefix (which isn't necessarily "protocol")
if (($proto_filename eq "packet-rtcp.c") && (index($_[0], "srtcp") >= 0)) {return 1;}
if (($proto_filename eq "packet-rtp.c") && (index($_[0], "srtp") >= 0)) {return 1;}
if (($proto_filename eq "packet-dcom-cba-acco.c") && (index($_[0], "cba") >= 0)) {return 1;}
if (($proto_filename eq "packet-dcom-cba.c") && (index($_[0], "cba") >= 0)) {return 1;}
#XXX - HACK to get around nested "s in field name
if (($proto_filename eq "packet-gsm_sim.c") && (index($_[0], "e\\") >= 0)) {return 1;}
return 0;
}
#--------------------------------------------------------------------
# This is a list of dissectors that use their (protocol) version number
# as part of the first display filter segment, which checkfiltername
# usually complains about. Manually allow them so that they can pass
# pre-commit script
#--------------------------------------------------------------------
sub is_protocol_version_allowed {
my $proto_filename;
my $dir_index = rindex($_[1], "\\");
#handle directory names on all platforms
if ($dir_index < 0) {
$dir_index = rindex($_[1], "/");
}
if ($dir_index < 0) {
$proto_filename = $_[1];
}
else {
$proto_filename = substr($_[1], $dir_index+1);
}
# XXX - may be faster to hash this?
if (($proto_filename eq "packet-ehs.c") && (index($_[0], "ehs2") >= 0)) {return 1;}
if (($proto_filename eq "packet-hsrp.c") && (index($_[0], "hsrp2") >= 0)) {return 1;}
if (($proto_filename eq "packet-ipv6.c") && (index($_[0], "ip") >= 0)) {return 1;}
if (($proto_filename eq "packet-openflow_v1.c") && (index($_[0], "openflow") >= 0)) {return 1;}
if (($proto_filename eq "packet-rtnet.c") && (index($_[0], "tdma-v1") >= 0)) {return 1;}
if (($proto_filename eq "packet-scsi-osd.c") && (index($_[0], "scsi_osd2") >= 0)) {return 1;}
if (($proto_filename eq "packet-sflow.c") && (index($_[0], "sflow_5") >= 0)) {return 1;}
if (($proto_filename eq "packet-sflow.c") && (index($_[0], "sflow_245") >= 0)) {return 1;}
if (($proto_filename eq "packet-tipc.c") && (index($_[0], "tipcv2") >= 0)) {return 1;}
if (($proto_filename eq "packet-bluetooth.c") && (index($_[0], "llc.bluetooth_pid") >= 0)) {return 1;}
return 0;
}
# ---------------------------------------------------------------------
#
# MAIN
#
GetOptions(
'showlineno' => \$showlinenoFlag,
'showautomated' => \$showautomatedFlag,
);
while (<>) {
if ($currfile !~ /$ARGV/) {
&printprevfile();
# New file - reset array and state
$filecount++;
$currfile = $ARGV;
#determine PROTABBREV for dissector based on file name format of (dirs)/packet-PROTABBREV.c or (dirs)/file-PROTABBREV.c
$protabbrev_index = rindex($currfile, "packet-");
if ($protabbrev_index == -1) {
$protabbrev_index = rindex($currfile, "file-");
if ($protabbrev_index == -1) {
#ignore "non-dissector" files
next;
}
$protabbrev = substr($currfile, $protabbrev_index+length("file-"));
$protabbrev_index = rindex($protabbrev, ".");
if ($protabbrev_index == -1) {
print "$currfile doesn't fit format of file-PROTABBREV.c\n";
next;
}
} else {
$protabbrev = substr($currfile, $protabbrev_index+length("packet-"));
$protabbrev_index = rindex($protabbrev, ".");
if ($protabbrev_index == -1) {
print "$currfile doesn't fit format of packet-PROTABBREV.c\n";
next;
}
}
$protabbrev = substr($protabbrev, 0, $protabbrev_index);
$PFNAME_value = "";
$noregprotocol = 1;
$automated = 0;
$nofields = 0;
$onefield = 0;
$noperiod = 0;
$linenumber = 1;
%filters = ( );
%expert_filters = ( );
@protocols = ( );
@elements = ( );
@elements_dup = ( );
$state = "s_unknown";
}
if (($automated == 0) && ($showautomatedFlag eq "")) {
#DCERPC automated files
if ($_ =~ "DO NOT EDIT") {
push(@dcerpcautomatedfilelist, "$currfile\n");
$automated = 1;
next;
}
#ASN.1 automated files
elsif ($_ =~ "Generated automatically by the ASN.1 to Wireshark dissector compiler") {
push(@asn1automatedfilelist, "$currfile\n");
$automated = 1;
next;
}
#idl2wrs automated files
elsif ($_ =~ "Autogenerated from idl2wrs") {
push(@idl2wrsautomatedfilelist, "$currfile\n");
$automated = 1;
next;
}
}
# opening then closing comment
if (/(.*?)\/\*.*\*\/(.*)/) {
$comment = 0;
$_ = "$1$2";
# closing then opening comment
} elsif (/.*?\*\/(.*?)\/\*/) {
$comment = 1;
$_ = "$1";
# opening comment
} elsif (/(.*?)\/\*/) {
$comment = 1;
$_ = "$1";
# closing comment
} elsif (/\*\/(.*?)/) {
$comment = 0;
$_ = "$1";
} elsif ($comment == 1) {
$linenumber++;
next;
}
# unhandled: more than one complete comment per line
chomp;
#proto_register_protocol state machine
$restofline = $_;
$more_tokens = 1;
#PFNAME is a popular #define for the proto filter name, so use it for testing
if ($restofline =~ /#define\s*PFNAME\s*\"([^\"]*)\"/) {
$PFNAME_value = $1;
$debug>1 && print "PFNAME: '$1'\n";
}
until ($more_tokens == 0) {
if (($restofline =~ /proto_register_protocol\s*\((.*)/) ||
($restofline =~ /proto_register_protocol_in_name_only\s*\((.*)/)) {
$noregprotocol = 0;
$restofline = $1;
$state = "s_proto_start";
} elsif (($state eq "s_proto_start") && ($restofline =~ /^(\s*\"([^\"]*)\"\s*,)\s*(.*)/)) {
$restofline = $3;
$state = "s_proto_long_name";
$debug>1 && print "proto long name: '$2'\n";
} elsif (($state eq "s_proto_start") && ($restofline =~ /^(\s*(([\w\d])+)\s*,)\s*(.*)/)) {
$restofline = $4;
$state = "s_proto_long_name";
$debug>1 && print "proto long name: '$2'\n";
} elsif (($state eq "s_proto_long_name") && ($restofline =~ /^(\s*\"([^\"]*)\"\s*,)\s*(.*)/)) {
$restofline = $3;
$state = "s_proto_short_name";
$debug>1 && print "proto short name: '$2'\n";
} elsif (($state eq "s_proto_long_name") && ($restofline =~ /^(\s*(([\w\d])+)\s*,)\s*(.*)/)) {
$restofline = $4;
$state = "s_proto_short_name";
$debug>1 && print "proto short name: '$2'\n";
} elsif (($state eq "s_proto_short_name") && ($restofline =~ /\s*PFNAME\s*(.*)/)) {
$more_tokens = 0;
$state = "s_proto_filter_name";
if ((index($PFNAME_value, ".") != -1) && ($noperiod == 0)) {
push(@periodinfilternamefilelist, "$currfile\n");
$noperiod = 1;
}
push(@protocols, $PFNAME_value);
$debug>1 && print "proto filter name: '$PFNAME_value'\n";
} elsif (($state eq "s_proto_short_name") && ($restofline =~ /\s*\"([^\"]*)\"\s*(.*)/)) {
$more_tokens = 0;
$state = "s_proto_filter_name";
if ((index($1, ".") != -1) && ($noperiod == 0)) {
push(@periodinfilternamefilelist, "$currfile\n");
$noperiod = 1;
}
push(@protocols, $1);
$debug>1 && print "proto filter name: '$1'\n";
} elsif (($state eq "s_proto_short_name") && ($restofline =~ /\s*(([\w\d])+)\s*(.*)/)) {
$more_tokens = 0;
$state = "s_proto_filter_name";
$debug>1 && print "proto filter name: '$1'\n";
} else {
$more_tokens = 0;
}
}
#retrieving display filters state machine
$restofline = $_;
$more_tokens = 1;
until ($more_tokens == 0) {
if ($restofline =~ /\s*static\s*hf_register_info\s*(\w+)\[\](.*)/) {
$restofline = $2;
$state = "s_start";
$debug>1 && print "$linenumber $state\n";
} elsif ($restofline =~ /\s*static\s*ei_register_info\s*(\w+)\[\](.*)/) {
$restofline = $2;
$state = "s_start_expert";
$debug>1 && print "$linenumber $state\n";
} elsif (($state eq "s_start") && ($restofline =~ /\W+{(.*)/)) {
$restofline = $1;
$state = "s_in_hf_register_info";
$debug>1 && print "$linenumber $state\n";
} elsif (($state eq "s_in_hf_register_info") && ($restofline =~ /\W+{(.*)/)) {
$restofline = $1;
$state = "s_hf_register_info_entry";
$debug>1 && print "$linenumber $state\n";
$onefield = 1;
} elsif (($state eq "s_in_hf_register_info") && ($restofline =~ /\s*};(.*)/)) {
$restofline = $1;
if ($onefield == 0) {
$debug && print "$linenumber NO FIELDS!!!\n";
$nofields = 1;
$state = "s_nofields";
$more_tokens = 0;
} else {
$state = "s_unknown";
}
} elsif (($state eq "s_hf_register_info_entry") && ($restofline =~ /\s*&\s*(hf_\w*(\[w*\])?)\s*,?(.*)/)) {
$restofline = $3;
$debug>1 && print "$linenumber hf_register_info_entry: $1\n";
$state = "s_header_field_info_entry";
} elsif (($state eq "s_header_field_info_entry") && ($restofline =~ /\s*{(.*)/)) {
$restofline = $1;
$state = "s_header_field_info_entry_start";
$debug>1 && print "$linenumber $state\n";
} elsif (($state eq "s_header_field_info_entry_start") && ($restofline =~ /((\"([^\"]*)\")|(\w+))\s*,(.*)/)) {
$restofline = $5;
$debug>1 && print "$linenumber header_field_info_entry_name: $1\n";
$state = "s_header_field_info_entry_name";
} elsif (($state eq "s_header_field_info_entry_name") && ($restofline =~ /\"([^\"]*)\"\s*,?(.*)/)) {
$restofline = $2;
$debug>1 && print "$linenumber header_field_info_entry_abbrev: $1\n";
$state = "s_header_field_info_entry_abbrev";
$filters{$linenumber} = $1;
} elsif (($state eq "s_header_field_info_entry_abbrev") && ($restofline =~ /[^}]*}(.*)/)) {
$restofline = $1;
$state = "s_header_field_info_entry_abbrev_end";
$debug>1 && print "$linenumber $state\n";
} elsif (($state eq "s_header_field_info_entry_abbrev_end") && ($restofline =~ /[^}]*}(.*)/)) {
$restofline = $1;
$state = "s_in_hf_register_info";
$debug>1 && print "$linenumber $state\n";
} elsif (($state eq "s_start_expert") && ($restofline =~ /\W+{(.*)/)) {
$restofline = $1;
$state = "s_in_ei_register_info";
$debug>1 && print "$linenumber $state\n";
} elsif (($state eq "s_in_ei_register_info") && ($restofline =~ /\W+{(.*)/)) {
$restofline = $1;
$state = "s_ei_register_info_entry";
$debug>1 && print "$linenumber $state\n";
} elsif (($state eq "s_in_ei_register_info") && ($restofline =~ /\s*};(.*)/)) {
$restofline = $1;
$state = "s_unknown";
} elsif (($state eq "s_ei_register_info_entry") && ($restofline =~ /\s*{(.*)/)) {
$restofline = $1;
$state = "s_ei_register_info_entry_start";
$debug>1 && print "$linenumber $state\n";
} elsif (($state eq "s_ei_register_info_entry_start") && ($restofline =~ /\"([^\"]*)\"\s*,(.*)/)) {
$restofline = $2;
$debug>1 && print "$linenumber ei_register_info_entry_abbrev: $1\n";
$expert_filters{$linenumber} = $1;
$state = "s_ei_register_info_entry_abbrev_end";
} elsif (($state eq "s_ei_register_info_entry_abbrev_end") && ($restofline =~ /[^}]*}(.*)/)) {
$restofline = $1;
$state = "s_in_ei_register_info";
$debug>1 && print "$linenumber $state\n";
} else {
$more_tokens = 0;
}
}
$linenumber++;
}
&printprevfile();
if ($totalerrorcount > 0) {
print "\n\nTOTAL ERRORS: $totalerrorcount";
if ($filecount > 1) {
print " ($errorfilecount files)\n";
print "NO FIELDS: " . scalar(@nofieldfilelist) . "\n";
print "AUTOMATED: " . (scalar(@asn1automatedfilelist) + scalar(@dcerpcautomatedfilelist) + scalar(@idl2wrsautomatedfilelist)) . "\n";
print "NO PROTOCOL: " . scalar(@noregprotocolfilelist) . "\n";
print "\nASN.1 AUTOMATED FILE LIST\n";
foreach (@asn1automatedfilelist) {
print $_;
}
print "\nDCE/RPC AUTOMATED FILE LIST\n";
foreach (@dcerpcautomatedfilelist) {
print $_;
}
print "\nIDL2WRS AUTOMATED FILE LIST\n";
foreach (@idl2wrsautomatedfilelist) {
print $_;
}
print "\n\"FILE MANIPULATION\" FILE LIST\n";
@uniquefilelist = grep{ not $unique{$_}++} @filemanipulationfilelist;
foreach (@uniquefilelist) {
print $_;
}
print "\nREMOVE PREFIX FILE LIST\n";
@uniquefilelist = grep{ not $unique{$_}++} @prefixfilelist;
foreach (@uniquefilelist) {
print $_;
}
print "\nNO PROTOCOL REGISTERED FILE LIST\n";
foreach (@noregprotocolfilelist) {
print $_;
}
print "\nNO FIELDS FILE LIST\n";
foreach (@nofieldfilelist) {
print $_;
}
print "\nPERIOD IN PROTO FILTER NAME FILE LIST\n";
foreach (@periodinfilternamefilelist) {
print $_;
}
} else {
print "\n";
}
exit(1); # exit 1 if ERROR
}
__END__