Annotation of tme/machine/sun/tme-sun-idprom.pl, revision 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.