#include "MediaTypes.h"
#include <stdint.h>
#include <string.h>
extern "C" {
# include <freebsd_network/compat/net/if_media.h>
}
struct media_type {
int type;
const char* name;
const char* pretty;
int subtype_mask;
struct {
int subtype;
const char* name;
const char* pretty;
} subtypes [10];
struct {
int option;
bool read_only;
const char* name;
const char* pretty;
} options [6];
};
const media_type kMediaTypes[] = {
{
IFM_ETHER,
"ether",
"Ethernet",
IFM_TMASK,
{
{ IFM_10_T, "10baseT", "10 MBit, 10BASE-T" },
{ IFM_100_TX, "100baseTX", "100 MBit, 100BASE-TX" },
{ IFM_1000_T, "1000baseT", "1 GBit, 1000BASE-T" },
{ IFM_1000_SX, "1000baseSX", "1 GBit, 1000BASE-SX" },
{ IFM_10G_T, "10GbaseT", "10 GBit, 10GBASE-T" },
{ IFM_10G_SR, "10GbaseSR", "10 Gbit, 850 nm Fibre"},
{ IFM_10G_LR, "10GbaseLR", "10 Gbit, 1310 nm Fibre"},
{ IFM_10G_LRM, "10GbaseLRM", "10 Gbit, 1300 nm Fibre"},
{ IFM_10G_TWINAX, "10GbaseCR", "10 Gbit, Direct Attach"},
{ -1, NULL, NULL }
},
{
{ -1, false, NULL, NULL }
}
},
{
IFM_IEEE80211,
"80211",
"Wireless Ethernet",
IFM_MMASK,
{
{ IFM_IEEE80211_11A, "802.11a", "802.11a" },
{ IFM_IEEE80211_11B, "802.11b", "802.11b" },
{ IFM_IEEE80211_11G, "802.11g", "802.11g" },
{ IFM_IEEE80211_FH, "802.11 FH", "802.11 FH" },
{ IFM_IEEE80211_11NA, "802.11n(a)", "802.11n(a)" },
{ IFM_IEEE80211_11NG, "802.11n(g)", "802.11n(g)" },
{ IFM_IEEE80211_VHT5G, "802.11ac", "802.11ac" },
{ -1, NULL, NULL }
},
{
{ -1, false, NULL, NULL }
}
},
{
0,
"all",
"All",
IFM_TMASK,
{
{ IFM_AUTO, "auto", "Auto-select" },
{ -1, NULL, NULL }
},
{
{ IFM_FDX, true, "fullduplex", "Full Duplex" },
{ IFM_HDX, true, "halfduplex", "Half Duplex" },
{ IFM_LOOP, true, "loop", "Loop" },
{ -1, false, NULL, NULL }
}
},
{ -1, NULL, NULL, -1, {{ -1, NULL, NULL }}, {{ -1, false, NULL, NULL }} }
};
const char*
get_media_type_name(size_t index)
{
if (index < sizeof(kMediaTypes) / sizeof(kMediaTypes[0]))
return kMediaTypes[index].pretty;
return NULL;
}
const char*
get_media_subtype_name(size_t typeIndex, size_t subIndex)
{
if (typeIndex < sizeof(kMediaTypes) / sizeof(kMediaTypes[0])) {
if (kMediaTypes[typeIndex].subtypes[subIndex].subtype >= 0)
return kMediaTypes[typeIndex].subtypes[subIndex].name;
}
return NULL;
}
bool
media_parse_subtype(const char* string, int media, int* type)
{
for (size_t i = 0; kMediaTypes[i].type >= 0; i++) {
if (kMediaTypes[i].type &&
kMediaTypes[i].type != media)
continue;
for (size_t j = 0; kMediaTypes[i].subtypes[j].subtype >= 0; j++) {
if (strcmp(kMediaTypes[i].subtypes[j].name, string) == 0) {
*type = kMediaTypes[i].subtypes[j].subtype;
return true;
}
}
}
return false;
}
const char*
media_type_to_string(int media)
{
for (size_t i = 0; kMediaTypes[i].type >= 0; i++) {
if (IFM_TYPE(media) == 0)
break;
if (kMediaTypes[i].type
&& kMediaTypes[i].type != IFM_TYPE(media))
continue;
const int subtype = (media & kMediaTypes[i].subtype_mask);
for (size_t j = 0; kMediaTypes[i].subtypes[j].subtype >= 0; j++) {
if (kMediaTypes[i].subtypes[j].subtype == subtype) {
return kMediaTypes[i].subtypes[j].pretty;
}
}
}
return NULL;
}