Guest User

setmac.c

a guest
Nov 15th, 2018
306
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4.  
  5. static void print_usage()
  6. {
  7.     printf("Usage:\n");
  8.     printf("    setmac [file] [MAC address]\n");
  9.     printf("MAC addresses should be one of two forms:\n");
  10.     printf("    xx:yy:zz:ss:tt:ww\n");
  11.     printf("    xxyyzzssttww\n");
  12. }
  13.  
  14. static int is_hex_value(char value)
  15. {
  16.     if (value >= '0' && value <= '9') return 1;
  17.     if (value >= 'a' && value <= 'f') return 1;
  18.     if (value >= 'A' && value <= 'F') return 1;
  19.     return 0;
  20. }
  21.  
  22. static unsigned char get_hex_value(char value)
  23. {
  24.     if (value >= '0' && value <= '9') return value - '0';
  25.     if (value >= 'a' && value <= 'f') return (value - 'a') + 10;
  26.     if (value >= 'A' && value <= 'F') return (value - 'A') + 10;
  27.     return 0xff;
  28. }
  29.  
  30. static unsigned char get_eeprom_checksum(unsigned short *eeprom)
  31. {
  32.     int checksum = (int)0xffffffa5;
  33.     checksum ^= eeprom[0] & 0x00ff;
  34.     checksum <<= 24;
  35.     checksum >>= 24;
  36.     checksum = (checksum << 1) | ((checksum < 0) ? 1 : 0);
  37.     checksum <<= 24;
  38.     checksum >>= 24;
  39.     for (int i = 1; i < 0x80; i++)
  40.     {
  41.         unsigned char upper = eeprom[i] >> 8;
  42.         unsigned char lower = eeprom[i] & 0x00ff;
  43.         unsigned char xorval = upper ^ lower;
  44.         checksum ^= xorval;
  45.         checksum <<= 24;
  46.         checksum >>= 24;
  47.         checksum = (checksum << 1) | ((checksum < 0) ? 1 : 0);
  48.         checksum <<= 24;
  49.         checksum >>= 24;
  50.     }
  51.  
  52.     return (unsigned char)checksum;
  53. }
  54.  
  55. int main(int argc, char **argv)
  56. {
  57.     if (argc < 3)
  58.     {
  59.         print_usage();
  60.         return 1;
  61.     }
  62.  
  63.     FILE *input = fopen(argv[1], "rb");
  64.     if (!input)
  65.     {
  66.         fprintf(stderr, "Unable to open file %s for reading.\n", argv[1]);
  67.         return 1;
  68.     }
  69.  
  70.     fseek(input, 0, SEEK_END);
  71.     long file_size = ftell(input);
  72.     fseek(input, 0, SEEK_SET);
  73.     if (file_size != 0x100)
  74.     {
  75.         fprintf(stderr, "File %s does not appear to be a 93C56 EEPROM dump.\n", argv[1]);
  76.         fclose(input);
  77.         return 1;
  78.     }
  79.  
  80.     int length = strlen(argv[2]);
  81.     if (length != 12 && length != 17)
  82.     {
  83.         fprintf(stderr, "'%s' does not appear to be a MAC address.\n", argv[2]);
  84.         print_usage();
  85.         fclose(input);
  86.         return 1;
  87.     }
  88.  
  89.     unsigned char mac[6];
  90.     int mac_pos = 0;
  91.     int upper_nybble = 1;
  92.     for (int i = 0; i < length; i++)
  93.     {
  94.         if (argv[2][i] == ':') continue;
  95.  
  96.         if (!is_hex_value(argv[2][i]))
  97.         {
  98.             fprintf(stderr, "'%c' is not a hexadecimal value.\n", argv[2][i]);
  99.             print_usage();
  100.             fclose(input);
  101.             return 1;
  102.         }
  103.  
  104.         if (upper_nybble)
  105.         {
  106.             mac[mac_pos] = get_hex_value(argv[2][i]) << 4;
  107.         }
  108.         else
  109.         {
  110.             mac[mac_pos] |= get_hex_value(argv[2][i]);
  111.             mac_pos++;
  112.         }
  113.  
  114.         upper_nybble = !upper_nybble;
  115.     }
  116.  
  117.     unsigned short eeprom[0x80];
  118.     for (int i = 0; i < 0x80; i++)
  119.     {
  120.         unsigned char upper = 0;
  121.         unsigned char lower = 0;
  122.         fread(&lower, 1, 1, input);
  123.         fread(&upper, 1, 1, input);
  124.         eeprom[i] = (upper << 8) | lower;
  125.     }
  126.     fclose(input);
  127.  
  128.     eeprom[0x7d] = (mac[0] << 8) | mac[1];
  129.     eeprom[0x7e] = (mac[2] << 8) | mac[3];
  130.     eeprom[0x7f] = (mac[4] << 8) | mac[5];
  131.  
  132.     unsigned char checksum = get_eeprom_checksum(eeprom);
  133.     eeprom[0x00] &= 0x00ff;
  134.     eeprom[0x00] |= checksum << 8;
  135.  
  136.     input = fopen(argv[1], "wb");
  137.     if (!input)
  138.     {
  139.         fprintf(stderr, "Unable to open file %s for writing. Check that it is not write-protected.\n", argv[1]);
  140.         return 1;
  141.     }
  142.     for (int i = 0; i < 0x80; i++)
  143.     {
  144.         unsigned char upper = eeprom[i] >> 8;
  145.         unsigned char lower = (unsigned char)eeprom[i];
  146.         fwrite(&lower, 1, 1, input);
  147.         fwrite(&upper, 1, 1, input);
  148.     }
  149.     fclose(input);
  150.  
  151.     printf("MAC set successfully.\n");
  152.     return 0;
  153. }
RAW Paste Data