Files
haiku-beta6/src/tests/kits/net/preflet/InterfacesAddOn/Setting.cpp
T
Philippe Houdoin e0aefacfbb Add vector icons
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@33490 a95241bf-73f2-0310-859d-f6bbb57e9c96
2009-10-09 06:08:22 +00:00

199 lines
4.0 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* Copyright 2004-2007 Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Author:
* Andre Alves Garzia, [email protected]
*/
#include "Setting.h"
#include <String.h>
#include <File.h>
#include <Path.h>
#include <SupportDefs.h>
#include <AutoDeleter.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <net/if_dl.h>
#include <net/if_media.h>
#include <net/if_types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/sockio.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
Setting::Setting(const char *name)
:
fAuto(true)
{
fSocket = socket(AF_INET, SOCK_DGRAM, 0);
fName = name;
ReadConfiguration();
}
Setting::~Setting()
{
close(fSocket);
}
bool
Setting::_PrepareRequest(struct ifreq& request)
{
//This function is used for talking direct to the stack.
//It´s used by _ShowConfiguration.
const char* name = fName.String();
if (strlen(name) > IF_NAMESIZE)
return false;
strcpy(request.ifr_name, name);
return true;
}
void
Setting::ReadConfiguration()
{
ifreq request;
if (!_PrepareRequest(request))
return;
BString text = "dummy";
char address[32];
sockaddr_in* inetAddress = NULL;
// Obtain IP.
if (ioctl(fSocket, SIOCGIFADDR, &request, sizeof(request)) < 0)
return;
inetAddress = (sockaddr_in*)&request.ifr_addr;
if (inet_ntop(AF_INET, &inetAddress->sin_addr, address,
sizeof(address)) == NULL) {
return;
}
fIP = address;
// Obtain netmask.
if (ioctl(fSocket, SIOCGIFNETMASK, &request,
sizeof(request)) < 0) {
return;
}
inetAddress = (sockaddr_in*)&request.ifr_mask;
if (inet_ntop(AF_INET, &inetAddress->sin_addr, address,
sizeof(address)) == NULL) {
return;
}
fNetmask = address;
// Obtain gateway
ifconf config;
config.ifc_len = sizeof(config.ifc_value);
if (ioctl(fSocket, SIOCGRTSIZE, &config, sizeof(struct ifconf)) < 0)
return;
uint32 size = (uint32)config.ifc_value;
if (size == 0)
return;
void *buffer = malloc(size);
if (buffer == NULL)
return;
MemoryDeleter bufferDeleter(buffer);
config.ifc_len = size;
config.ifc_buf = buffer;
if (ioctl(fSocket, SIOCGRTTABLE, &config, sizeof(struct ifconf)) < 0)
return;
ifreq *interface = (ifreq *)buffer;
ifreq *end = (ifreq *)((uint8 *)buffer + size);
while (interface < end) {
route_entry& route = interface->ifr_route;
if (route.flags & RTF_GATEWAY) {
inetAddress = (sockaddr_in*)route.gateway;
fGateway = inet_ntoa(inetAddress->sin_addr);
}
int32 addressSize = 0;
if (route.destination != NULL)
addressSize += route.destination->sa_len;
if (route.mask != NULL)
addressSize += route.mask->sa_len;
if (route.gateway != NULL)
addressSize += route.gateway->sa_len;
interface = (ifreq *)((addr_t)interface +
IF_NAMESIZE + sizeof(route_entry) + addressSize);
}
uint32 flags = 0;
if (ioctl(fSocket, SIOCGIFFLAGS, &request, sizeof(struct ifreq)) == 0)
flags = request.ifr_flags;
fAuto = flags & IFF_AUTO_CONFIGURED;
if (ioctl(fSocket, SIOCGIFMEDIA, &request, sizeof(struct ifreq)) == 0)
fMedia = request.ifr_media;
// read resolv.conf for the dns.
fNameservers.MakeEmpty();
#define MATCH(line, name) \
(!strncmp(line, name, sizeof(name) - 1) && \
(line[sizeof(name) - 1] == ' ' || \
line[sizeof(name) - 1] == '\t'))
register FILE *fp = fopen("/etc/resolv.conf", "r");
if (fp == NULL) {
fprintf(stderr, "failed to open '/etc/resolv.conf' to "
"read nameservers: %s\n", strerror(errno));
return;
}
int nserv = 0;
char buf[1024];
register char *cp; //, **pp;
// register int n;
int MAXNS = 2;
// read the config file
while (fgets(buf, sizeof(buf), fp) != NULL) {
// skip comments
if (*buf == ';' || *buf == '#')
continue;
// read nameservers to query
if (MATCH(buf, "nameserver") && nserv < MAXNS) {
// char sbuf[2];
cp = buf + sizeof("nameserver") - 1;
while (*cp == ' ' || *cp == '\t')
cp++;
cp[strcspn(cp, ";# \t\n")] = '\0';
if ((*cp != '\0') && (*cp != '\n')) {
fNameservers.AddItem(new BString(cp));
nserv++;
}
}
continue;
}
fclose(fp);
}