On request implemented setting media type.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24311 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
François Revol
2008-03-08 18:16:49 +00:00
parent e29faac6cd
commit 76ec752f89
+134 -27
View File
@@ -88,6 +88,89 @@ inet_print_address(sockaddr* _address)
// #pragma mark - // #pragma mark -
struct media_type {
int type;
const char* name;
const char* pretty;
struct {
int subtype;
const char* name;
const char* pretty;
} subtypes [6];
struct {
int option;
bool ro;
const char* name;
const char* pretty;
} options [6];
};
static const media_type kMediaTypes[] = {
{
0, // for generic options
"all",
"All",
{
{ IFM_AUTO, "auto", "Auto-select" },
{ -1, NULL, NULL }
},
{
{ IFM_FULL_DUPLEX, true, "fullduplex", "Full Duplex" },
{ IFM_HALF_DUPLEX, true, "halfduplex", "Half Duplex" },
{ IFM_LOOP, true, "loop", "Loop" },
//{ IFM_ACTIVE, false, "active", "Active" },
{ -1, false, NULL, NULL }
}
},
{
IFM_ETHER,
"ether",
"Ethernet",
{
//{ IFM_AUTO, "auto", "Auto-select" },
//{ IFM_AUI, "AUI", "10 MBit, AUI" },
//{ IFM_10_2, "10base2", "10 MBit, 10BASE-2" },
{ 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" },
{ -1, NULL, NULL }
},
{
{ -1, false, NULL, NULL }
}
},
{ -1, NULL, NULL, {{ -1, NULL, NULL }}, {{ -1, false, NULL, NULL }} }
};
static bool media_parse_subtype(const char* string, int media, int* type);
static bool
media_parse_subtype(const char* string, int media, int* type)
{
for (int32 i = 0; kMediaTypes[i].type >= 0; i++) {
// only check for generic or correct subtypes
if (kMediaTypes[i].type &&
kMediaTypes[i].type != media)
continue;
for (int32 j = 0; kMediaTypes[i].subtypes[j].subtype >= 0; j++) {
if (strcmp(kMediaTypes[i].subtypes[j].name, string) == 0) {
// found a match
*type = kMediaTypes[i].subtypes[j].subtype;
return true;
}
}
}
return false;
}
// #pragma mark -
void void
usage(int status) usage(int status)
{ {
@@ -99,10 +182,18 @@ usage(int status)
" peer <addr> - ppp-peer address\n" " peer <addr> - ppp-peer address\n"
" mtu <bytes> - maximal transfer unit\n" " mtu <bytes> - maximal transfer unit\n"
" metric <number> - metric number to use (defaults to 0)\n" " metric <number> - metric number to use (defaults to 0)\n"
"And <flags> can be: up, down, [-]promisc, [-]allmulti, [-]bcast, loopback\n\n" " media <media> - media type to use (defaults to auto)\n",
kProgramName, kProgramName);
for (int32 i = 0; kMediaTypes[i].type >= 0; i++) {
printf("For %s <media> can be one of: ", kMediaTypes[i].pretty);
for (int32 j = 0; kMediaTypes[i].subtypes[j].subtype >= 0; j++)
printf("%s ", kMediaTypes[i].subtypes[j].name);
printf("\n");
}
printf("And <flags> can be: up, down, [-]promisc, [-]allmulti, [-]bcast, loopback\n\n"
"Example:\n" "Example:\n"
"\t%s loop 127.0.0.1 255.0.0.0 up\n", "\t%s loop 127.0.0.1 255.0.0.0 up\n",
kProgramName, kProgramName, kProgramName); kProgramName);
exit(status); exit(status);
} }
@@ -218,32 +309,24 @@ list_interface(int socket, const char* name)
&& (request.ifr_media & IFM_ACTIVE) != 0) { && (request.ifr_media & IFM_ACTIVE) != 0) {
// dump media state in case we're linked // dump media state in case we're linked
const char* type = "unknown"; const char* type = "unknown";
bool show = true; bool show = false;
switch (IFM_TYPE(request.ifr_media)) { for (int32 i = 0; kMediaTypes[i].type >= 0; i++) {
case IFM_ETHER: // loopback don't really have a media anyway
switch (IFM_SUBTYPE(request.ifr_media)) { if (IFM_TYPE(request.ifr_media) == 0/*IFT_LOOP*/)
case IFM_AUTO: break;
type = "Auto-select"; // only check for generic or correct subtypes
break; if (kMediaTypes[i].type &&
case IFM_10_T: kMediaTypes[i].type != IFM_TYPE(request.ifr_media))
type = "10 MBit, 10BASE-T"; continue;
break; for (int32 j = 0; kMediaTypes[i].subtypes[j].subtype >= 0; j++) {
case IFM_100_TX: if (kMediaTypes[i].subtypes[j].subtype == IFM_SUBTYPE(request.ifr_media)) {
type = "100 MBit, 100BASE-TX"; // found a match
break; type = kMediaTypes[i].subtypes[j].pretty;
case IFM_1000_T: show = true;
type = "1 GBit, 1000BASE-T"; break;
break;
case IFM_1000_SX:
type = "1 GBit, 1000BASE-SX";
break;
} }
break; }
default:
show = false;
break;
} }
if (show) if (show)
@@ -416,7 +499,8 @@ configure_interface(int socket, const char* name, char* const* args,
bool hasAddress = false, hasMask = false, hasPeer = false, hasBroadcast = false; bool hasAddress = false, hasMask = false, hasPeer = false, hasBroadcast = false;
struct sockaddr address, mask, peer, broadcast; struct sockaddr address, mask, peer, broadcast;
int mtu = -1, metric = -1, addFlags = 0, removeFlags = 0, currentFlags = 0; int mtu = -1, metric = -1, media = -1;
int addFlags = 0, removeFlags = 0, currentFlags = 0;
// try to parse address family // try to parse address family
@@ -517,6 +601,23 @@ configure_interface(int socket, const char* name, char* const* args,
} }
metric = strtol(args[i + 1], NULL, 0); metric = strtol(args[i + 1], NULL, 0);
i++; i++;
} else if (!strcmp(args[i], "media")) {
if (ioctl(socket, SIOCGIFMEDIA, &request, sizeof(struct ifreq)) < 0) {
fprintf(stderr, "%s: Unable to detect media type\n",
kProgramName);
exit(1);
}
if (i + 1 >= argCount) {
fprintf(stderr, "%s: Option 'media' exptected parameter\n",
kProgramName);
exit(1);
}
if (!media_parse_subtype(args[i + 1], IFM_TYPE(request.ifr_media), &media)) {
fprintf(stderr, "%s: Invalid parameter for option 'media': '%s'\n",
kProgramName, args[i + 1]);
exit(1);
}
i++;
} else if (!strcmp(args[i], "up") || !strcmp(args[i], "-down")) { } else if (!strcmp(args[i], "up") || !strcmp(args[i], "-down")) {
addFlags |= IFF_UP; addFlags |= IFF_UP;
} else if (!strcmp(args[i], "down") || !strcmp(args[i], "-up")) { } else if (!strcmp(args[i], "down") || !strcmp(args[i], "-up")) {
@@ -611,6 +712,12 @@ configure_interface(int socket, const char* name, char* const* args,
if (ioctl(socket, SIOCSIFMETRIC, &request, sizeof(struct ifreq)) < 0) if (ioctl(socket, SIOCSIFMETRIC, &request, sizeof(struct ifreq)) < 0)
fprintf(stderr, "%s: Setting metric failed: %s\n", kProgramName, strerror(errno)); fprintf(stderr, "%s: Setting metric failed: %s\n", kProgramName, strerror(errno));
} }
if (media != -1) {
request.ifr_media = media;
if (ioctl(socket, SIOCSIFMEDIA, &request, sizeof(struct ifreq)) < 0)
fprintf(stderr, "%s: Setting media failed: %s\n", kProgramName, strerror(errno));
}
} }