Allow the "manuf" file to contain well-known MAC addresses and address
[obnox/wireshark/wip.git] / make-manuf
1 #!/usr/bin/perl -w
2 #
3 # $Id: make-manuf,v 1.7 2002/09/09 19:38:09 guy Exp $
4 #
5 # Make-manuf - Creates a file containing ethernet OUIs and their
6 # company IDs.  It merges the databases at
7 # http://standards.ieee.org/regauth/oui/index.shtml and
8 # http://www.cavebear.com/CaveBear/Ethernet/
9 # with entries in our template file.
10 #
11 # The script reads the comments at the top of "manuf.tmpl" and writes
12 # them to "manuf".  It then joins the manufacturer listing in "manuf.tmpl"
13 # with the listing in "oui.txt", with the entries in "manuf.tmpl" taking
14 # precedence.
15
16 # LWP is part of the standard Perl module libwww 
17 eval "require LWP::UserAgent;";
18 if( $@ ) {
19   die "LWP isn't installed. It is part of the standard Perl\n" .
20         " module libwww.  Bailing.\n";
21 }
22
23 $template = "manuf.tmpl";
24 $wkatmpl  = "wka.tmpl";
25 $outfile  = "manuf";
26 $inheader = 1;
27 $ieee_url = "http://standards.ieee.org/regauth/oui/oui_public.txt";
28 $cb_url   = "http://www.cavebear.com/CaveBear/Ethernet/Ethernet.txt";
29 %oui_list = ();
30 $hp       = "[0-9a-fA-F]{2}";
31 $oui_re   = "$hp:$hp:$hp";
32 $cb_re    = "$hp$hp$hp";
33 $ieee_re  = "$hp-$hp-$hp";
34
35 $tmpl_added   = 0;
36 $cb_added     = 0;
37 $cb_skipped   = 0;
38 $ieee_added   = 0;
39 $ieee_skipped = 0;
40
41 $agent    = LWP::UserAgent->new;
42
43 print "Fetching $cb_url.\n";
44 $request  = HTTP::Request->new(GET => $cb_url);
45 $result   = $agent->request($request);
46
47 if (!$result->is_success) {
48   die ("Error fetching $cb_url: " . $result->status_line . "\n");
49 }
50 $cb_list = $result->content;
51
52 print "Fetching $ieee_url.\n";
53 $request  = HTTP::Request->new(GET => $ieee_url);
54 $result   = $agent->request($request);
55
56 if (!$result->is_success) {
57   die ("Error fetching $ieee_url: " . $result->status_line . "\n");
58 }
59 $ieee_list = $result->content;
60
61 open (TMPL, "< $template") || 
62   die "Couldn't open template file for reading ($template)\n";
63
64 open (WKATMPL, "< $wkatmpl") || 
65   die "Couldn't open well-known address template file for reading ($wkatmpl)\n";
66
67 open (OUT, "> $outfile") ||
68   die "Couldn't open output file for writing ($outfile)\n";
69
70 # Write out the header and populate the OUI list with our entries.
71 while ($line = <TMPL>) {
72   chomp($line);
73   if ($line !~ /^$oui_re\s+\S/ && $inheader) {
74     print(OUT "$line\n");
75   } elsif (($oui, $manuf) = ($line =~ /^($oui_re)\s+(\S.*)$/)) {
76     $inheader = 0;
77     # Ensure OUI is all upper-case
78     $oui =~ tr/a-f/A-F/;
79     $oui_list{$oui} = $manuf;
80     $tmpl_added++;
81   }
82 }
83
84 # Add IEEE entries for OUIs not yet known.
85 foreach $line (split(/\n/, $ieee_list)) {
86   if (($oui, $manuf) = ($line =~ /^($ieee_re)\s+\(hex\)\s+(\S.*)$/)) {
87     $oui =~ tr /-/:/;  # The IEEE bytes are separated by dashes.
88     # Ensure OUI is all upper-case
89     $oui =~ tr/a-f/A-F/;
90     if (exists $oui_list{$oui}) {
91       printf "$oui - Skipping IEEE \"$manuf\" in favor of \"$oui_list{$oui}\"\n";
92       $ieee_skipped++;
93     } else {
94       $oui_list{$oui} = $manuf;
95       $ieee_added++;
96     }
97   }
98 }
99
100 # Add CaveBear entries for OUIs not yet known.
101 foreach $line (split(/\n/, $cb_list)) {
102   if (($oui, $manuf) = ($line =~ /^($cb_re)\s+(\S.*)$/)) {
103     ($h1, $h2, $h3) = ($oui =~ /($hp)($hp)($hp)/);  # The CaveBear bytes have no separators
104     $oui = "$h1:$h2:$h3";
105     # Ensure OUI is all upper-case
106     $oui =~ tr/a-f/A-F/;
107     if (exists $oui_list{$oui}) {
108       printf "$oui - Skipping CaveBear \"$manuf\" in favor of \"$oui_list{$oui}\"\n";
109       $cb_skipped++;
110     } else {
111       $oui_list{$oui} = $manuf;
112       $cb_added++;
113     }
114   }
115 }
116
117 foreach $oui (sort(keys %oui_list)) {
118   print(OUT "$oui\t$oui_list{$oui}\n");
119 }
120
121 #
122 # Write out a blank line separating the OUIs from the well-known
123 # addresses, and then read the well-known address template file
124 # and write it to the manuf file.
125 #
126 # XXX - it'd be nice to get this from the Cavebear file, but inferring
127 # the address mask from entries in that file involves some work.
128 #
129 print(OUT "\n");
130 while ($line = <WKATMPL>) {
131   chomp($line);
132   print(OUT "$line\n");
133 }
134
135 $total_added = $tmpl_added + $cb_added + $ieee_added;
136 print <<"Fin"
137 Original entries : $tmpl_added
138 IEEE added       : $ieee_added
139 CaveBear added   : $cb_added
140 Total            : $total_added
141
142 IEEE skipped     : $ieee_skipped
143 CaveBear skipped : $cb_skipped
144 Fin