Define and use an OS enumeration type
This commit is contained in:
@@ -24,6 +24,18 @@
|
|||||||
|
|
||||||
typedef struct private_os_info_t private_os_info_t;
|
typedef struct private_os_info_t private_os_info_t;
|
||||||
|
|
||||||
|
ENUM(os_type_names, OS_TYPE_UNKNOWN, OS_TYPE_ANDROID,
|
||||||
|
"Unknown",
|
||||||
|
"Debian",
|
||||||
|
"Ubuntu",
|
||||||
|
"Fedora",
|
||||||
|
"Red Hat",
|
||||||
|
"CentOS",
|
||||||
|
"SUSE",
|
||||||
|
"Gentoo",
|
||||||
|
"Android"
|
||||||
|
);
|
||||||
|
|
||||||
ENUM(os_fwd_status_names, OS_FWD_DISABLED, OS_FWD_UNKNOWN,
|
ENUM(os_fwd_status_names, OS_FWD_DISABLED, OS_FWD_UNKNOWN,
|
||||||
"disabled",
|
"disabled",
|
||||||
"enabled",
|
"enabled",
|
||||||
@@ -41,6 +53,11 @@ struct private_os_info_t {
|
|||||||
*/
|
*/
|
||||||
os_info_t public;
|
os_info_t public;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OS type
|
||||||
|
*/
|
||||||
|
os_type_t type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* OS name
|
* OS name
|
||||||
*/
|
*/
|
||||||
@@ -53,6 +70,12 @@ struct private_os_info_t {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
METHOD(os_info_t, get_type, os_type_t,
|
||||||
|
private_os_info_t *this)
|
||||||
|
{
|
||||||
|
return this->type;
|
||||||
|
}
|
||||||
|
|
||||||
METHOD(os_info_t, get_name, chunk_t,
|
METHOD(os_info_t, get_name, chunk_t,
|
||||||
private_os_info_t *this)
|
private_os_info_t *this)
|
||||||
{
|
{
|
||||||
@@ -190,7 +213,7 @@ typedef struct {
|
|||||||
enumerator_t public;
|
enumerator_t public;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* streamed pipe
|
* package info pipe stream
|
||||||
*/
|
*/
|
||||||
FILE* file;
|
FILE* file;
|
||||||
|
|
||||||
@@ -247,11 +270,9 @@ METHOD(os_info_t, create_package_enumerator, enumerator_t*,
|
|||||||
{
|
{
|
||||||
FILE *file;
|
FILE *file;
|
||||||
package_enumerator_t *enumerator;
|
package_enumerator_t *enumerator;
|
||||||
chunk_t debian = { "Debian", 6 };
|
|
||||||
chunk_t ubuntu = { "Ubuntu", 6 };
|
|
||||||
|
|
||||||
/* Only Debian and Ubuntu package enumeration is currently supported */
|
/* Only Debian and Ubuntu package enumeration is currently supported */
|
||||||
if (!chunk_equals(this->name, debian) && !chunk_equals(this->name, ubuntu))
|
if (this->type != OS_TYPE_DEBIAN && this->type != OS_TYPE_UBUNTU)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -288,15 +309,18 @@ METHOD(os_info_t, destroy, void,
|
|||||||
/**
|
/**
|
||||||
* Determine Linux distribution version and hardware platform
|
* Determine Linux distribution version and hardware platform
|
||||||
*/
|
*/
|
||||||
static bool extract_platform_info(chunk_t *name, chunk_t *version)
|
static bool extract_platform_info(os_type_t *type, chunk_t *name,
|
||||||
|
chunk_t *version)
|
||||||
{
|
{
|
||||||
FILE *file;
|
FILE *file;
|
||||||
u_char buf[BUF_LEN], *pos = buf;
|
u_char buf[BUF_LEN], *pos = buf;
|
||||||
int len = BUF_LEN - 1;
|
int len = BUF_LEN - 1;
|
||||||
|
os_type_t os_type = OS_TYPE_UNKNOWN;
|
||||||
chunk_t os_name = chunk_empty;
|
chunk_t os_name = chunk_empty;
|
||||||
chunk_t os_version = chunk_empty;
|
chunk_t os_version = chunk_empty;
|
||||||
|
char *os_str;
|
||||||
struct utsname uninfo;
|
struct utsname uninfo;
|
||||||
int i;
|
int i, t;
|
||||||
|
|
||||||
/* Linux/Unix distribution release info (from http://linuxmafia.com) */
|
/* Linux/Unix distribution release info (from http://linuxmafia.com) */
|
||||||
const char* releases[] = {
|
const char* releases[] = {
|
||||||
@@ -367,7 +391,6 @@ static bool extract_platform_info(chunk_t *name, chunk_t *version)
|
|||||||
DBG1(DBG_IMC, "failed to find end of DISTRIB_ID field");
|
DBG1(DBG_IMC, "failed to find end of DISTRIB_ID field");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
os_name.len = pos - os_name.ptr;
|
os_name.len = pos - os_name.ptr;
|
||||||
|
|
||||||
/* Determine Distribution Release */
|
/* Determine Distribution Release */
|
||||||
@@ -387,18 +410,15 @@ static bool extract_platform_info(chunk_t *name, chunk_t *version)
|
|||||||
DBG1(DBG_IMC, "failed to find end of DISTRIB_RELEASE field");
|
DBG1(DBG_IMC, "failed to find end of DISTRIB_RELEASE field");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
os_version.len = pos - os_version.ptr;
|
os_version.len = pos - os_version.ptr;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case RELEASE_DEBIAN:
|
case RELEASE_DEBIAN:
|
||||||
{
|
{
|
||||||
char str_debian[] = "Debian";
|
os_type = OS_TYPE_DEBIAN;
|
||||||
|
|
||||||
os_name = chunk_create(str_debian, strlen(str_debian));
|
|
||||||
os_version.ptr = buf;
|
os_version.ptr = buf;
|
||||||
|
|
||||||
pos = strchr(buf, '\n');
|
pos = strchr(buf, '\n');
|
||||||
if (!pos)
|
if (!pos)
|
||||||
{
|
{
|
||||||
@@ -424,6 +444,7 @@ static bool extract_platform_info(chunk_t *name, chunk_t *version)
|
|||||||
}
|
}
|
||||||
|
|
||||||
os_name.len = pos - os_name.ptr;
|
os_name.len = pos - os_name.ptr;
|
||||||
|
|
||||||
pos += strlen(str_release);
|
pos += strlen(str_release);
|
||||||
os_version.ptr = pos;
|
os_version.ptr = pos;
|
||||||
|
|
||||||
@@ -454,6 +475,29 @@ static bool extract_platform_info(chunk_t *name, chunk_t *version)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Try to find a matching OS type */
|
||||||
|
if (os_type == OS_TYPE_UNKNOWN)
|
||||||
|
{
|
||||||
|
for (t = OS_TYPE_DEBIAN; t <= OS_TYPE_GENTOO; t++)
|
||||||
|
{
|
||||||
|
os_str = enum_to_name(os_type_names, t);
|
||||||
|
if (memeq(os_name.ptr, os_str, min(os_name.len, strlen(os_str))))
|
||||||
|
{
|
||||||
|
os_type = t;
|
||||||
|
os_name = chunk_create(os_str, strlen(os_str));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
os_str = enum_to_name(os_type_names, os_type);
|
||||||
|
os_name = chunk_create(os_str, strlen(os_str));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* copy OS type */
|
||||||
|
*type = os_type;
|
||||||
|
|
||||||
/* copy OS name */
|
/* copy OS name */
|
||||||
*name = chunk_clone(os_name);
|
*name = chunk_clone(os_name);
|
||||||
|
|
||||||
@@ -475,8 +519,9 @@ os_info_t *os_info_create(void)
|
|||||||
{
|
{
|
||||||
private_os_info_t *this;
|
private_os_info_t *this;
|
||||||
chunk_t name, version;
|
chunk_t name, version;
|
||||||
|
os_type_t type;
|
||||||
|
|
||||||
/* As an opton OS name and OS version can be configured manually */
|
/* As an option OS name and OS version can be configured manually */
|
||||||
name.ptr = lib->settings->get_str(lib->settings,
|
name.ptr = lib->settings->get_str(lib->settings,
|
||||||
"libimcv.os_info.name", NULL);
|
"libimcv.os_info.name", NULL);
|
||||||
version.ptr = lib->settings->get_str(lib->settings,
|
version.ptr = lib->settings->get_str(lib->settings,
|
||||||
@@ -491,7 +536,7 @@ os_info_t *os_info_create(void)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!extract_platform_info(&name, &version))
|
if (!extract_platform_info(&type, &name, &version))
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -503,6 +548,7 @@ os_info_t *os_info_create(void)
|
|||||||
|
|
||||||
INIT(this,
|
INIT(this,
|
||||||
.public = {
|
.public = {
|
||||||
|
.get_type = _get_type,
|
||||||
.get_name = _get_name,
|
.get_name = _get_name,
|
||||||
.get_numeric_version = _get_numeric_version,
|
.get_numeric_version = _get_numeric_version,
|
||||||
.get_version = _get_version,
|
.get_version = _get_version,
|
||||||
@@ -512,6 +558,7 @@ os_info_t *os_info_create(void)
|
|||||||
.create_package_enumerator = _create_package_enumerator,
|
.create_package_enumerator = _create_package_enumerator,
|
||||||
.destroy = _destroy,
|
.destroy = _destroy,
|
||||||
},
|
},
|
||||||
|
.type = type,
|
||||||
.name = name,
|
.name = name,
|
||||||
.version = version,
|
.version = version,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -22,12 +22,27 @@
|
|||||||
#define OS_INFO_H_
|
#define OS_INFO_H_
|
||||||
|
|
||||||
typedef struct os_info_t os_info_t;
|
typedef struct os_info_t os_info_t;
|
||||||
|
typedef enum os_type_t os_type_t;
|
||||||
typedef enum os_fwd_status_t os_fwd_status_t;
|
typedef enum os_fwd_status_t os_fwd_status_t;
|
||||||
|
|
||||||
#include <library.h>
|
#include <library.h>
|
||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
|
enum os_type_t {
|
||||||
|
OS_TYPE_UNKNOWN,
|
||||||
|
OS_TYPE_DEBIAN,
|
||||||
|
OS_TYPE_UBUNTU,
|
||||||
|
OS_TYPE_FEDORA,
|
||||||
|
OS_TYPE_REDHAT,
|
||||||
|
OS_TYPE_CENTOS,
|
||||||
|
OS_TYPE_SUSE,
|
||||||
|
OS_TYPE_GENTOO,
|
||||||
|
OS_TYPE_ANDROID
|
||||||
|
};
|
||||||
|
|
||||||
|
extern enum_name_t *os_type_names;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines the IPv4 forwarding status
|
* Defines the IPv4 forwarding status
|
||||||
*/
|
*/
|
||||||
@@ -44,6 +59,13 @@ extern enum_name_t *os_fwd_status_names;
|
|||||||
*/
|
*/
|
||||||
struct os_info_t {
|
struct os_info_t {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the OS type if it can be determined
|
||||||
|
*
|
||||||
|
* @return OS type
|
||||||
|
*/
|
||||||
|
os_type_t (*get_type)(os_info_t *this);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the OS product name or distribution
|
* Get the OS product name or distribution
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -128,32 +128,33 @@ TNC_Result TNC_IMC_NotifyConnectionChange(TNC_IMCID imc_id,
|
|||||||
static void add_product_info(imc_msg_t *msg)
|
static void add_product_info(imc_msg_t *msg)
|
||||||
{
|
{
|
||||||
pa_tnc_attr_t *attr;
|
pa_tnc_attr_t *attr;
|
||||||
chunk_t os_name;
|
os_type_t os_type;
|
||||||
pen_t vendor_id = PEN_IETF;
|
pen_t vendor_id = PEN_IETF;
|
||||||
char *vendor;
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
typedef struct vendor_pen_t {
|
typedef struct vendor_pen_t {
|
||||||
char *vendor;
|
os_type_t os_type;
|
||||||
pen_t pen;
|
pen_t pen;
|
||||||
} vendor_pen_t;
|
} vendor_pen_t;
|
||||||
|
|
||||||
vendor_pen_t vendor_pens[] = {
|
vendor_pen_t vendor_pens[] = {
|
||||||
{ "Debian", PEN_DEBIAN },
|
{ OS_TYPE_DEBIAN, PEN_DEBIAN },
|
||||||
{ "Ubuntu", PEN_CANONICAL }
|
{ OS_TYPE_UBUNTU, PEN_CANONICAL },
|
||||||
|
{ OS_TYPE_FEDORA, PEN_FEDORA },
|
||||||
|
{ OS_TYPE_REDHAT, PEN_REDHAT },
|
||||||
|
{ OS_TYPE_ANDROID, PEN_GOOGLE }
|
||||||
};
|
};
|
||||||
|
|
||||||
os_name = os->get_name(os);
|
os_type = os->get_type(os);
|
||||||
for (i = 0; i < countof(vendor_pens); i++)
|
for (i = 0; i < countof(vendor_pens); i++)
|
||||||
{
|
{
|
||||||
vendor = vendor_pens[i].vendor;
|
if (os_type == vendor_pens[i].os_type)
|
||||||
if (chunk_equals(os_name, chunk_create(vendor, strlen(vendor))))
|
|
||||||
{
|
{
|
||||||
vendor_id = vendor_pens[i].pen;
|
vendor_id = vendor_pens[i].pen;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
attr = ietf_attr_product_info_create(vendor_id, 0, os_name);
|
attr = ietf_attr_product_info_create(vendor_id, 0, os->get_name(os));
|
||||||
msg->add_attribute(msg, attr);
|
msg->add_attribute(msg, attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user