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

1.1       root        1: #! /usr/pkg/bin/perl -w
                      2: 
                      3: # $Id: tme-sun-idprom.pl,v 1.1 2003/05/18 00:02:24 fredette Exp $
                      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',
                     67:       '386i/150',              'Roadrunner',
                     68:       '386i/250',              'Roadrunner',
                     69:       '3/460',                 'Pegasus',
                     70:       '3/470',                 'Pegasus',
                     71:       '3/480',                 'Pegasus',
                     72:       '3/80',                  'Hydra',
                     73:       '*SPARCStation 1',       'Campus',
                     74:       'SS1',                   'Campus',
                     75:       '4/60',                  'Campus',
                     76:       '*SPARCstation IPC',     'Phoenix',
                     77:       'IPC',                   'Phoenix',
                     78:       '4/40',                  'Phoenix',
                     79:       '*SPARCStation 1+',      'Campus B',
                     80:       'SS1+',                  'Campus B',
                     81:       '4/65',                  'Campus B',
                     82:       '*SPARCstation SLC',     'Off-Campus',
                     83:       'SLC',                   'Off-Campus',
                     84:       '4/20',                  'Off-Campus',
                     85:       '*SPARCStation 2',       'Calvin',
                     86:       'SS2',                   'Calvin',
                     87:       '4/75',                  'Calvin',
                     88:       '*SPARCstation ELC',     'Node Warrior',
                     89:       'ELC',                   'Node Warrior',
                     90:       '4/25',                  'Node Warrior',
                     91:       '*SPARCstation IPX',     'Hobbes',
                     92:       'IPX',                   'Hobbes',
                     93:       '4/50',                  'Hobbes',
                     94:       '*SPARCengine 1',                'Polaris',
                     95:       '4/E',                   'Polaris',
                     96:       '4/600',                 'Galaxy',
                     97:       '4/630',                 'Galaxy',
                     98:       '4/670',                 'Galaxy',
                     99:       '4/690',                 'Galaxy',
                    100:       '*SPARCstation 10',      'Campus-2',
                    101:       'SS10',                  'Campus-2',
                    102:       '*SPARCstation 20',      'Kodiak',
                    103:       'SS20',                  'Kodiak',
                    104:       '*SPARCclassic X',       'Hamlet',
                    105:       'Classic X',             'Hamlet',
                    106:       '4/10',                  'Hamlet',
                    107:       '*SPARCClassic',         'Sunergy',
                    108:       '4/15',                  'Sunergy',
                    109:       'classic',               'Sunergy',
                    110:       '4/30',                  'Sunergy',
                    111:       'SPARCstation LX',       'Sunergy',
                    112:       'LX',                    'Sunergy',
                    113:       'Voyager',               'Gypsy',
                    114:       'SS5',                   'Aurora',
                    115:       'SS4',                   'Perigee',
                    116:       );
                    117: %machine_codename = @machine_codename;
                    118: 
                    119: # mapping from Sun code name to IDPROM machine type byte:
                    120: @codename_machtype = 
                    121:     ( 'sun2 Multibus', 0x01,
                    122:       'sun2 VME',      0x02,
                    123:       'Carrera',       0x11,
                    124:       'Model 25',      0x12,
                    125:       'Sirius',                0x13,
                    126:       'Prism',         0x14,
                    127:       'Ferrari',       0x17,
                    128:       'Sun3E',         0x18,
                    129:       'Sunrise',       0x21,
                    130:       'Cobra',         0x22,
                    131:       'Stingray',      0x23,
                    132:       'Sunray',                0x24,
                    133:       'Roadrunner',    0x31,
                    134:       'Pegasus',       0x41,
                    135:       'Hydra',         0x42,
                    136:       'Campus',                0x51,
                    137:       'Phoenix',       0x52,
                    138:       'Campus B',      0x53,
                    139:       'Off-Campus',    0x54,
                    140:       'Calvin',                0x55,
                    141:       'Node Warrior',  0x56,
                    142:       'Hobbes',                0x57,
                    143:       'Polaris',       0x61,
                    144:       'Galaxy',                0x71,
                    145:       'Campus-2',      0x72,
                    146:       'Kodiak',                0x72,
                    147:       'Sunergy',       0x80,
                    148:       'Gypsy',         0x80,
                    149:       'Aurora',                0x80,
                    150:       'Perigee',       0x80,
                    151:       );
                    152: %codename_machtype = @codename_machtype;
                    153: 
                    154: # mapping from Sun code name to sometime during the
                    155: # shipping/availability period, if known, for those machines that
                    156: # shipped with a real manufacture date in the IDPROM:
                    157: %codename_shipping =
                    158:     ( 'sun2 Multibus', 457370182,
                    159:       'Carrera',       587239630,
                    160:       'Ferrari',       564526348,
                    161:       );
                    162: 
                    163: # if our standard input is not a terminal, assume we're checking an IDPROM there:
                    164: unless (-t STDIN) {
                    165:     
                    166:     # read in the IDPROM:
                    167:     $size = sysread(STDIN, $idprom, 32);
                    168:     if ($size != 32) {
                    169:        print STDERR "fatal: IDPROM has wrong size ($size), must be exactly 32\n";
                    170:        exit(1);
                    171:     }
                    172: 
                    173:     # unpack the IDPROM:
                    174:     ($format, 
                    175:      $machtype,
                    176:      $ether0, 
                    177:      $ether1, 
                    178:      $ether2, 
                    179:      $ether3, 
                    180:      $ether4, 
                    181:      $ether5, 
                    182:      $date, 
                    183:      $serial_and_cksum) = 
                    184:        (unpack("C C C6 N N", $idprom));
                    185:     $serial = ($serial_and_cksum >> 8);
                    186: 
                    187:     # check the format:
                    188:     if ($format != 1) {
                    189:        print "warning: IDPROM has invalid format byte ($format), must be 1\n";
                    190:     }
                    191: 
                    192:     # check the checksum, which only covers the first 16 bytes:
                    193:     @bytes = (unpack("C16", $idprom));
                    194:     $cksum_old = pop(@bytes);
                    195:     $cksum_new = 0;
                    196:     foreach $byte (@bytes) {
                    197:        $cksum_new ^= $byte;
                    198:     }
                    199:     if ($cksum_new != $cksum_old) {
                    200:        print "warning: IDPROM has bad cksum ";
                    201:        print sprintf("(0x%02x)", $cksum_old);
                    202:        print ", should be ";
                    203:        print sprintf("0x%02x", $cksum_new);
                    204:        print "\n";
                    205:     }
                    206: 
                    207:     # turn the machine type into a set of code names and machines:
                    208:     @codenames = ();
                    209:     @machines = ();
                    210:     for ($i = 0; $i < @codename_machtype; $i += 2) {
                    211:        if ($codename_machtype[$i + 1] == $machtype) {
                    212:            $codename = $codename_machtype[$i + 0];
                    213:            push (@codenames, $codename);
                    214:            @codename_machines = ();
                    215:            for ($j = 0; $j < @machine_codename; $j += 2) {
                    216:                if ($machine_codename[$j + 1] eq $codename) {
                    217:                    $machine = $machine_codename[$j + 0];
                    218:                    if ($machine =~ /^\*(.*)$/) {
                    219:                        push (@codename_machines, $1);
                    220:                        last;
                    221:                    }
                    222:                    else {
                    223:                        push(@codename_machines, $machine);
                    224:                    }
                    225:                }
                    226:            }
                    227:            if (@codename_machines > 2) {
                    228:                $codename_machines[$#codename_machines] = "or ".$codename_machines[$#codename_machines];
                    229:                $codename_machines = join(", ", @codename_machines);
                    230:            }
                    231:            elsif (@codename_machines == 2) {
                    232:                $codename_machines = join(" or ", @codename_machines);
                    233:            }
                    234:            else {
                    235:                $codename_machines = $codename_machines[0];
                    236:            }
                    237:            push(@machines, $codename_machines);
                    238:        }
                    239:     }
                    240:     
                    241:     # display a PROM-like banner:
                    242:     if (@codenames == 0) {
                    243:        print "warning: IDPROM has unknown machine type ";
                    244:        print sprintf("(0x%02x)", $machtype);
                    245:        print "\n";
                    246:     }
                    247:     elsif (@codenames == 1) {
                    248:        $codename = $codenames[0];
                    249:        $machines = $machines[0];
                    250:        if ($machines =~ /^\d+i?\//
                    251:            || $machines =~ / or /) {
                    252:            print "Sun Workstation, Model ";
                    253:        }
                    254:        print $machines;
                    255:        print " (codename \"$codename\")" unless ($codename =~ /^sun2/);
                    256:        print "\n";
                    257:     }
                    258:     else {
                    259:        print "Sun Workstation, Model ";
                    260:        for ($i = 0; $i < @codenames; $i++) {
                    261:            $codename = $codenames[$i];
                    262:            $machines[$i] .= " (codename \"$codename\")"
                    263:                unless ($codename =~ /^sun2/);
                    264:        }
                    265:        print join((@codenames == 2 ? " or " : ", or "), @machines);
                    266:        print "\n";
                    267:     }
                    268:     print "Serial \#$serial, Ethernet address";
                    269:     $sep = ' ';
                    270:     foreach $byte ($ether0, $ether1, $ether2, $ether3, $ether4, $ether5) {
                    271:        print $sep.sprintf("%x", $byte);
                    272:        $sep = ':';
                    273:     }
                    274:     print "\n";
                    275:     print "Manufacture date ".gmtime($date)."\n";
                    276: }
                    277: 
                    278: # otherwise, we're generating a new IDPROM:
                    279: else {
                    280:     
                    281:     # check our command line:
                    282:     $usage = 0;
                    283: 
                    284:     # the machine or code name:
                    285:     if (@ARGV == 0) {
                    286:        print STDERR "missing machine name\n";
                    287:        $usage = 1;
                    288:     }
                    289:     else {
                    290:        $name = shift(@ARGV);
                    291:        if (defined($codename_machtype{$name})) {
                    292:            $codename = $name;
                    293:        }
                    294:        else {
                    295:            # this should be a machine name:
                    296:            $codename = $machine_codename{$name};
                    297:            if (!defined($codename)) {
                    298:                $codename = $machine_codename{"*$name"};
                    299:            }
                    300:            if (!defined($codename)) {
                    301:                print STDERR "unknown machine name '$name'\n";
                    302:                $usage = 1;
                    303:            }
                    304:        }
                    305:     }
                    306:     
                    307:     # the Ethernet address:
                    308:     if (@ARGV == 0) {
                    309:        print STDERR "missing Ethernet address\n";
                    310:        $usage = 1;
                    311:     }
                    312:     else {
                    313:        $ether = shift(@ARGV);
                    314:        @ether = split(/:/, $ether);
                    315:        unless ($ether =~ /^[0-9a-fA-F:]+/
                    316:                && @ether == 6) {
                    317:            print STDERR "bad Ethernet address '$ether'\n";
                    318:            $usage = 1;
                    319:        }
                    320:     }
                    321: 
                    322:     # the optional serial number:
                    323:     if (@ARGV > 0) {
                    324:        $serial = shift(@ARGV);
                    325:        unless ($serial =~ /^\d+$/) {
                    326:            print STDERR "bad serial number '$serial'\n";
                    327:            $usage = 1;
                    328:        }
                    329:     }
                    330:     else {
                    331:        $serial = 1 + int(rand(100000));
                    332:     }
                    333: 
                    334:     # standard output must not be a terminal:
                    335:     if (-t STDOUT) {
                    336:        print STDERR "standard output must not be a terminal\n";
                    337:        $usage = 1;
                    338:     }
                    339: 
                    340:     # any other arguments are unexpected:
                    341:     if (@ARGV > 0) {
                    342:        print STDERR "unexpected argument '$ARGV[0]'\n";
                    343:        $usage = 1;
                    344:     }
                    345: 
                    346:     if ($usage) {
                    347:        print STDERR "usage: $0 MACHINE ETHERNET [ SERIAL ] > IDPROM\n";
                    348:        print STDERR "       $0 < IDPROM\n";
                    349:        exit(1);
                    350:     }
                    351: 
                    352:     # start the IDPROM:
                    353:     $idprom = "";
                    354: 
                    355:     # add in the format byte:
                    356:     $idprom .= pack("C", 1);
                    357: 
                    358:     # add in the machine type:
                    359:     $machtype = $codename_machtype{$codename};
                    360:     if (!defined($machtype)) {
                    361:        die "internal error - machtype byte for codename $codename missing\n";
                    362:     }
                    363:     $idprom .= pack("C", $machtype);
                    364: 
                    365:     # add in the ethernet address:
                    366:     foreach $byte (@ether) {
                    367:        $byte = hex($byte);
                    368:        $idprom .= pack("C", $byte);
                    369:     }
                    370:     if ($ether[0] != 0x08
                    371:        || $ether[1] != 0x00
                    372:        || $ether[2] != 0x20) {
                    373:        print STDERR "warning: Ethernet address $ether doesn't begin with Sun's OUI 8:0:20\n";
                    374:     }
                    375: 
                    376:     # add in a date, if possible:
                    377:     $date = $codename_shipping{$codename};
                    378:     if (defined($date)) {
                    379:        # smear the date within 30 days of the known date:
                    380:        $date += (int(rand(60)) - 30) * (24 * 60 * 60);
                    381:     }
                    382:     else {
                    383:        $date = 0;
                    384:     }
                    385:     $idprom .= pack("N", $date);
                    386: 
                    387:     # add in the serial number:
                    388:     $idprom .= substr(pack("N", $serial), 1);
                    389:     
                    390:     # calculate the checksum:
                    391:     @bytes = (unpack("C*", $idprom));
                    392:     $cksum_new = 0;
                    393:     foreach $byte (@bytes) {
                    394:        $cksum_new ^= $byte;
                    395:     }
                    396:     $idprom .= pack("C", $cksum_new);
                    397: 
                    398:     # add the extra 16 bytes:
                    399:     $idprom .= pack("NNNN", 0, 0, 0, 0);
                    400: 
                    401:     # dump out the IDPROM:
                    402:     print $idprom;
                    403: }
                    404: 
                    405: # done:
                    406: exit(0);
                    407:     

unix.superglobalmegacorp.com

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