|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.