Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1584418
  • 博文数量: 239
  • 博客积分: 1760
  • 博客等级: 上尉
  • 技术积分: 1595
  • 用 户 组: 普通用户
  • 注册时间: 2011-01-08 23:53
文章分类

全部博文(239)

文章存档

2016年(1)

2015年(28)

2014年(53)

2013年(42)

2012年(50)

2011年(65)

分类: C/C++

2014-09-08 21:53:39

在网上找了好长时间关于获取CPUID的代码,都不是完全版本,回去还得改,自己写好了,是借鉴dmidecode中的代码成完的,希望多多提意见,谢谢。
这样做的缺点是必须得有root权限才可以,其它用户的权限是不能进行访问/dev/mem这个文件。
types.h

点击(此处)折叠或打开

  1. #ifndef TYPES_H
  2. #define TYPES_H


  3. typedef unsigned char u8;
  4. typedef unsigned short u16;
  5. typedef signed short i16;
  6. typedef unsigned int u32;

  7. #ifdef BIGENDIAN
  8. typedef struct {
  9.     u32 h;
  10.     u32 l;
  11. } u64;
  12. #else
  13. typedef struct {
  14.     u32 l;
  15.     u32 h;
  16. } u64;
  17. #endif

  18. #ifdef ALIGNMENT_WORKAROUND
  19. static inline u64 U64(u32 low, u32 high)
  20. {
  21.     u64 self;

  22.     self.l = low;
  23.     self.h = high;

  24.     return self;
  25. }
  26. #endif

  27. #ifdef ALIGNMENT_WORKAROUND
  28. #    ifdef BIGENDIAN
  29. #    define WORD(x) (u16)((x)[1] + ((x)[0] << 8))
  30. #    define DWORD(x) (u32)((x)[3] + ((x)[2] << 8) + ((x)[1] << 16) + ((x)[0] << 24))
  31. #    define QWORD(x) (U64(DWORD(x + 4), DWORD(x)))
  32. #    else /* BIGENDIAN */
  33. #    define WORD(x) (u16)((x)[0] + ((x)[1] << 8))
  34. #    define DWORD(x) (u32)((x)[0] + ((x)[1] << 8) + ((x)[2] << 16) + ((x)[3] << 24))
  35. #    define QWORD(x) (U64(DWORD(x), DWORD(x + 4)))
  36. #    endif /* BIGENDIAN */
  37. #else /* ALIGNMENT_WORKAROUND */
  38. #define WORD(x) (u16)(*(const u16 *)(x))
  39. #define DWORD(x) (u32)(*(const u32 *)(x))
  40. #define QWORD(x) (*(const u64 *)(x))
  41. #endif /* ALIGNMENT_WORKAROUND */

  42. #endif


util.h

点击(此处)折叠或打开

  1. #include <sys/types.h>
  2. #include <sys/ioctl.h>
  3. #include <sys/socket.h>
  4. #include <netinet/in.h>
  5. #include <net/if.h>
  6. #include <string.h>

  7. #include "types.h"

  8. struct dmi_header
  9. {
  10.         u8 type;
  11.         u8 length;
  12.         u16 handle;
  13.         u8 *data;
  14. };

  15. int checksum(const u8 *buf, size_t len);
  16. void *mem_chunk(size_t base, size_t len, const char *devmem);
  17. u64 u64_range(u64 start, u64 end);
  18. void to_dmi_header(struct dmi_header *h, u8 *data);
  19. int get_cpuid(char *cpuid);
  20. int get_mac(char* mac);
util.c

