Advertisement
Guest User

dieid.c - Get die ID / generate random strings on Gumstix.

a guest
Oct 23rd, 2013
118
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.06 KB | None | 0 0
  1. /* dieid.c:
  2.  *   Tool to get die ID from Gumstix and to generate random strings from it.
  3.  *
  4.  * Copyright (C) 2013 Jason Cipriani, jason.cipriani@gmail.com
  5.  *
  6.  * If redistributed in source form please include this notice and the entire
  7.  * source. If source is modified, a note must be added identifying the
  8.  * author of the modifications.
  9.  *
  10.  * If redistributed in binary form, no attribution is required.
  11.  *
  12.  * This program can be used for any purpose. It is provided as-is and the
  13.  * author is not responsible for any damage resulting from the use of this
  14.  * software.
  15.  *
  16.  * Tested only on Gumstix Overo WaterSTORM COM.
  17.  */
  18.  
  19. #include <fcntl.h>
  20. #include <stdio.h>
  21. #include <stdlib.h>
  22. #include <string.h>
  23. #include <sys/mman.h>
  24. #include <sys/stat.h>
  25. #include <sys/types.h>
  26. #include <unistd.h>
  27.  
  28. /* these may or may not be appropriate for all platforms... */
  29. #define DIEID_OFFSET ((off_t)0x4830A218)
  30. #define DIEID_LENGTH ((size_t)16)
  31.  
  32.  
  33. /**
  34.  * read dieid from /dev/mem.
  35.  * @param dieid buffer to store result on success.
  36.  * @return 0 on success, non-zero on error. prints message stderr on error.
  37.  */
  38. int read_dieid (unsigned char dieid[DIEID_LENGTH]) {
  39.  
  40.   int f, n;
  41.   size_t pagesize, length;
  42.   off_t start, dieaddr;
  43.   void *m;
  44.  
  45.   if ((pagesize = sysconf(_SC_PAGESIZE)) == (size_t)-1) {
  46.     perror("sysconf");
  47.     return 1;
  48.   }
  49.  
  50.   /* calculate page-aligned start and min # of pages required to get the id. */
  51.   start = pagesize * (off_t)(DIEID_OFFSET / pagesize);
  52.   dieaddr = DIEID_OFFSET - start;
  53.   length = pagesize * (off_t)(1 + (DIEID_LENGTH - 1) / pagesize);
  54.  
  55.   if ((f = open("/dev/mem", O_RDONLY)) < 0) {
  56.     perror("/dev/mem");
  57.     return 1;
  58.   }
  59.  
  60.   if ((m = mmap(NULL, length, PROT_READ, MAP_SHARED, f, start)) == (void *)-1) {
  61.     perror("mmap");
  62.     close(f);
  63.     return 1;
  64.   }
  65.  
  66.   /* bytes in memory are reversed from what u-boot prints on boot. */
  67.   for (n = 0; n < (int)DIEID_LENGTH; ++ n)
  68.     dieid[n] = ((const unsigned char *)m)[dieaddr + DIEID_LENGTH - n - 1];
  69.  
  70.   munmap(m, length);
  71.   close(f);
  72.   return 0;
  73.  
  74. }
  75.  
  76.  
  77. /**
  78.  * replace all ^ in template with random hex digit and print it. we use libc's
  79.  * srand/rand. for libc independence or consistency, implement your own.
  80.  * @param dieid die id, used as random seed.
  81.  * @param template template string.
  82.  */
  83. void gen_template (const unsigned char dieid[DIEID_LENGTH], const char *template, int salt) {
  84.  
  85.   static const char hex[16] = "0123456789abcdef";
  86.   unsigned long seed = 0, value = 0;
  87.   int n;
  88.  
  89.   for (n = 0; n < (int)DIEID_LENGTH - 4; n += 4)
  90.     seed += *(unsigned long *)(dieid + n);
  91.   srand(seed + salt);
  92.  
  93.   while (*template) {
  94.     if (*template == '^') {
  95.       if (value == 0)
  96.     value = rand();
  97.       putchar(hex[value & 15]);
  98.       value >>= 4;
  99.     } else {
  100.       putchar(*template);
  101.     }
  102.     ++ template;
  103.   }
  104.  
  105.   putchar('\n');
  106.  
  107. }
  108.  
  109.  
  110. int main (int argc, char **argv) {
  111.  
  112.   int salt = 0;
  113.   const char *template = NULL;
  114.   unsigned char dieid[DIEID_LENGTH];
  115.  
  116.   /** very basic arg parse. */
  117.   if ((argc == 3 || argc == 4) && !strcmp(argv[1], "-m")) {
  118.     template = argv[2];
  119.     salt = (argc > 3) ? atoi(argv[3]) : 0;
  120.   } else if (argc != 1) {
  121.     fprintf(stderr, "usage: %s [ -m template [ salt ] ]\n\n", argv[0]);
  122.     fprintf(stderr, "  no options: prints die id.\n");
  123.     fprintf(stderr, "  -m template: replace all '^' in template with random hex digit.\n");
  124.     fprintf(stderr, "               salt is an integer to produce different random output.\n\n");
  125.     fprintf(stderr, "example: generate mac address with prefix:\n");
  126.     fprintf(stderr, "  %s -m ab:cd:ef:^^:^^:^^\n\n", argv[0]);
  127.     fprintf(stderr, "example: generate two random macs:\n");
  128.     fprintf(stderr, "  %s -m ^^:^^:^^:^^:^^:^^ 1\n", argv[0]);
  129.     fprintf(stderr, "  %s -m ^^:^^:^^:^^:^^:^^ 2\n\n", argv[0]);
  130.     return 1;
  131.   }
  132.  
  133.   if (read_dieid(dieid))
  134.     return 1;
  135.  
  136.   if (template)
  137.     gen_template(dieid, template, salt);
  138.   else {
  139.     int n;
  140.     for (n = 0; n < (int)DIEID_LENGTH; ++ n)
  141.       printf("%02x", (unsigned)dieid[n]);
  142.     putchar('\n');
  143.   }
  144.  
  145.   return 0;
  146.  
  147. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement