Package: hw-detect

Version: 1.107


Attached are changes to add a utility that detects if we are running in a 
VMware VM, and add open-vm-tools to the list of packages to be installed. 
Please consider adding it to hw-detect.



Thanks,

Oliver




diff --git a/.gitignore b/.gitignore
index e2df58f..b53d8af 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,6 +2,7 @@ build-stamp
 configure-stamp
 archdetect
 archdetect-deb
+checkvm
 *.o
 devnames-static.gz
 
diff --git a/Makefile b/Makefile
index 88a7582..ca5c70d 100644
--- a/Makefile
+++ b/Makefile
@@ -37,7 +37,7 @@ man1dir=$(DESTDIR)/usr/share/man/man1
 INSTALL=install
 INSTALL_DATA = ${INSTALL} -m 644
 
-all: archdetect devnames-static.gz
+all: checkvm archdetect devnames-static.gz
 
 test:
 	set -e; for sh in *.sh; do sh -n $$sh; done
@@ -46,9 +46,10 @@ clean:
 	rm -f *~
 	rm -f *.o
 	rm -f archdetect
+	rm -f checkvm
 	rm -f devnames-static.gz
 
-install: install-hw-detect install-ethdetect install-disk-detect install-driver-injection-disk-detect install-archdetect install-archdetect-deb
+install: install-hw-detect install-ethdetect install-disk-detect install-driver-injection-disk-detect install-archdetect install-archdetect-deb install-checkvm
 
 install-hw-detect: hw-detect.sh
 	$(INSTALL) -d $(bindir)
@@ -79,6 +80,12 @@ endif
 else
 	$(INSTALL) detect-stub.sh $(bindir)/hw-detect
 endif
+ifeq ($(DEB_HOST_ARCH),i386)
+	$(INSTALL) checkvm $(bindir)
+endif
+ifeq ($(DEB_HOST_ARCH),amd64)
+	$(INSTALL) checkvm $(bindir)
+endif
 
 install-ethdetect: ethdetect.sh
 	$(INSTALL) -d $(bindir) $(netdir)
@@ -97,6 +104,7 @@ install-archdetect: archdetect
 	$(INSTALL) -d $(bindir)
 	$(INSTALL) archdetect $(bindir)
 
+
 install-archdetect-deb: archdetect
 	$(INSTALL) -d $(bindir)
 	$(INSTALL) archdetect $(bindir)
@@ -109,5 +117,11 @@ archdetect: archdetect.o
 archdetect.o: %.o:%.c
 	$(CC) $(CPPFLAGS) $(CFLAGS) $(CFLAGS_ARCH) -c $<
 
+checkvm: checkvm.o 
+	${CC} ${LDFLAGS} -o $@ $^
+
+checkvm.o: %.o:%.c
+	$(CC) $(CPPFLAGS) $(CFLAGS) $(CFLAGS_ARCH) -c $<
+
 devnames-static.gz: devnames-static.txt
 	grep -v '^#' $< | gzip -9c > $@
