Annotation of tme/machine/sun/tme-sun-idprom.pl, revision 1.1.1.2

1.1       root        1: #! /usr/pkg/bin/perl -w
                      2: 
1.1.1.2 ! root        3: # $Id: tme-sun-idprom.pl,v 1.2 2003/07/29 18:21:31 fredette Exp $
1.1       root        4: 
                      5: # machine/sun/sun-idprom.pl - dumps and makes Sun IDPROM contents:
                      6: 
                      7: # Copyright (c) 2003 Matt Fredette
                      8: # All rights reserved.
                      9: #
                     10: # Redistribution and use in source and binary forms, with or without
                     11: # modification, are permitted provided that the following conditions
                     12: # are met:
                     13: # 1. Redistributions of source code must retain the above copyright
                     14: #    notice, this list of conditions and the following disclaimer.
                     15: # 2. Redistributions in binary form must reproduce the above copyright
                     16: #    notice, this list of conditions and the following disclaimer in the
                     17: #    documentation and/or other materials provided with the distribution.
                     18: # 3. All advertising materials mentioning features or use of this software
                     19: #    must display the following acknowledgement:
                     20: #      This product includes software developed by Matt Fredette.
                     21: # 4. The name of the author may not be used to endorse or promote products
                     22: #    derived from this software without specific prior written permission.
                     23: #
                     24: # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     25: # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
                     26: # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
                     27: # DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
                     28: # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
                     29: # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
                     30: # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     31: # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
                     32: # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
                     33: # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     34: # POSSIBILITY OF SUCH DAMAGE.
                     35: 
                     36: # mapping from machine name to Sun code name:
                     37: @machine_codename = 
                     38:     ( '2/120',                 'sun2 Multibus',
                     39:       '2/170',                 'sun2 Multibus',
                     40:       '2/50',                  'sun2 VME',
                     41:       '2/130',                 'sun2 VME',
                     42:       '2/160',                 'sun2 VME',
                     43:       '3/75',                  'Carrera',
                     44:       '3/140',                 'Carrera',
                     45:       '3/150',                 'Carrera',
                     46:       '3/160',                 'Carrera',
                     47:       '3/180',                 'Carrera',
                     48:       '3/50',                  'Model 25',
                     49:       '3/260',                 'Sirius',
                     50:       '3/280',                 'Sirius',
                     51:       '3/110',                 'Prism',
                     52:       '3/60',                  'Ferrari',
                     53:       '3/E',                   'Sun3E',
                     54:       '4/260',                 'Sunrise',
                     55:       '4/280',                 'Sunrise',
                     56:       '4/110',                 'Cobra',
                     57:       '4/150',                 'Cobra',
                     58:       '4/330',                 'Stingray',
                     59:       '4/310',                 'Stingray',
                     60:       '4/350',                 'Stingray',
                     61:       '4/360',                 'Stingray',
                     62:       '4/370',                 'Stingray',
                     63:       '4/380',                 'Stingray',
                     64:       '4/390',                 'Stingray',
                     65:       '4/470',                 'Sunray',
                     66:       '4/490',                 'Sunray',
1.1.1.2 ! root       67:       '386i/MB1',              'Roadrunner-MB1',
1.1       root       68:       '386i/150',              'Roadrunner',
                     69:       '386i/250',              'Roadrunner',
                     70:       '3/460',                 'Pegasus',
                     71:       '3/470',                 'Pegasus',
                     72:       '3/480',                 'Pegasus',
                     73:       '3/80',                  'Hydra',
                     74:       '*SPARCStation 1',       'Campus',
                     75:       'SS1',                   'Campus',
                     76:       '4/60',                  'Campus',
                     77:       '*SPARCstation IPC',     'Phoenix',
                     78:       'IPC',                   'Phoenix',
                     79:       '4/40',                  'Phoenix',
                     80:       '*SPARCStation 1+',      'Campus B',
                     81:       'SS1+',                  'Campus B',
                     82:       '4/65',                  'Campus B',
                     83:       '*SPARCstation SLC',     'Off-Campus',
                     84:       'SLC',                   'Off-Campus',
                     85:       '4/20',                  'Off-Campus',
                     86:       '*SPARCStation 2',       'Calvin',
                     87:       'SS2',                   'Calvin',
                     88:       '4/75',                  'Calvin',
                     89:       '*SPARCstation ELC',     'Node Warrior',
                     90:       'ELC',                   'Node Warrior',
                     91:       '4/25',                  'Node Warrior',
                     92:       '*SPARCstation IPX',     'Hobbes',
                     93:       'IPX',                   'Hobbes',
                     94:       '4/50',                  'Hobbes',
                     95:       '*SPARCengine 1',                'Polaris',
                     96:       '4/E',                   'Polaris',
                     97:       '4/600',                 'Galaxy',
                     98:       '4/630',                 'Galaxy',
                     99:       '4/670',                 'Galaxy',
                    100:       '4/690',                 'Galaxy',
                    101:       '*SPARCstation 10',      'Campus-2',
                    102:       'SS10',                  'Campus-2',
                    103:       '*SPARCstation 20',      'Kodiak',
                    104:       'SS20',                  'Kodiak',
                    105:       '*SPARCclassic X',       'Hamlet',
                    106:       'Classic X',             'Hamlet',
                    107:       '4/10',                  'Hamlet',
                    108:       '*SPARCClassic',         'Sunergy',
                    109:       '4/15',                  'Sunergy',
                    110:       'classic',               'Sunergy',
                    111:       '4/30',                  'Sunergy',
                    112:       'SPARCstation LX',       'Sunergy',
                    113:       'LX',                    'Sunergy',
                    114:       'Voyager',               'Gypsy',
                    115:       'SS5',                   'Aurora',
                    116:       'SS4',                   'Perigee',
                    117:       );
                    118: %machine_codename = @machine_codename;
                    119: 
                    120: # mapping from Sun code name to IDPROM machine type byte:
                    121: @codename_machtype = 
                    122:     ( 'sun2 Multibus', 0x01,
                    123:       'sun2 VME',      0x02,
                    124:       'Carrera',       0x11,
                    125:       'Model 25',      0x12,
                    126:       'Sirius',                0x13,
                    127:       'Prism',         0x14,
                    128:       'Ferrari',       0x17,
                    129:       'Sun3E',         0x18,
                    130:       'Sunrise',       0x21,
                    131:       'Cobra',         0x22,
                    132:       'Stingray',      0x23,
                    133:       'Sunray',                0x24,
                    134:       'Roadrunner',    0x31,
1.1.1.2 ! root      135:       'Roadrunner-MB1',        0x3a,
1.1       root      136:       'Pegasus',       0x41,
                    137:       'Hydra',         0x42,
                    138:       'Campus',                0x51,
                    139:       'Phoenix',       0x52,
                    140:       'Campus B',      0x53,
                    141:       'Off-Campus',    0x54,
                    142:       'Calvin',                0x55,
                    143:       'Node Warrior',  0x56,
                    144:       'Hobbes',                0x57,
                    145:       'Polaris',       0x61,
                    146:       'Galaxy',                0x71,
                    147:       'Campus-2',      0x72,
                    148:       'Kodiak',                0x72,
                    149:       'Sunergy',       0x80,
                    150:       'Gypsy',         0x80,
                    151:       'Aurora',                0x80,
                    152:       'Perigee',       0x80,
                    153:       );
                    154: %codename_machtype = @codename_machtype;
                    155: 
                    156: # mapping from Sun code name to sometime during the
                    157: # shipping/availability period, if known, for those machines that
                    158: # shipped with a real manufacture date in the IDPROM:
                    159: %codename_shipping =
                    160:     ( 'sun2 Multibus', 457370182,
                    161:       'Carrera',       587239630,
                    162:       'Ferrari',       564526348,
                    163:       );
                    164: 
                    165: # if our standard input is not a terminal, assume we're checking an IDPROM there:
                    166: unless (-t STDIN) {
                    167:     
                    168:     # read in the IDPROM:
                    169:     $size = sysread(STDIN, $idprom, 32);
                    170:     if ($size != 32) {
                    171:        print STDERR "fatal: IDPROM has wrong size ($size), must be exactly 32\n";
                    172:        exit(1);
                    173:     }
                    174: 
                    175:     # unpack the IDPROM:
                    176:     ($format, 
                    177:      $machtype,
                    178:      $ether0, 
                    179:      $ether1, 
                    180:      $ether2, 
                    181:      $ether3, 
                    182:      $ether4, 
                    183:      $ether5, 
                    184:      $date, 
                    185:      $serial_and_cksum) = 
                    186:        (unpack("C C C6 N N", $idprom));
                    187:     $serial = ($serial_and_cksum >> 8);
                    188: 
                    189:     # check the format:
                    190:     if ($format != 1) {
                    191:        print "warning: IDPROM has invalid format byte ($format), must be 1\n";
                    192:     }
                    193: 
                    194:     # check the checksum, which only covers the first 16 bytes:
                    195:     @bytes = (unpack("C16", $idprom));
                    196:     $cksum_old = pop(@bytes);
                    197:     $cksum_new = 0;
                    198:     foreach $byte (@bytes) {
                    199:        $cksum_new ^= $byte;
                    200:     }
                    201:     if ($cksum_new != $cksum_old) {
                    202:        print "warning: IDPROM has bad cksum ";
                    203:        print sprintf("(0x%02x)", $cksum_old);
                    204:        print ", should be ";
                    205:        print sprintf("0x%02x", $cksum_new);
                    206:        print "\n";
                    207:     }
                    208: 
                    209:     # turn the machine type into a set of code names and machines:
                    210:     @codenames = ();
                    211:     @machines = ();
                    212:     for ($i = 0; $i < @codename_machtype; $i += 2) {
                    213:        if ($codename_machtype[$i + 1] == $machtype) {
                    214:            $codename = $codename_machtype[$i + 0];
                    215:            push (@codenames, $codename);
                    216:            @codename_machines = ();
                    217:            for ($j = 0; $j < @machine_codename; $j += 2) {
                    218:                if ($machine_codename[$j + 1] eq $codename) {
                    219:                    $machine = $machine_codename[$j + 0];
                    220:                    if ($machine =~ /^\*(.*)$/) {
                    221:                        push (@codename_machines, $1);
                    222:                        last;
                    223:                    }
                    224:                    else {
                    225:                        push(@codename_machines, $machine);
                    226:                    }
                    227:                }
                    228:            }
                    229:            if (@codename_machines > 2) {
                    230:                $codename_machines[$#codename_machines] = "or ".$codename_machines[$#codename_machines];
                    231:                $codename_machines = join(", ", @codename_machines);
                    232:            }
                    233:            elsif (@codename_machines == 2) {
                    234:                $codename_machines = join(" or ", @codename_machines);
                    235:            }
                    236:            else {
                    237:                $codename_machines = $codename_machines[0];
                    238:            }
                    239:            push(@machines, $codename_machines);
                    240:        }
                    241:     }
                    242:     
                    243:     # display a PROM-like banner:
                    244:     if (@codenames == 0) {
                    245:        print "warning: IDPROM has unknown machine type ";
                    246:        print sprintf("(0x%02x)", $machtype);
                    247:        print "\n";
                    248:     }
                    249:     elsif (@codenames == 1) {
                    250:        $codename = $codenames[0];
                    251:        $machines = $machines[0];
                    252:        if ($machines =~ /^\d+i?\//
                    253:            || $machines =~ / or /) {
                    254:            print "Sun Workstation, Model ";
                    255:        }
                    256:        print $machines;
                    257:        print " (codename \"$codename\")" unless ($codename =~ /^sun2/);
                    258:        print "\n";
                    259:     }
                    260:     else {
                    261:        print "Sun Workstation, Model ";
                    262:        for ($i = 0; $i < @codenames; $i++) {
                    263:            $codename = $codenames[$i];
                    264:            $machines[$i] .= " (codename \"$codename\")"
                    265:                unless ($codename =~ /^sun2/);
                    266:        }
                    267:        print join((@codenames == 2 ? " or " : ", or "), @machines);
                    268:        print "\n";
                    269:     }
                    270:     print "Serial \#$serial, Ethernet address";
                    271:     $sep = ' ';
                    272:     foreach $byte ($ether0, $ether1, $ether2, $ether3, $ether4, $ether5) {
                    273:        print $sep.sprintf("%x", $byte);
                    274:        $sep = ':';
                    275:     }
                    276:     print "\n";
                    277:     print "Manufacture date ".gmtime($date)."\n";
                    278: }
                    279: 
                    280: # otherwise, we're generating a new IDPROM:
                    281: else {
                    282:     
                    283:     # check our command line:
                    284:     $usage = 0;
                    285: 
                    286:     # the machine or code name:
                    287:     if (@ARGV == 0) {
                    288:        print STDERR "missing machine name\n";
                    289:        $usage = 1;
                    290:     }
                    291:     else {
                    292:        $name = shift(@ARGV);
                    293:        if (defined($codename_machtype{$name})) {
                    294:            $codename = $name;
                    295:        }
                    296:        else {
                    297:            # this should be a machine name:
                    298:            $codename = $machine_codename{$name};
                    299:            if (!defined($codename)) {
                    300:                $codename = $machine_codename{"*$name"};
                    301:            }
                    302:            if (!defined($codename)) {
                    303:                print STDERR "unknown machine name '$name'\n";
                    304:                $usage = 1;
                    305:            }
                    306:        }
                    307:     }
                    308:     
                    309:     # the Ethernet address:
                    310:     if (@ARGV == 0) {
                    311:        print STDERR "missing Ethernet address\n";
                    312:        $usage = 1;
                    313:     }
                    314:     else {
                    315:        $ether = shift(@ARGV);
                    316:        @ether = split(/:/, $ether);
                    317:        unless ($ether =~ /^[0-9a-fA-F:]+/
                    318:                && @ether == 6) {
                    319:            print STDERR "bad Ethernet address '$ether'\n";
                    320:            $usage = 1;
                    321:        }
                    322:     }
                    323: 
                    324:     # the optional serial number:
                    325:     if (@ARGV > 0) {
                    326:        $serial = shift(@ARGV);
                    327:        unless ($serial =~ /^\d+$/) {
                    328:            print STDERR "bad serial number '$serial'\n";
                    329:            $usage = 1;
                    330:        }
                    331:     }
                    332:     else {
                    333:        $serial = 1 + int(rand(100000));
                    334:     }
                    335: 
                    336:     # standard output must not be a terminal:
                    337:     if (-t STDOUT) {
                    338:        print STDERR "standard output must not be a terminal\n";
                    339:        $usage = 1;
                    340:     }
                    341: 
                    342:     # any other arguments are unexpected:
                    343:     if (@ARGV > 0) {
                    344:        print STDERR "unexpected argument '$ARGV[0]'\n";
                    345:        $usage = 1;
                    346:     }
                    347: 
                    348:     if ($usage) {
                    349:        print STDERR "usage: $0 MACHINE ETHERNET [ SERIAL ] > IDPROM\n";
                    350:        print STDERR "       $0 < IDPROM\n";
                    351:        exit(1);
                    352:     }
                    353: 
                    354:     # start the IDPROM:
                    355:     $idprom = "";
                    356: 
                    357:     # add in the format byte:
                    358:     $idprom .= pack("C", 1);
                    359: 
                    360:     # add in the machine type:
                    361:     $machtype = $codename_machtype{$codename};
                    362:     if (!defined($machtype)) {
                    363:        die "internal error - machtype byte for codename $codename missing\n";
                    364:     }
                    365:     $idprom .= pack("C", $machtype);
                    366: 
                    367:     # add in the ethernet address:
                    368:     foreach $byte (@ether) {
                    369:        $byte = hex($byte);
                    370:        $idprom .= pack("C", $byte);
                    371:     }
                    372:     if ($ether[0] != 0x08
                    373:        || $ether[1] != 0x00
                    374:        || $ether[2] != 0x20) {
                    375:        print STDERR "warning: Ethernet address $ether doesn't begin with Sun's OUI 8:0:20\n";
                    376:     }
                    377: 
                    378:     # add in a date, if possible:
                    379:     $date = $codename_shipping{$codename};
                    380:     if (defined($date)) {
                    381:        # smear the date within 30 days of the known date:
                    382:        $date += (int(rand(60)) - 30) * (24 * 60 * 60);
                    383:     }
                    384:     else {
                    385:        $date = 0;
                    386:     }
                    387:     $idprom .= pack("N", $date);
                    388: 
                    389:     # add in the serial number:
                    390:     $idprom .= substr(pack("N", $serial), 1);
                    391:     
                    392:     # calculate the checksum:
                    393:     @bytes = (unpack("C*", $idprom));
                    394:     $cksum_new = 0;
                    395:     foreach $byte (@bytes) {
                    396:        $cksum_new ^= $byte;
                    397:     }
                    398:     $idprom .= pack("C", $cksum_new);
                    399: 
                    400:     # add the extra 16 bytes:
                    401:     $idprom .= pack("NNNN", 0, 0, 0, 0);
                    402: 
                    403:     # dump out the IDPROM:
                    404:     print $idprom;
                    405: }
                    406: 
                    407: # done:
                    408: exit(0);
                    409:     

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.