169 lines
3.2 KiB
C
169 lines
3.2 KiB
C
#include <sys/types.h>
|
|
#include <sys/socket.h>
|
|
#include <sys/ioctl.h>
|
|
#include <netinet/in.h>
|
|
#include <net/if.h>
|
|
#include <net/if_arp.h>
|
|
#include <stdio.h>
|
|
#include <errno.h>
|
|
#include <fcntl.h>
|
|
#include <ctype.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
#include <netdb.h>
|
|
|
|
#include "rpc.h"
|
|
#include "netconfig.h"
|
|
|
|
static char *if_parse_name(char *name, char *p)
|
|
{
|
|
while (isspace(*p))
|
|
p++;
|
|
while (*p) {
|
|
if (isspace(*p))
|
|
break;
|
|
if (*p == ':') { /* could be an alias */
|
|
char *dot = p, *dotname = name;
|
|
*name++ = *p++;
|
|
while (isdigit(*p))
|
|
*name++ = *p++;
|
|
if (*p != ':') { /* it wasn't, backup */
|
|
p = dot;
|
|
name = dotname;
|
|
}
|
|
if (*p == '\0')
|
|
return NULL;
|
|
p++;
|
|
break;
|
|
}
|
|
*name++ = *p++;
|
|
}
|
|
*name++ = '\0';
|
|
return p;
|
|
}
|
|
|
|
|
|
/* call ioctl system call */
|
|
ret_code if_ioctl(unsigned long request, caddr_t ifreq, int *ret)
|
|
{
|
|
int sock;
|
|
int err = 0;
|
|
|
|
if(ret)
|
|
{
|
|
*ret = 0;
|
|
}
|
|
|
|
sock = socket(AF_INET, SOCK_DGRAM, 0);
|
|
if (sock < 0)
|
|
{
|
|
rpc_log_error("Cannot create UDP socket");
|
|
return RET_SOCKERR;
|
|
}
|
|
if ((err = ioctl(sock, request, ifreq)) < 0)
|
|
{
|
|
rpc_log_error("Ioctl error: %s\n", strerror(errno));
|
|
|
|
}
|
|
|
|
close(sock);
|
|
|
|
if (err < 0)
|
|
{
|
|
if(ret)
|
|
{
|
|
*ret = err;
|
|
}
|
|
return RET_SYSERR;
|
|
}
|
|
|
|
return RET_OK;
|
|
}
|
|
|
|
|
|
/* Set a certain interface flag. */
|
|
static int if_set_flag(char *ifname, short flag, int *code)
|
|
{
|
|
struct ifreq ifr = {0};
|
|
ret_code ret = RET_OK;
|
|
|
|
strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name) - 1);
|
|
|
|
ret = if_ioctl(SIOCGIFFLAGS, (caddr_t)&ifr, code);
|
|
ASSERT_RET(ret);
|
|
|
|
strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name) - 1);
|
|
ifr.ifr_flags |= flag;
|
|
|
|
ret = if_ioctl(SIOCSIFFLAGS, (caddr_t)&ifr, code);
|
|
ASSERT_RET(ret);
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
/* Clear a certain interface flag. */
|
|
static int if_clear_flag(char *ifname, short flag, int *code)
|
|
{
|
|
struct ifreq ifr = {0};
|
|
ret_code ret;
|
|
|
|
strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name) - 1);
|
|
|
|
ret = if_ioctl(SIOCGIFFLAGS, (caddr_t)&ifr, code);
|
|
ASSERT_RET(ret);
|
|
|
|
strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name) - 1);
|
|
ifr.ifr_flags &= ~flag;
|
|
|
|
ret = if_ioctl(SIOCSIFFLAGS, (caddr_t)&ifr, code);
|
|
ASSERT_RET(ret);
|
|
|
|
return ret;
|
|
}
|
|
|
|
ret_code if_set_up(char *ifname, int *code)
|
|
{
|
|
return if_set_flag(ifname, (IFF_UP | IFF_RUNNING), code);
|
|
}
|
|
|
|
ret_code if_set_down(char *ifname, int *code)
|
|
{
|
|
return if_clear_flag(ifname, IFF_UP, code);
|
|
}
|
|
|
|
int if_readlist(caddr_t ifcfg, int max_port)
|
|
{
|
|
struct ifreq *ifreq = (struct ifreq *)ifcfg;
|
|
char name[128] = {0};
|
|
char buf[512] = {0};
|
|
int i = 0;
|
|
FILE *fh;
|
|
|
|
fh = fopen(PATH_PROCNET_DEV, "r");
|
|
if (!fh) {
|
|
return 0;
|
|
}
|
|
|
|
fgets(buf, sizeof buf, fh); /* eat line */
|
|
fgets(buf, sizeof buf, fh);
|
|
|
|
while (fgets(buf, sizeof buf, fh)) {
|
|
if(i >= max_port){
|
|
break;
|
|
}
|
|
|
|
memset(name, 0, 128);
|
|
if_parse_name(name, buf);
|
|
if(strlen(name) != 0){
|
|
strncpy(ifreq[i].ifr_name, name, sizeof(ifreq[i].ifr_name));
|
|
i++;
|
|
}
|
|
}
|
|
|
|
fclose(fh);
|
|
return i;
|
|
}
|
|
|