1#!/usr/bin/perl 2 3my $debug = 0; 4# 0: off 5# 1: specific debug 6# 2: full debug 7 8# 9# verify that display filter names correspond with the PROTABBREV of 10# of the dissector. Enforces the dissector to have a source 11# filename of format packet-PROTABBREV.c 12# 13# Usage: checkfiltername.pl <file or files> 14 15# 16# Copyright 2011 Michael Mann (see AUTHORS file) 17# 18# Wireshark - Network traffic analyzer 19# By Gerald Combs <gerald@wireshark.org> 20# Copyright 1998 Gerald Combs 21# 22# SPDX-License-Identifier: GPL-2.0-or-later 23 24# 25# Example: 26# ~/work/wireshark/trunk/epan/dissectors> ../../tools/checkfiltername.pl packet-3com-xns.c 27# packet-3com-xns.c (2 (of 2) fields) 28# 102 3comxns.type doesn't match PROTOABBREV of 3com-xns 29# 106 3comxns.type doesn't match PROTOABBREV of 3com-xns 30# 31# or checkfiltername.pl packet-*.c, which will check all the dissector files. 32# 33# 34 35use warnings; 36use strict; 37use Getopt::Long; 38 39my @elements; 40my @elements_dup; 41my @protocols; 42my %filters; 43my %expert_filters; 44my @acceptedprefixes = ("dcerpc-"); 45my @asn1automatedfilelist; 46my @dcerpcautomatedfilelist; 47my @idl2wrsautomatedfilelist; 48my @filemanipulationfilelist; 49my @prefixfilelist; 50my @nofieldfilelist; 51my %unique; 52my @uniquefilelist; 53my @noregprotocolfilelist; 54my @periodinfilternamefilelist; 55 56my $showlinenoFlag = ''; 57my $showautomatedFlag = ''; 58 59my $state = ""; 60# "s_unknown", 61# "s_start", 62# "s_in_hf_register_info", 63# "s_hf_register_info_entry", 64# "s_header_field_info_entry", 65# "s_header_field_info_entry_start", 66# "s_header_field_info_entry_name", 67# "s_header_field_info_entry_abbrev", 68# "s_header_field_info_entry_abbrev_end", 69# "s_start_expert", 70# "s_in_ei_register_info", 71# "s_ei_register_info_entry", 72# "s_ei_register_info_entry_start", 73# "s_ei_register_info_entry_abbrev_end", 74# "s_nofields" 75 76my $restofline; 77my $filecount = 0; 78my $currfile = ""; 79my $protabbrev = ""; 80my $protabbrev_index; 81my $PFNAME_value = ""; 82my $linenumber = 1; 83my $totalerrorcount = 0; 84my $errorfilecount = 0; 85my $onefield = 0; 86my $nofields = 0; 87my $noperiod = 0; 88my $noregprotocol = 1; 89my $automated = 0; 90my $more_tokens; 91my $showall = 0; 92 93my $comment = 0; 94 95sub checkprotoabbrev { 96 my $abbrev = ""; 97 my $abbrevpos; 98 my $proto_abbrevpos1; 99 my $proto_abbrevpos2; 100 my $afterabbrev = ""; 101 my $check_dup_abbrev = ""; 102 my $modprotabbrev = ""; 103 my $errorline = 0; 104 my $prefix; 105 106 if (($automated == 0) || ($showall == 1)) { 107 $abbrevpos = index($_[0], "."); 108 if ($abbrevpos == -1) { 109 $abbrev = $_[0]; 110 } 111 else { 112 $abbrev = substr($_[0], 0, $abbrevpos); 113 $afterabbrev = substr($_[0], $abbrevpos+1, length($_[0])-$abbrevpos); 114 $check_dup_abbrev = $afterabbrev; 115 $afterabbrev = substr($afterabbrev, 0, length($abbrev)); 116 } 117 118 if ($abbrev ne $protabbrev) { 119 $errorline = 1; 120 121 #check if there is a supported protocol that matches the abbrev. 122 #This may be a case of filename != PROTOABBREV 123 foreach (@protocols) { 124 if ($abbrev eq $_) { 125 $errorline = 0; 126 } elsif (index($_, ".") != -1) { 127 128 #compare from start of string for each period found 129 $proto_abbrevpos1 = 0; 130 while ((($proto_abbrevpos2 = index($_, ".", $proto_abbrevpos1)) != -1) && 131 ($errorline == 1)) { 132 if ($abbrev eq substr($_, 0, $proto_abbrevpos2)) { 133 $errorline = 0; 134 } 135 136 $proto_abbrevpos1 = $proto_abbrevpos2+1; 137 } 138 } 139 } 140 } 141 142 # find any underscores that preface or follow a period 143 if (((index($_[0], "._") >= 0) || (index($_[0], "_.") >= 0)) && 144 #ASN.1 dissectors can intentionally generating this field name, so don't fault the dissector 145 (index($_[0], "_untag_item_element") < 0)) { 146 if ($showlinenoFlag) { 147 push(@elements, "$_[1] $_[0] contains an unnecessary \'_\'\n"); 148 } else { 149 push(@elements, "$_[0] contains an unnecessary \'_\'\n"); 150 } 151 } 152 153 if (($errorline == 1) && ($showall == 0)) { 154 #try some "accepted" variations of PROTOABBREV 155 156 #replace '-' with '_' 157 $modprotabbrev = $protabbrev; 158 $modprotabbrev =~ s/-/_/g; 159 if ($abbrev eq $modprotabbrev) { 160 $errorline = 0; 161 } 162 163 #remove '-' 164 if ($errorline == 1) { 165 $modprotabbrev = $protabbrev; 166 $modprotabbrev =~ s/-//g; 167 if ($abbrev eq $modprotabbrev) { 168 $errorline = 0; 169 } 170 } 171 172 #remove '_' 173 if ($errorline == 1) { 174 $modprotabbrev = $protabbrev; 175 $modprotabbrev =~ s/_//g; 176 if ($abbrev eq $modprotabbrev) { 177 $errorline = 0; 178 } 179 } 180 181 if ($errorline == 1) { 182 #remove any "accepted" prefix to see if there is still a problem 183 foreach (@acceptedprefixes) { 184 if ($protabbrev =~ /^$_/) { 185 $modprotabbrev = substr($protabbrev, length($_)); 186 if ($abbrev eq $modprotabbrev) { 187 push(@prefixfilelist, "$currfile\n"); 188 $errorline = 0; 189 } 190 } 191 } 192 } 193 else { 194 push(@filemanipulationfilelist, "$currfile\n"); 195 } 196 197 #now check the acceptable "fields from a different protocol" 198 if ($errorline == 1) { 199 if (is_from_other_protocol_allowed($_[0], $currfile) == 1) { 200 $errorline = 0; 201 } 202 } 203 204 #now check the acceptable "fields that include a version number" 205 if ($errorline == 1) { 206 if (is_protocol_version_allowed($_[0], $currfile) == 1) { 207 $errorline = 0; 208 } 209 } 210 } 211 212 if ($errorline == 1) { 213 $debug>1 && print "$_[1] $_[0] doesn't match PROTOABBREV of $protabbrev\n"; 214 if ($showlinenoFlag) { 215 push(@elements, "$_[1] $_[0] doesn't match PROTOABBREV of $protabbrev\n"); 216 } else { 217 push(@elements, "$_[0] doesn't match PROTOABBREV of $protabbrev\n"); 218 } 219 } 220 221 if (($abbrev ne "") && (lc($abbrev) eq lc($afterabbrev))) { 222 # Allow ASN.1 generated files to duplicate part of proto name 223 if ((!(grep {$currfile eq $_ } @asn1automatedfilelist)) && 224 # Check allowed list 225 (is_proto_dup_allowed($abbrev, $check_dup_abbrev) == 0)) { 226 if ($showlinenoFlag) { 227 push(@elements_dup, "$_[1] $_[0] duplicates PROTOABBREV of $abbrev\n"); 228 } else { 229 push(@elements_dup, "$_[0] duplicates PROTOABBREV of $abbrev\n"); 230 } 231 } 232 } 233 } 234} 235 236sub printprevfile { 237 my $totalfields = keys(%filters); 238 my $count_ele; 239 my $count_dup; 240 my $total_count; 241 242 foreach (sort keys %filters) { 243 checkprotoabbrev ($filters{$_}, $_); 244 } 245 246 foreach (sort keys %expert_filters) { 247 checkprotoabbrev ($expert_filters{$_}, $_); 248 } 249 250 $count_ele = @elements; 251 $count_dup = @elements_dup; 252 $total_count = $count_ele+$count_dup; 253 254 if ($noregprotocol == 1) { 255 #if no protocol is registered, only worry about duplicates 256 if ($currfile ne "") { 257 push(@noregprotocolfilelist, "$currfile\n"); 258 } 259 260 if ($count_dup > 0) { 261 $errorfilecount++; 262 $totalerrorcount += $count_dup; 263 } 264 265 if (($showall == 1) || ($count_dup > 0)) { 266 print "\n\n$currfile - NO PROTOCOL REGISTERED\n"; 267 if ($showall == 1) { 268 #everything is included, so count all errors 269 $totalerrorcount += $count_ele; 270 if (($count_ele > 0) && ($count_dup == 0)) { 271 $errorfilecount++; 272 } 273 274 foreach (@elements) { 275 print $_; 276 } 277 } 278 foreach (@elements_dup) { 279 print $_; 280 } 281 } 282 } else { 283 if ($total_count > 0) { 284 $errorfilecount++; 285 $totalerrorcount += $total_count; 286 } 287 288 if (($automated == 0) || ($showall == 1)) { 289 if ($total_count > 0) { 290 if ($automated == 1) { 291 if ($showall == 1) { 292 print "\n\n$currfile - AUTOMATED ($total_count (of $totalfields) fields)\n"; 293 } 294 } else { 295 print "\n\n$currfile ($total_count (of $totalfields) fields)\n"; 296 } 297 298 foreach (@elements) { 299 print $_; 300 } 301 foreach (@elements_dup) { 302 print $_; 303 } 304 } 305 306 if ((($nofields) || ($totalfields == 0)) && ($currfile ne "")) { 307 if ($showall == 1) { 308 print "\n\n$currfile - NO FIELDS\n"; 309 } 310 push(@nofieldfilelist, "$currfile\n"); 311 } 312 } 313 } 314} 315 316#-------------------------------------------------------------------- 317# This is a list of dissectors that intentionally have filter names 318# where the second segment duplicates (at least partially) the name 319# of the first. The most common case is in ASN.1 dissectors, but 320# those can be dealt with by looking at the first few lines of the 321# dissector. This list has been vetted and justification will need 322# to be provided to add to it. Acknowledge these dissectors aren't 323# a problem for the pre-commit script 324#-------------------------------------------------------------------- 325sub is_proto_dup_allowed { 326 if (($_[0] eq "amf") && (index($_[1], "amf0") >= 0)) {return 1;} 327 if (($_[0] eq "amf") && (index($_[1], "amf3") >= 0)) {return 1;} 328 if (($_[0] eq "amqp") && (index($_[1], "amqp") >= 0)) {return 1;} 329 if (($_[0] eq "bat") && (index($_[1], "batman") >= 0)) {return 1;} 330 if (($_[0] eq "browser") && (index($_[1], "browser_") >= 0)) {return 1;} 331 if (($_[0] eq "dlsw") && (index($_[1], "dlsw_version") >= 0)) {return 1;} 332 if (($_[0] eq "dns") && (index($_[1], "dnskey") >= 0)) {return 1;} 333 if (($_[0] eq "ecmp") && (index($_[1], "ecmp_") >= 0)) {return 1;} 334 if (($_[0] eq "exported_pdu") && (index($_[1], "exported_pdu") >= 0)) {return 1;} 335 if (($_[0] eq "fc") && (index($_[1], "fctl") >= 0)) {return 1;} 336 if (($_[0] eq "fcs") && (index($_[1], "fcsmask") >= 0)) {return 1;} 337 if (($_[0] eq "fmp") && (index($_[1], "fmp") >= 0)) {return 1;} 338 if (($_[0] eq "fr") && (index($_[1], "frame_relay") >= 0)) {return 1;} 339 if (($_[0] eq "lustre") && (index($_[1], "lustre_") >= 0)) {return 1;} 340 if (($_[0] eq "mac") && (index($_[1], "macd") >= 0)) {return 1;} 341 if (($_[0] eq "mac") && (index($_[1], "macis") >= 0)) {return 1;} 342 if (($_[0] eq "mih") && (index($_[1], "mihf") >= 0)) {return 1;} 343 if (($_[0] eq "mih") && (index($_[1], "mihcap") >= 0)) {return 1;} 344 if (($_[0] eq "ncp") && (index($_[1], "ncp") >= 0)) {return 1;} 345 if (($_[0] eq "nfs") && (index($_[1], "nfs") >= 0)) {return 1;} 346 if (($_[0] eq "oxid") && (index($_[1], "oxid") >= 0)) {return 1;} 347 if (($_[0] eq "rquota") && (index($_[1], "rquota") >= 0)) {return 1;} 348 if (($_[0] eq "pfcp") && (index($_[1], "pfcp") >= 0)) {return 1;} 349 if (($_[0] eq "sm") && (index($_[1], "sm_") >= 0)) {return 1;} 350 if (($_[0] eq "smpp") && (index($_[1], "smppplus") >= 0)) {return 1;} 351 if (($_[0] eq "spray") && (index($_[1], "sprayarr") >= 0)) {return 1;} 352 if (($_[0] eq "tds") && (index($_[1], "tds_") >= 0)) {return 1;} 353 if (($_[0] eq "time") && (index($_[1], "time") >= 0)) {return 1;} 354 if (($_[0] eq "tn3270") && (index($_[1], "tn3270e") >= 0)) {return 1;} 355 if (($_[0] eq "usb") && (index($_[1], "usb") >= 0)) {return 1;} 356 if (($_[0] eq "xml") && (index($_[1], "xml") >= 0)) {return 1;} 357 358 return 0; 359} 360 361#-------------------------------------------------------------------- 362# This is a list of dissectors that intentionally have filter names 363# shared with other dissectors. This list has been vetted and 364# justification will need to be provided to add to it. 365# Acknowledge these dissectors aren't a problem for the pre-commit script 366#-------------------------------------------------------------------- 367sub is_from_other_protocol_allowed { 368 my $proto_filename; 369 my $dir_index = rindex($_[1], "\\"); 370 371 #handle directory names on all platforms 372 if ($dir_index < 0) { 373 $dir_index = rindex($_[1], "/"); 374 } 375 376 if ($dir_index < 0) { 377 $proto_filename = $_[1]; 378 } 379 else { 380 $proto_filename = substr($_[1], $dir_index+1); 381 } 382 383 # XXX - may be faster to hash this (note 1-many relationship)? 384 if (($proto_filename eq "packet-atalk.c") && (index($_[0], "llc") >= 0)) {return 1;} 385 if (($proto_filename eq "packet-awdl.c") && (index($_[0], "llc") >= 0)) {return 1;} 386 if (($proto_filename eq "packet-bpdu.c") && (index($_[0], "mstp") >= 0)) {return 1;} 387 if (($proto_filename eq "packet-bssap.c") && (index($_[0], "bsap") >= 0)) {return 1;} 388 if (($proto_filename eq "packet-caneth.c") && (index($_[0], "can") >= 0)) {return 1;} 389 if (($proto_filename eq "packet-cimetrics.c") && (index($_[0], "llc") >= 0)) {return 1;} 390 if (($proto_filename eq "packet-cipsafety.c") && (index($_[0], "cip") >= 0)) {return 1;} 391 if (($proto_filename eq "packet-cipsafety.c") && (index($_[0], "enip") >= 0)) {return 1;} 392 if (($proto_filename eq "packet-dcerpc-netlogon.c") && (index($_[0], "ntlmssp") >= 0)) {return 1;} 393 if (($proto_filename eq "packet-dcom-oxid.c") && (index($_[0], "dcom") >= 0)) {return 1;} 394 if (($proto_filename eq "packet-dvb-data-mpe.c") && (index($_[0], "mpeg_sect") >= 0)) {return 1;} 395 if (($proto_filename eq "packet-dvb-ipdc.c") && (index($_[0], "ipdc") >= 0)) {return 1;} 396 if (($proto_filename eq "packet-enip.c") && (index($_[0], "cip") >= 0)) {return 1;} 397 if (($proto_filename eq "packet-extreme.c") && (index($_[0], "llc") >= 0)) {return 1;} 398 if (($proto_filename eq "packet-fmp_notify.c") && (index($_[0], "fmp") >= 0)) {return 1;} 399 if (($proto_filename eq "packet-foundry.c") && (index($_[0], "llc") >= 0)) {return 1;} 400 if (($proto_filename eq "packet-glusterfs.c") && (index($_[0], "gluster") >= 0)) {return 1;} 401 if (($proto_filename eq "packet-h248_annex_e.c") && (index($_[0], "h248") >= 0)) {return 1;} 402 if (($proto_filename eq "packet-h248_q1950.c") && (index($_[0], "h248") >= 0)) {return 1;} 403 if (($proto_filename eq "packet-ieee1722.c") && (index($_[0], "can") >= 0)) {return 1;} 404 if (($proto_filename eq "packet-ieee80211.c") && (index($_[0], "eapol") >= 0)) {return 1;} 405 if (($proto_filename eq "packet-ieee80211-radio.c") && (index($_[0], "wlan") >= 0)) {return 1;} 406 if (($proto_filename eq "packet-ieee80211-wlancap.c") && (index($_[0], "wlan") >= 0)) {return 1;} 407 if (($proto_filename eq "packet-ieee802154.c") && (index($_[0], "wpan") >= 0)) {return 1;} 408 if (($proto_filename eq "packet-isup.c") && (index($_[0], "ansi_isup") >= 0)) {return 1;} 409 if (($proto_filename eq "packet-isup.c") && (index($_[0], "bat_ase") >= 0)) {return 1;} 410 if (($proto_filename eq "packet-isup.c") && (index($_[0], "nsap") >= 0)) {return 1;} 411 if (($proto_filename eq "packet-isup.c") && (index($_[0], "x213") >= 0)) {return 1;} 412 if (($proto_filename eq "packet-iwarp-ddp-rdmap.c") && (index($_[0], "iwarp_ddp") >= 0)) {return 1;} 413 if (($proto_filename eq "packet-iwarp-ddp-rdmap.c") && (index($_[0], "iwarp_rdma") >= 0)) {return 1;} 414 if (($proto_filename eq "packet-k12.c") && (index($_[0], "aal2") >= 0)) {return 1;} 415 if (($proto_filename eq "packet-k12.c") && (index($_[0], "atm") >= 0)) {return 1;} 416 if (($proto_filename eq "packet-m3ua.c") && (index($_[0], "mtp3") >= 0)) {return 1;} 417 if (($proto_filename eq "packet-mle.c") && (index($_[0], "wpan") >= 0)) {return 1;} 418 if (($proto_filename eq "packet-mpeg-dsmcc.c") && (index($_[0], "mpeg_sect") >= 0)) {return 1;} 419 if (($proto_filename eq "packet-mpeg-dsmcc.c") && (index($_[0], "etv.dsmcc") >= 0)) {return 1;} 420 if (($proto_filename eq "packet-mpeg1.c") && (index($_[0], "rtp.payload_mpeg_") >= 0)) {return 1;} 421 if (($proto_filename eq "packet-mysql.c") && (index($_[0], "mariadb") >= 0)) {return 1;} 422 if (($proto_filename eq "packet-ndps.c") && (index($_[0], "spx.ndps_") >= 0)) {return 1;} 423 if (($proto_filename eq "packet-pw-atm.c") && (index($_[0], "atm") >= 0)) {return 1;} 424 if (($proto_filename eq "packet-pw-atm.c") && (index($_[0], "pw") >= 0)) {return 1;} 425 if (($proto_filename eq "packet-scsi.c") && (index($_[0], "scsi_sbc") >= 0)) {return 1;} 426 if (($proto_filename eq "packet-sndcp-xid.c") && (index($_[0], "llcgprs") >= 0)) {return 1;} 427 if (($proto_filename eq "packet-wlccp.c") && (index($_[0], "llc") >= 0)) {return 1;} 428 if (($proto_filename eq "packet-wps.c") && (index($_[0], "eap") >= 0)) {return 1;} 429 if (($proto_filename eq "packet-wsp.c") && (index($_[0], "wap") >= 0)) {return 1;} 430 if (($proto_filename eq "packet-xot.c") && (index($_[0], "x25") >= 0)) {return 1;} 431 if (($proto_filename eq "packet-zbee-zcl-misc.c") && (index($_[0], "zbee_zcl_hvac") >= 0)) {return 1;} 432 if (($proto_filename eq "packet-zbee-zcl-misc.c") && (index($_[0], "zbee_zcl_ias") >= 0)) {return 1;} 433 434 #Understand why, but I think it could be prefixed with "dissector" 435 #prefix (which isn't necessarily "protocol") 436 if (($proto_filename eq "packet-rtcp.c") && (index($_[0], "srtcp") >= 0)) {return 1;} 437 if (($proto_filename eq "packet-rtp.c") && (index($_[0], "srtp") >= 0)) {return 1;} 438 if (($proto_filename eq "packet-dcom-cba-acco.c") && (index($_[0], "cba") >= 0)) {return 1;} 439 if (($proto_filename eq "packet-dcom-cba.c") && (index($_[0], "cba") >= 0)) {return 1;} 440 441 #XXX - HACK to get around nested "s in field name 442 if (($proto_filename eq "packet-gsm_sim.c") && (index($_[0], "e\\") >= 0)) {return 1;} 443 444 return 0; 445} 446 447#-------------------------------------------------------------------- 448# This is a list of dissectors that use their (protocol) version number 449# as part of the first display filter segment, which checkfiltername 450# usually complains about. Manually allow them so that they can pass 451# pre-commit script 452#-------------------------------------------------------------------- 453sub is_protocol_version_allowed { 454 my $proto_filename; 455 my $dir_index = rindex($_[1], "\\"); 456 457 #handle directory names on all platforms 458 if ($dir_index < 0) { 459 $dir_index = rindex($_[1], "/"); 460 } 461 462 if ($dir_index < 0) { 463 $proto_filename = $_[1]; 464 } 465 else { 466 $proto_filename = substr($_[1], $dir_index+1); 467 } 468 469 # XXX - may be faster to hash this? 470 if (($proto_filename eq "packet-ehs.c") && (index($_[0], "ehs2") >= 0)) {return 1;} 471 if (($proto_filename eq "packet-hsrp.c") && (index($_[0], "hsrp2") >= 0)) {return 1;} 472 if (($proto_filename eq "packet-ipv6.c") && (index($_[0], "ip") >= 0)) {return 1;} 473 if (($proto_filename eq "packet-openflow_v1.c") && (index($_[0], "openflow") >= 0)) {return 1;} 474 if (($proto_filename eq "packet-rtnet.c") && (index($_[0], "tdma-v1") >= 0)) {return 1;} 475 if (($proto_filename eq "packet-scsi-osd.c") && (index($_[0], "scsi_osd2") >= 0)) {return 1;} 476 if (($proto_filename eq "packet-sflow.c") && (index($_[0], "sflow_5") >= 0)) {return 1;} 477 if (($proto_filename eq "packet-sflow.c") && (index($_[0], "sflow_245") >= 0)) {return 1;} 478 if (($proto_filename eq "packet-tipc.c") && (index($_[0], "tipcv2") >= 0)) {return 1;} 479 if (($proto_filename eq "packet-bluetooth.c") && (index($_[0], "llc.bluetooth_pid") >= 0)) {return 1;} 480 481 return 0; 482} 483 484# --------------------------------------------------------------------- 485# 486# MAIN 487# 488GetOptions( 489 'showlineno' => \$showlinenoFlag, 490 'showautomated' => \$showautomatedFlag, 491 ); 492 493while (<>) { 494 if ($currfile !~ /$ARGV/) { 495 &printprevfile(); 496 497 # New file - reset array and state 498 $filecount++; 499 $currfile = $ARGV; 500 501 #determine PROTABBREV for dissector based on file name format of (dirs)/packet-PROTABBREV.c or (dirs)/file-PROTABBREV.c 502 $protabbrev_index = rindex($currfile, "packet-"); 503 if ($protabbrev_index == -1) { 504 $protabbrev_index = rindex($currfile, "file-"); 505 if ($protabbrev_index == -1) { 506 #ignore "non-dissector" files 507 next; 508 } 509 510 $protabbrev = substr($currfile, $protabbrev_index+length("file-")); 511 $protabbrev_index = rindex($protabbrev, "."); 512 if ($protabbrev_index == -1) { 513 print "$currfile doesn't fit format of file-PROTABBREV.c\n"; 514 next; 515 } 516 } else { 517 $protabbrev = substr($currfile, $protabbrev_index+length("packet-")); 518 $protabbrev_index = rindex($protabbrev, "."); 519 if ($protabbrev_index == -1) { 520 print "$currfile doesn't fit format of packet-PROTABBREV.c\n"; 521 next; 522 } 523 } 524 $protabbrev = substr($protabbrev, 0, $protabbrev_index); 525 526 $PFNAME_value = ""; 527 $noregprotocol = 1; 528 $automated = 0; 529 $nofields = 0; 530 $onefield = 0; 531 $noperiod = 0; 532 $linenumber = 1; 533 %filters = ( ); 534 %expert_filters = ( ); 535 @protocols = ( ); 536 @elements = ( ); 537 @elements_dup = ( ); 538 $state = "s_unknown"; 539 } 540 541 if (($automated == 0) && ($showautomatedFlag eq "")) { 542 #DCERPC automated files 543 if ($_ =~ "DO NOT EDIT") { 544 push(@dcerpcautomatedfilelist, "$currfile\n"); 545 $automated = 1; 546 next; 547 } 548 #ASN.1 automated files 549 elsif ($_ =~ "Generated automatically by the ASN.1 to Wireshark dissector compiler") { 550 push(@asn1automatedfilelist, "$currfile\n"); 551 $automated = 1; 552 next; 553 } 554 #idl2wrs automated files 555 elsif ($_ =~ "Autogenerated from idl2wrs") { 556 push(@idl2wrsautomatedfilelist, "$currfile\n"); 557 $automated = 1; 558 next; 559 } 560 } 561 562 # opening then closing comment 563 if (/(.*?)\/\*.*\*\/(.*)/) { 564 $comment = 0; 565 $_ = "$1$2"; 566 # closing then opening comment 567 } elsif (/.*?\*\/(.*?)\/\*/) { 568 $comment = 1; 569 $_ = "$1"; 570 # opening comment 571 } elsif (/(.*?)\/\*/) { 572 $comment = 1; 573 $_ = "$1"; 574 # closing comment 575 } elsif (/\*\/(.*?)/) { 576 $comment = 0; 577 $_ = "$1"; 578 } elsif ($comment == 1) { 579 $linenumber++; 580 next; 581 } 582 # unhandled: more than one complete comment per line 583 584 chomp; 585 586 #proto_register_protocol state machine 587 $restofline = $_; 588 $more_tokens = 1; 589 590 #PFNAME is a popular #define for the proto filter name, so use it for testing 591 if ($restofline =~ /#define\s*PFNAME\s*\"([^\"]*)\"/) { 592 $PFNAME_value = $1; 593 $debug>1 && print "PFNAME: '$1'\n"; 594 } 595 596 until ($more_tokens == 0) { 597 if (($restofline =~ /proto_register_protocol\s*\((.*)/) || 598 ($restofline =~ /proto_register_protocol_in_name_only\s*\((.*)/)) { 599 $noregprotocol = 0; 600 $restofline = $1; 601 $state = "s_proto_start"; 602 } elsif (($state eq "s_proto_start") && ($restofline =~ /^(\s*\"([^\"]*)\"\s*,)\s*(.*)/)) { 603 $restofline = $3; 604 $state = "s_proto_long_name"; 605 $debug>1 && print "proto long name: '$2'\n"; 606 } elsif (($state eq "s_proto_start") && ($restofline =~ /^(\s*(([\w\d])+)\s*,)\s*(.*)/)) { 607 $restofline = $4; 608 $state = "s_proto_long_name"; 609 $debug>1 && print "proto long name: '$2'\n"; 610 } elsif (($state eq "s_proto_long_name") && ($restofline =~ /^(\s*\"([^\"]*)\"\s*,)\s*(.*)/)) { 611 $restofline = $3; 612 $state = "s_proto_short_name"; 613 $debug>1 && print "proto short name: '$2'\n"; 614 } elsif (($state eq "s_proto_long_name") && ($restofline =~ /^(\s*(([\w\d])+)\s*,)\s*(.*)/)) { 615 $restofline = $4; 616 $state = "s_proto_short_name"; 617 $debug>1 && print "proto short name: '$2'\n"; 618 } elsif (($state eq "s_proto_short_name") && ($restofline =~ /\s*PFNAME\s*(.*)/)) { 619 $more_tokens = 0; 620 $state = "s_proto_filter_name"; 621 if ((index($PFNAME_value, ".") != -1) && ($noperiod == 0)) { 622 push(@periodinfilternamefilelist, "$currfile\n"); 623 $noperiod = 1; 624 } 625 push(@protocols, $PFNAME_value); 626 $debug>1 && print "proto filter name: '$PFNAME_value'\n"; 627 } elsif (($state eq "s_proto_short_name") && ($restofline =~ /\s*\"([^\"]*)\"\s*(.*)/)) { 628 $more_tokens = 0; 629 $state = "s_proto_filter_name"; 630 if ((index($1, ".") != -1) && ($noperiod == 0)) { 631 push(@periodinfilternamefilelist, "$currfile\n"); 632 $noperiod = 1; 633 } 634 push(@protocols, $1); 635 $debug>1 && print "proto filter name: '$1'\n"; 636 } elsif (($state eq "s_proto_short_name") && ($restofline =~ /\s*(([\w\d])+)\s*(.*)/)) { 637 $more_tokens = 0; 638 $state = "s_proto_filter_name"; 639 $debug>1 && print "proto filter name: '$1'\n"; 640 } else { 641 $more_tokens = 0; 642 } 643 } 644 645 #retrieving display filters state machine 646 $restofline = $_; 647 $more_tokens = 1; 648 until ($more_tokens == 0) { 649 if ($restofline =~ /\s*static\s*hf_register_info\s*(\w+)\[\](.*)/) { 650 $restofline = $2; 651 $state = "s_start"; 652 $debug>1 && print "$linenumber $state\n"; 653 } elsif ($restofline =~ /\s*static\s*ei_register_info\s*(\w+)\[\](.*)/) { 654 $restofline = $2; 655 $state = "s_start_expert"; 656 $debug>1 && print "$linenumber $state\n"; 657 } elsif (($state eq "s_start") && ($restofline =~ /\W+{(.*)/)) { 658 $restofline = $1; 659 $state = "s_in_hf_register_info"; 660 $debug>1 && print "$linenumber $state\n"; 661 } elsif (($state eq "s_in_hf_register_info") && ($restofline =~ /\W+{(.*)/)) { 662 $restofline = $1; 663 $state = "s_hf_register_info_entry"; 664 $debug>1 && print "$linenumber $state\n"; 665 $onefield = 1; 666 } elsif (($state eq "s_in_hf_register_info") && ($restofline =~ /\s*};(.*)/)) { 667 $restofline = $1; 668 if ($onefield == 0) { 669 $debug && print "$linenumber NO FIELDS!!!\n"; 670 $nofields = 1; 671 $state = "s_nofields"; 672 $more_tokens = 0; 673 } else { 674 $state = "s_unknown"; 675 } 676 } elsif (($state eq "s_hf_register_info_entry") && ($restofline =~ /\s*&\s*(hf_\w*(\[w*\])?)\s*,?(.*)/)) { 677 $restofline = $3; 678 $debug>1 && print "$linenumber hf_register_info_entry: $1\n"; 679 $state = "s_header_field_info_entry"; 680 } elsif (($state eq "s_header_field_info_entry") && ($restofline =~ /\s*{(.*)/)) { 681 $restofline = $1; 682 $state = "s_header_field_info_entry_start"; 683 $debug>1 && print "$linenumber $state\n"; 684 } elsif (($state eq "s_header_field_info_entry_start") && ($restofline =~ /((\"([^\"]*)\")|(\w+))\s*,(.*)/)) { 685 $restofline = $5; 686 $debug>1 && print "$linenumber header_field_info_entry_name: $1\n"; 687 $state = "s_header_field_info_entry_name"; 688 } elsif (($state eq "s_header_field_info_entry_name") && ($restofline =~ /\"([^\"]*)\"\s*,?(.*)/)) { 689 $restofline = $2; 690 $debug>1 && print "$linenumber header_field_info_entry_abbrev: $1\n"; 691 $state = "s_header_field_info_entry_abbrev"; 692 $filters{$linenumber} = $1; 693 } elsif (($state eq "s_header_field_info_entry_abbrev") && ($restofline =~ /[^}]*}(.*)/)) { 694 $restofline = $1; 695 $state = "s_header_field_info_entry_abbrev_end"; 696 $debug>1 && print "$linenumber $state\n"; 697 } elsif (($state eq "s_header_field_info_entry_abbrev_end") && ($restofline =~ /[^}]*}(.*)/)) { 698 $restofline = $1; 699 $state = "s_in_hf_register_info"; 700 $debug>1 && print "$linenumber $state\n"; 701 } elsif (($state eq "s_start_expert") && ($restofline =~ /\W+{(.*)/)) { 702 $restofline = $1; 703 $state = "s_in_ei_register_info"; 704 $debug>1 && print "$linenumber $state\n"; 705 } elsif (($state eq "s_in_ei_register_info") && ($restofline =~ /\W+{(.*)/)) { 706 $restofline = $1; 707 $state = "s_ei_register_info_entry"; 708 $debug>1 && print "$linenumber $state\n"; 709 } elsif (($state eq "s_in_ei_register_info") && ($restofline =~ /\s*};(.*)/)) { 710 $restofline = $1; 711 $state = "s_unknown"; 712 } elsif (($state eq "s_ei_register_info_entry") && ($restofline =~ /\s*{(.*)/)) { 713 $restofline = $1; 714 $state = "s_ei_register_info_entry_start"; 715 $debug>1 && print "$linenumber $state\n"; 716 } elsif (($state eq "s_ei_register_info_entry_start") && ($restofline =~ /\"([^\"]*)\"\s*,(.*)/)) { 717 $restofline = $2; 718 $debug>1 && print "$linenumber ei_register_info_entry_abbrev: $1\n"; 719 $expert_filters{$linenumber} = $1; 720 $state = "s_ei_register_info_entry_abbrev_end"; 721 } elsif (($state eq "s_ei_register_info_entry_abbrev_end") && ($restofline =~ /[^}]*}(.*)/)) { 722 $restofline = $1; 723 $state = "s_in_ei_register_info"; 724 $debug>1 && print "$linenumber $state\n"; 725 } else { 726 $more_tokens = 0; 727 } 728 } 729 730 $linenumber++; 731} 732 733&printprevfile(); 734 735if ($totalerrorcount > 0) { 736 print "\n\nTOTAL ERRORS: $totalerrorcount"; 737 738 if ($filecount > 1) { 739 print " ($errorfilecount files)\n"; 740 741 print "NO FIELDS: " . scalar(@nofieldfilelist) . "\n"; 742 print "AUTOMATED: " . (scalar(@asn1automatedfilelist) + scalar(@dcerpcautomatedfilelist) + scalar(@idl2wrsautomatedfilelist)) . "\n"; 743 print "NO PROTOCOL: " . scalar(@noregprotocolfilelist) . "\n"; 744 745 print "\nASN.1 AUTOMATED FILE LIST\n"; 746 foreach (@asn1automatedfilelist) { 747 print $_; 748 } 749 print "\nDCE/RPC AUTOMATED FILE LIST\n"; 750 foreach (@dcerpcautomatedfilelist) { 751 print $_; 752 } 753 print "\nIDL2WRS AUTOMATED FILE LIST\n"; 754 foreach (@idl2wrsautomatedfilelist) { 755 print $_; 756 } 757 print "\n\"FILE MANIPULATION\" FILE LIST\n"; 758 @uniquefilelist = grep{ not $unique{$_}++} @filemanipulationfilelist; 759 foreach (@uniquefilelist) { 760 print $_; 761 } 762 print "\nREMOVE PREFIX FILE LIST\n"; 763 @uniquefilelist = grep{ not $unique{$_}++} @prefixfilelist; 764 foreach (@uniquefilelist) { 765 print $_; 766 } 767 print "\nNO PROTOCOL REGISTERED FILE LIST\n"; 768 foreach (@noregprotocolfilelist) { 769 print $_; 770 } 771 print "\nNO FIELDS FILE LIST\n"; 772 foreach (@nofieldfilelist) { 773 print $_; 774 } 775 776 print "\nPERIOD IN PROTO FILTER NAME FILE LIST\n"; 777 foreach (@periodinfilternamefilelist) { 778 print $_; 779 } 780 } else { 781 print "\n"; 782 } 783 784 exit(1); # exit 1 if ERROR 785} 786 787__END__ 788