]> git.ipfire.org Git - thirdparty/lldpd.git/blob - src/daemon/dmi-osx.c
Be more defensive when parsing PRETTY_NAME out of os-release
[thirdparty/lldpd.git] / src / daemon / dmi-osx.c
1 /* -*- mode: c; c-file-style: "openbsd" -*- */
2 /*
3 * Copyright (c) 2012 Vincent Bernat <bernat@luffy.cx>
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18 #include "lldpd.h"
19
20 #include <CoreFoundation/CoreFoundation.h>
21 #include <IOKit/IOKitLib.h>
22
23 #ifdef ENABLE_LLDPMED
24 static char *
25 dmi_get(const char *classname, CFStringRef property)
26 {
27 char *result = NULL;
28 CFMutableDictionaryRef matching = NULL;
29 CFTypeRef cfres = NULL;
30 io_service_t service = 0;
31 matching = IOServiceMatching(classname);
32 if (!matching) {
33 log_debug("localchassis", "cannot get %s class from registry",
34 classname);
35 goto end;
36 }
37 service = IOServiceGetMatchingService(kIOMasterPortDefault, matching);
38 if (!service) {
39 log_warnx("localchassis", "cannot get matching %s class from registry",
40 classname);
41 goto end;
42 }
43 cfres = IORegistryEntryCreateCFProperty(service, property, kCFAllocatorDefault,
44 kNilOptions);
45 if (!cfres) {
46 log_debug("localchassis",
47 "cannot find property %s in class %s in registry",
48 CFStringGetCStringPtr(property, kCFStringEncodingMacRoman),
49 classname);
50 goto end;
51 }
52
53 if (CFGetTypeID(cfres) == CFStringGetTypeID())
54 result = strdup(CFStringGetCStringPtr((CFStringRef)cfres,
55 kCFStringEncodingMacRoman));
56 else if (CFGetTypeID(cfres) == CFDataGetTypeID()) {
57 /* OK, we know this is a string. */
58 result = calloc(1, CFDataGetLength((CFDataRef)cfres) + 1);
59 if (!result) goto end;
60 memcpy(result, CFDataGetBytePtr((CFDataRef)cfres),
61 CFDataGetLength((CFDataRef)cfres));
62 } else
63 log_debug("localchassis", "unknown type for property %s in class %s",
64 CFStringGetCStringPtr(property, kCFStringEncodingMacRoman),
65 classname);
66
67 end:
68 if (cfres) CFRelease(cfres);
69 if (service) IOObjectRelease(service);
70 return result;
71 }
72
73 char *
74 dmi_hw()
75 {
76 return dmi_get("IOPlatformExpertDevice", CFSTR("version"));
77 }
78
79 char *
80 dmi_fw()
81 {
82 /* Dunno where it is. Maybe in SMC? */
83 return NULL;
84 }
85
86 char *
87 dmi_sn()
88 {
89 return dmi_get("IOPlatformExpertDevice", CFSTR("IOPlatformSerialNumber"));
90 }
91
92 char *
93 dmi_manuf()
94 {
95 return dmi_get("IOPlatformExpertDevice", CFSTR("manufacturer"));
96 }
97
98 char *
99 dmi_model()
100 {
101 return dmi_get("IOPlatformExpertDevice", CFSTR("model"));
102 }
103
104 char *
105 dmi_asset()
106 {
107 return dmi_get("IOPlatformExpertDevice", CFSTR("board-id"));
108 }
109 #endif