/*! SetConfiguration sets this classes current BNetworkAddress settings to the interface directly via BNetworkInterface and friends */ void NetworkSettings::SetConfiguration() { printf("Setting %s\n", Name()); fNetworkDevice->JoinNetwork(WirelessNetwork()); for (int index = 0; index < MAX_PROTOCOLS; index++) { int inet_id = fProtocols[index].inet_id; if (fProtocols[index].present) { int32 zeroAddr = fNetworkInterface->FindFirstAddress(inet_id); if (zeroAddr >= 0) { BNetworkInterfaceAddress interfaceConfig; fNetworkInterface->GetAddressAt(zeroAddr, interfaceConfig); interfaceConfig.SetAddress(fAddress[inet_id]); interfaceConfig.SetMask(fNetmask[inet_id]); fNetworkInterface->SetAddress(interfaceConfig); fNetworkInterface->SetTo(zeroAddr); } else { // TODO : test this case (no address set for this protocol) printf("no zeroAddr found for %s(%d), found %lu\n", fProtocols[index].name, inet_id, zeroAddr); BNetworkInterfaceAddress interfaceConfig; interfaceConfig.SetAddress(fAddress[inet_id]); interfaceConfig.SetMask(fNetmask[inet_id]); fNetworkInterface->AddAddress(interfaceConfig); } } } }
status_t BNetworkInterface::AddAddress(const BNetworkAddress& local) { BNetworkInterfaceAddress address; address.SetAddress(local.SockAddr()); return do_ifaliasreq(Name(), B_SOCKET_ADD_ALIAS, address); }
void configure_interface(const char* name, char* const* args, int32 argCount) { // try to parse address family int32 i = 0; int family = get_address_family(args[i]); if (family != AF_UNSPEC) i++; // try to parse address BNetworkAddress address; BNetworkAddress mask; if (parse_address(family, args[i], address)) { i++; if (parse_address(family, args[i], mask)) i++; } BNetworkInterface interface(name); if (!interface.Exists()) { // the interface does not exist yet, we have to add it first BNetworkRoster& roster = BNetworkRoster::Default(); status_t status = roster.AddInterface(interface); if (status != B_OK) { fprintf(stderr, "%s: Could not add interface: %s\n", kProgramName, strerror(status)); exit(1); } } BNetworkAddress broadcast; BNetworkAddress peer; int mtu = -1, metric = -1, media = -1; int addFlags = 0, currentFlags = 0, removeFlags = 0; bool doAutoConfig = false; // parse parameters and flags while (i < argCount) { if (!strcmp(args[i], "peer")) { if (!parse_address(family, args[i + 1], peer)) { fprintf(stderr, "%s: Option 'peer' needs valid address " "parameter\n", kProgramName); exit(1); } i++; } else if (!strcmp(args[i], "nm") || !strcmp(args[i], "netmask")) { if (!mask.IsEmpty()) { fprintf(stderr, "%s: Netmask or prefix length is specified " "twice\n", kProgramName); exit(1); } if (!parse_address(family, args[i + 1], mask)) { fprintf(stderr, "%s: Option 'netmask' needs valid address " "parameter\n", kProgramName); exit(1); } i++; } else if (!strcmp(args[i], "prefixlen") || !strcmp(args[i], "plen") || !strcmp(args[i], "prefix-length")) { if (!mask.IsEmpty()) { fprintf(stderr, "%s: Netmask or prefix length is specified " "twice\n", kProgramName); exit(1); } // default to AF_INET if no address family has been specified yet if (family == AF_UNSPEC) family = AF_INET; if (!prefix_length_to_mask(family, args[i + 1], mask)) { fprintf(stderr, "%s: Option 'prefix-length %s' is invalid for " "this address family\n", kProgramName, args[i + 1]); exit(1); } i++; } else if (!strcmp(args[i], "bc") || !strcmp(args[i], "broadcast")) { if (!broadcast.IsEmpty()) { fprintf(stderr, "%s: broadcast address is specified twice\n", kProgramName); exit(1); } if (!parse_address(family, args[i + 1], broadcast)) { fprintf(stderr, "%s: Option 'broadcast' needs valid address " "parameter\n", kProgramName); exit(1); } addFlags |= IFF_BROADCAST; i++; } else if (!strcmp(args[i], "mtu")) { mtu = args[i + 1] ? strtol(args[i + 1], NULL, 0) : 0; if (mtu <= 500) { fprintf(stderr, "%s: Option 'mtu' expected valid max transfer " "unit size\n", kProgramName); exit(1); } i++; } else if (!strcmp(args[i], "metric")) { if (i + 1 >= argCount) { fprintf(stderr, "%s: Option 'metric' expected parameter\n", kProgramName); exit(1); } metric = strtol(args[i + 1], NULL, 0); i++; } else if (!strcmp(args[i], "media")) { media = interface.Media(); if (media < 0) { fprintf(stderr, "%s: Unable to detect media type\n", kProgramName); exit(1); } if (i + 1 >= argCount) { fprintf(stderr, "%s: Option 'media' expected parameter\n", kProgramName); exit(1); } if (!media_parse_subtype(args[i + 1], IFM_TYPE(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")) { addFlags |= IFF_UP; } else if (!strcmp(args[i], "down") || !strcmp(args[i], "-up")) { removeFlags |= IFF_UP; } else if (!strcmp(args[i], "bcast")) { addFlags |= IFF_BROADCAST; } else if (!strcmp(args[i], "-bcast")) { removeFlags |= IFF_BROADCAST; } else if (!strcmp(args[i], "promisc")) { addFlags |= IFF_PROMISC; } else if (!strcmp(args[i], "-promisc")) { removeFlags |= IFF_PROMISC; } else if (!strcmp(args[i], "allmulti")) { addFlags |= IFF_ALLMULTI; } else if (!strcmp(args[i], "-allmulti")) { removeFlags |= IFF_ALLMULTI; } else if (!strcmp(args[i], "loopback")) { addFlags |= IFF_LOOPBACK; } else if (!strcmp(args[i], "auto-config")) { doAutoConfig = true; } else usage(1); i++; } if ((addFlags & removeFlags) != 0) { fprintf(stderr, "%s: Contradicting flags specified\n", kProgramName); exit(1); } if (doAutoConfig && (!address.IsEmpty() || !mask.IsEmpty() || !broadcast.IsEmpty() || !peer.IsEmpty())) { fprintf(stderr, "%s: Contradicting changes specified\n", kProgramName); exit(1); } // set address/mask/broadcast/peer if (!address.IsEmpty() || !mask.IsEmpty() || !broadcast.IsEmpty()) { BNetworkInterfaceAddress interfaceAddress; interfaceAddress.SetAddress(address); interfaceAddress.SetMask(mask); if (!broadcast.IsEmpty()) interfaceAddress.SetBroadcast(broadcast); else if (!peer.IsEmpty()) interfaceAddress.SetDestination(peer); status_t status = interface.SetAddress(interfaceAddress); if (status != B_OK) { fprintf(stderr, "%s: Setting address failed: %s\n", kProgramName, strerror(status)); exit(1); } } currentFlags = interface.Flags(); // set flags if (!address.IsEmpty() || !mask.IsEmpty() || !broadcast.IsEmpty() || !peer.IsEmpty()) removeFlags = IFF_AUTO_CONFIGURED | IFF_CONFIGURING; if (addFlags || removeFlags) { status_t status = interface.SetFlags((currentFlags & ~removeFlags) | addFlags); if (status != B_OK) { fprintf(stderr, "%s: Setting flags failed: %s\n", kProgramName, strerror(status)); } } // set options if (mtu != -1) { status_t status = interface.SetMTU(mtu); if (status != B_OK) { fprintf(stderr, "%s: Setting MTU failed: %s\n", kProgramName, strerror(status)); } } if (metric != -1) { status_t status = interface.SetMetric(metric); if (status != B_OK) { fprintf(stderr, "%s: Setting metric failed: %s\n", kProgramName, strerror(status)); } } if (media != -1) { status_t status = interface.SetMedia(media); if (status != B_OK) { fprintf(stderr, "%s: Setting media failed: %s\n", kProgramName, strerror(status)); } } // start auto configuration, if asked for if (doAutoConfig) { status_t status = interface.AutoConfigure(family); if (status == B_BAD_PORT_ID) { fprintf(stderr, "%s: The net_server needs to run for the auto " "configuration!\n", kProgramName); } else if (status != B_OK) { fprintf(stderr, "%s: Auto-configuring failed: %s\n", kProgramName, strerror(status)); } } }