diff --git a/checkvm.c b/checkvm.c
new file mode 100644
index 0000000..5e017b0
--- /dev/null
+++ b/checkvm.c
@@ -0,0 +1,146 @@
+#include <string.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <setjmp.h>
+
+
+#define OC_CPU_X86_MMX      (1<<0)
+#define OC_CPU_X86_3DNOW    (1<<1)
+#define OC_CPU_X86_3DNOWEXT (1<<2)
+#define OC_CPU_X86_MMXEXT   (1<<3)
+#define OC_CPU_X86_SSE      (1<<4)
+#define OC_CPU_X86_SSE2     (1<<5)
+#define OC_CPU_X86_PNI      (1<<6)
+#define OC_CPU_X86_SSSE3    (1<<7)
+#define OC_CPU_X86_SSE4_1   (1<<8)
+#define OC_CPU_X86_SSE4_2   (1<<9)
+#define OC_CPU_X86_SSE4A    (1<<10)
+#define OC_CPU_X86_SSE5     (1<<11)
+#define OC_CPU_PPC_ALTIVEC  (1<<12)
+
+
+typedef unsigned int ogg_uint32_t;
+
+#if defined(i386) || defined(__x86_64__) || defined(_M_IX86) || defined(_M_AMD64)
+# if !defined(_MSC_VER)
+#  if defined(__amd64__)||defined(__x86_64__)
+/*On x86-64, gcc seems to be able to figure out how to save %rbx for us when
+   compiling with -fPIC.*/
+#   define cpuid(_op,_eax,_ebx,_ecx,_edx) \
+  __asm__ __volatile__( \
+   "cpuid\n\t" \
+   :[eax]"=a"(_eax),[ebx]"=b"(_ebx),[ecx]"=c"(_ecx),[edx]"=d"(_edx) \
+   :"a"(_op) \
+   :"cc" \
+  )
+#  else
+/*On x86-32, not so much.*/
+#   define cpuid(_op,_eax,_ebx,_ecx,_edx) \
+  __asm__ __volatile__( \
+   "xchgl %%ebx,%[ebx]\n\t" \
+   "cpuid\n\t" \
+   "xchgl %%ebx,%[ebx]\n\t" \
+   :[eax]"=a"(_eax),[ebx]"=r"(_ebx),[ecx]"=c"(_ecx),[edx]"=d"(_edx) \
+   :"a"(_op) \
+   :"cc" \
+  )
+#  endif
+#  endif
+#  endif
+
+int cpuid_check()
+{
+	ogg_uint32_t eax;
+	ogg_uint32_t ebx;
+	ogg_uint32_t ecx;
+	ogg_uint32_t edx;
+        char hyper_vendor_id[13];
+
+        cpuid(0x1, eax, ebx, ecx, edx);
+//        if  (bit 31 of ecx is set) {
+	if (ecx & (1 << 30)) {
+                cpuid(0x40000000, eax, ebx, ecx, edx);
+                memcpy(hyper_vendor_id + 0, &ebx, 4);
+                memcpy(hyper_vendor_id + 4, &ecx, 4);
+                memcpy(hyper_vendor_id + 8, &edx, 4);
+                hyper_vendor_id[12] = '\0';
+                if (!strcmp(hyper_vendor_id, "VMwareVMware"))
+                        return 1;               // Success - running under VMware
+        }
+        return 0;
+}
+
+#define DMI_BIOS_SERIAL_PATH "/sys/devices/virtual/dmi/id/product_serial"
+
+int get_bios_serial(char *buf)
+{
+	FILE *fptr;
+
+	if ((fptr = fopen(DMI_BIOS_SERIAL_PATH, "rt"))) {
+		int cnt;
+		cnt = fread(buf, 10, 1, fptr);
+		if (cnt < 0) {
+			return 1;
+		}
+		fclose(fptr);
+	}
+	return 0;
+}
+
+int dmi_check(void)
+{
+        char string[10];
+        get_bios_serial(string);
+
+        if (!memcmp(string, "VMware-", 7) || !memcmp(string, "VMW", 3))
+                return 1;                       // DMI contains VMware specific string.
+        else
+                return 0;
+}
+
+#define VMWARE_HYPERVISOR_MAGIC 0x564D5868
+#define VMWARE_HYPERVISOR_PORT  0x5658
+
+#define VMWARE_PORT_CMD_GETVERSION      10
+
+#define UINT_MAX 0xffffffff
+
+#define VMWARE_PORT(cmd, eax, ebx, ecx, edx)                            \
+        __asm__("inl (%%dx)" :                                          \
+                        "=a"(eax), "=c"(ecx), "=d"(edx), "=b"(ebx) :    \
+                        "0"(VMWARE_HYPERVISOR_MAGIC),                   \
+                        "1"(VMWARE_PORT_CMD_##cmd),                     \
+                        "2"(VMWARE_HYPERVISOR_PORT), "3"(UINT_MAX) :    \
+                        "memory");
+
+int hypervisor_port_check(void)
+{
+//        uint32_t eax, ebx, ecx, edx;
+        unsigned int eax, ebx, ecx, edx;
+        VMWARE_PORT(GETVERSION, eax, ebx, ecx, edx);
+        if (ebx == VMWARE_HYPERVISOR_MAGIC)
+                return 1;               // Success - running under VMware
+        else
+                return 0;
+}
+
+int Detect_VMware(void)
+{
+        if (cpuid_check()) {
+		printf("detected vm by cpu id\n");
+                return 1;               // Success running under VMware.
+	} else if (dmi_check() && hypervisor_port_check()) {
+		printf("detected vm by hypervisor port\n");
+                return 2;
+	}
+	printf("not running in a vm\n");
+        return 0;
+}
+
+int main()
+{
+	exit(Detect_VMware() ? EXIT_SUCCESS : EXIT_FAILURE);
+}
+
diff --git a/hw-detect.sh b/hw-detect.sh
index 6f16a52..0f8c22e 100755
--- a/hw-detect.sh
+++ b/hw-detect.sh
@@ -531,6 +531,14 @@ case "$(udpkg --print-architecture)" in
 	;;
 esac
 
+case "$(udpkg --print-architecture)" in
+    i386|amd64)
+	if checkvm ; then
+		apt-install open-vm-tools
+	fi
+	;;
+esac
+
 db_progress SET $MAX_STEPS
 db_progress STOP
 

Reply via email to