点击(此处)折叠或打开

  1. #include <sys/types.h>
  2. #include <sys/stat.h>

  3. #ifdef USE_MMAP
  4. #include <sys/mman.h>
  5. #ifndef MAP_FAILED
  6. #define MAP_FAILED ((void *) -1)
  7. #endif /* !MAP_FAILED */
  8. #endif /* USE MMAP */

  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <unistd.h>
  12. #include <string.h>
  13. #include <fcntl.h>
  14. #include <errno.h>

  15. #include "types.h"
  16. #include "util.h"

  17. static int myread(int fd, u8 *buf, size_t count, const char *prefix)
  18. {
  19.     ssize_t r = 1;
  20.     size_t r2 = 0;

  21.     while (r2 != count && r != 0)
  22.     {
  23.         r = read(fd, buf + r2, count - r2);
  24.         if (r == -1)
  25.         {
  26.             if (errno != EINTR)
  27.             {
  28.                 close(fd);
  29.                 perror(prefix);
  30.                 return -1;
  31.             }
  32.         }
  33.         else
  34.             r2 += r;
  35.     }

  36.     if (r2 != count)
  37.     {
  38.         close(fd);
  39.         fprintf(stderr, "%s: Unexpected end of file\n", prefix);
  40.         return -1;
  41.     }

  42.     return 0;
  43. }

  44. int checksum(const u8 *buf, size_t len)
  45. {
  46.     u8 sum = 0;
  47.     size_t a;

  48.     for (a = 0; a < len; a++)
  49.         sum += buf[a];
  50.     return (sum == 0);
  51. }

  52. /*
  53.  * Copy a physical memory chunk into a memory buffer.
  54.  * This function allocates memory.
  55.  */
  56. void *mem_chunk(size_t base, size_t len, const char *devmem)
  57. {
  58.     void *p;
  59.     int fd;
  60. #ifdef USE_MMAP
  61.     size_t mmoffset;
  62.     void *mmp;
  63. #endif

  64.     if ((fd = open(devmem, O_RDONLY)) == -1)
  65.     {
  66.         perror(devmem);
  67.         return NULL;
  68.     }

  69.     if ((p = malloc(len)) == NULL)
  70.     {
  71.         perror("malloc");
  72.         return NULL;
  73.     }

  74. #ifdef USE_MMAP
  75. #ifdef _SC_PAGESIZE
  76.     mmoffset = base % sysconf(_SC_PAGESIZE);
  77. #else
  78.     mmoffset = base % getpagesize();
  79. #endif /* _SC_PAGESIZE */
  80.     /*
  81.      * Please note that we don't use mmap() for performance reasons here,
  82.      * but to workaround problems many people encountered when trying
  83.      * to read from /dev/mem using regular read() calls.
  84.      */
  85.     mmp = mmap(0, mmoffset + len, PROT_READ, MAP_SHARED, fd, base - mmoffset);
  86.     if (mmp == MAP_FAILED)
  87.         goto try_read;

  88.     memcpy(p, (u8 *)mmp + mmoffset, len);

  89.     if (munmap(mmp, mmoffset + len) == -1)
  90.     {
  91.         fprintf(stderr, "%s: ", devmem);
  92.         perror("munmap");
  93.     }

  94.     goto out;

  95. #endif /* USE_MMAP */

  96. try_read:
  97.     if (lseek(fd, base, SEEK_SET) == -1)
  98.     {
  99.         fprintf(stderr, "%s: ", devmem);
  100.         perror("lseek");
  101.         free(p);
  102.         return NULL;
  103.     }

  104.     if (myread(fd, p, len, devmem) == -1)
  105.     {
  106.         free(p);
  107.         return NULL;
  108.     }

  109. out:
  110.     if (close(fd) == -1)
  111.         perror(devmem);

  112.     return p;
  113. }

  114. void to_dmi_header(struct dmi_header *h, u8 *data)
  115. {
  116.     h->type = data[0];
  117.     h->length = data[1];
  118.     h->handle = WORD(data + 2);
  119.     h->data = data;
  120. }

  121. int get_cpuid(char *cpuid)
  122. {
  123.     char devmem[10] = "/dev/mem";
  124.     u16 len;
  125.     u16 num;
  126.     size_t fp;
  127.     u8 *buf=NULL, *nbuf=NULL, *data, *p;
  128.     int i = 0;
  129.     if ((buf = mem_chunk(0xF0000, 0x10000, devmem)) == NULL)
  130.     {
  131.         free(buf);
  132.         return 0;
  133.     }

  134.     for (fp = 0; fp <= 0xFFF0; fp += 16)
  135.     {
  136.         if(memcmp(buf + fp, "_SM_", 4) == 0 && fp <= 0xFFE0)
  137.         {
  138.             len = WORD(buf + fp + 0x16);
  139.             num = WORD(buf + fp + 0x1C);

  140.             if (!checksum(buf + fp, (buf + fp)[0x05]) || memcmp(buf + fp + 0x10, "_DMI_", 5) != 0 || !checksum(buf + fp + 0x10, 0x0F))
  141.             {
  142.                 free(buf);
  143.                 return 0;
  144.             }
  145.             if ((nbuf = mem_chunk(DWORD(buf + fp + 0x18), len, devmem)) == NULL)
  146.             {
  147.                 fprintf(stderr, "Table is unreachable, sorry.\n");
  148.                 free(buf);
  149.                 free(nbuf);
  150.                 return 0;
  151.             }
  152.             data = nbuf;
  153.             while (i < num && data+4 <= nbuf + len)
  154.             {
  155.                 u8 *next;
  156.                 struct dmi_header h;

  157.                 to_dmi_header(&h, data);

  158.                 if (h.length < 4)
  159.                 {
  160.                     printf("Invalid entry length (%u). DMI table is "
  161.                            "broken! Stop.\n\n", (unsigned int)h.length);
  162.                     free(buf);
  163.                     free(nbuf);
  164.                     return 0;
  165.                 }

  166.                 next = data + h.length;
  167.                 while (next - nbuf + 1 < len && (next[0] != 0 || next[1] != 0))
  168.                     next++;
  169.                 next += 2;
  170.                 if (h.type ==4)
  171.                 {
  172.                     p = h.data + 0x08;
  173.                     //printf("CPUID:%02X%02X%02X%02X%02X%02X%02X%02X\n", p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
  174.                     sprintf(cpuid, "%02X%02X%02X%02X%02X%02X%02X%02X", p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
  175.                     free(buf);
  176.                     free(nbuf);
  177.                     return 1;
  178.                 }
  179.                 data = next;
  180.                 i++;
  181.             }
  182.             fp += 16;
  183.         }
  184.     }
  185.     free(buf);
  186.     free(nbuf);
  187.     return 0;
  188. }

  189. int get_mac(char* mac)
  190. {
  191.     int sockfd;
  192.     struct ifreq tmp;
  193.     char mac_addr[30];

  194.     sockfd = socket(AF_INET, SOCK_STREAM, 0);
  195.     if( sockfd < 0)
  196.     {
  197.         perror("create socket fail\n");
  198.         return -1;
  199.     }

  200.     memset(&tmp,0,sizeof(struct ifreq));
  201.     strncpy(tmp.ifr_name,"eth0",sizeof(tmp.ifr_name)-1);
  202.     if( (ioctl(sockfd,SIOCGIFHWADDR,&tmp)) < 0 )
  203.     {
  204.         printf("mac ioctl error\n");
  205.         return -1;
  206.     }

  207.     sprintf(mac_addr, "%02x%02x%02x%02x%02x%02x",
  208.             (unsigned char)tmp.ifr_hwaddr.sa_data[0],
  209.             (unsigned char)tmp.ifr_hwaddr.sa_data[1],
  210.             (unsigned char)tmp.ifr_hwaddr.sa_data[2],
  211.             (unsigned char)tmp.ifr_hwaddr.sa_data[3],
  212.             (unsigned char)tmp.ifr_hwaddr.sa_data[4],
  213.             (unsigned char)tmp.ifr_hwaddr.sa_data[5]
  214.             );
  215.     close(sockfd);
  216.     memcpy(mac,mac_addr,strlen(mac_addr));

  217.     return 0;
  218. }
getsysinfo.c

点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include "util.h"

  3. int main()
  4. {
  5.     char cpuid[20], mac[20];
  6.     get_cpuid(cpuid);
  7.     printf("CPUID:%s\n", cpuid);
  8.     get_mac(mac);
  9.     printf("MAC:%s\n", mac);
  10.     return 0;
  11. }
Makefile

点击(此处)折叠或打开

  1. # Copyright (C) Zhou Zhongbai 46784314@qq.com
  2. CC = gcc
  3. CFLAGS = -W -Wall -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-qual \
  4. -Wcast-align -Wwrite-strings -Wmissing-prototypes -Winline -Wundef
  5. #CFLAGS += -DBIGENDIAN
  6. #CFLAGS += -DALIGNMENT_WORKAROUND
  7. # When debugging, disable -O2 and enable -g.
  8. CFLAGS += -O2
  9. #CFLAGS += -g
  10. # Pass linker flags here
  11. LDFLAGS =
  12. DESTDIR =
  13. prefix = /usr/local
  14. sbindir = $(prefix)/sbin
  15. mandir = $(prefix)/share/man
  16. man8dir = $(mandir)/man8
  17. docdir = $(prefix)/share/doc/getcpuid
  18. INSTALL := install
  19. INSTALL_DATA := $(INSTALL) -m 644
  20. INSTALL_DIR := $(INSTALL) -m 755 -d
  21. INSTALL_PROGRAM := $(INSTALL) -m 755
  22. RM := rm -f
  23. # BSD make provides $MACHINE, but GNU make doesn't
  24. MACHINE ?= $(shell uname -m 2>/dev/null)
  25. PROGRAMS = getsysinfo
  26. all : $(PROGRAMS)
  27. #
  28. # Programs
  29. #
  30. getsysinfo : getsysinfo.o util.o
  31. $(CC) $(LDFLAGS) getsysinfo.o util.o -o $@
  32. #
  33. # Objects
  34. #
  35. getsysinfo.o : getsysinfo.c util.h
  36. $(CC) $(CFLAGS) -c $< -o $@
  37. util.o : util.c util.h
  38. $(CC) $(CFLAGS) -c $< -o $@
  39. #
  40. # Commands
  41. #
  42. strip : $(PROGRAMS)
  43. strip $(PROGRAMS)
  44. install : install-bin install-man install-doc
  45. uninstall : uninstall-bin uninstall-man uninstall-doc
  46. install-bin : $(PROGRAMS)
  47. $(INSTALL_DIR) $(DESTDIR)$(sbindir)
  48. for program in $(PROGRAMS) ; do \
  49. $(INSTALL_PROGRAM) $$program $(DESTDIR)$(sbindir) ; done
  50. uninstall-bin :
  51. for program in $(PROGRAMS) ; do \
  52. $(RM) $(DESTDIR)$(sbindir)/$$program ; done
  53. install-man :
  54. $(INSTALL_DIR) $(DESTDIR)$(man8dir)
  55. for program in $(PROGRAMS) ; do \
  56. $(INSTALL_DATA) man/$$program.8 $(DESTDIR)$(man8dir) ; done
  57. uninstall-man :
  58. for program in $(PROGRAMS) ; do \
  59. $(RM) $(DESTDIR)$(man8dir)/$$program.8 ; done
  60. install-doc :
  61. $(INSTALL_DIR) $(DESTDIR)$(docdir)
  62. $(INSTALL_DATA) README $(DESTDIR)$(docdir)
  63. $(INSTALL_DATA) CHANGELOG $(DESTDIR)$(docdir)
  64. $(INSTALL_DATA) AUTHORS $(DESTDIR)$(docdir)
  65. uninstall-doc :
  66. $(RM) -r $(DESTDIR)$(docdir)
  67. clean :
  68. $(RM) *.o $(PROGRAMS)

阅读(15215) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~