/*
* intf.c
*
* Copyright (c) 2001 Dug Song <dugsong@monkey.org>
*
* $Id: intf.c,v 1.4 2004/01/13 06:51:56 dugsong Exp $
*/
#include "config.h"
#include <sys/types.h>
#include <err.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "dnet.h"
#include "mod.h"
static intf_t *intf;
static void
usage(void)
{
fprintf(stderr, "Usage: dnet intf show\n"
" dnet intf get <name>\n"
" dnet intf set <name> "
"[alias|dst|inet|link <addr> ...] [up|down|arp|noarp ...]\n"
" dnet intf src <ip>\n"
" dnet intf dst <ip>\n"
);
exit(1);
}
static char *
flags2string(u_short flags)
{
static char buf[256];
buf[0] = '\0';
if (flags & INTF_FLAG_UP)
strlcat(buf, ",UP", sizeof(buf));
if (flags & INTF_FLAG_LOOPBACK)
strlcat(buf, ",LOOPBACK", sizeof(buf));
if (flags & INTF_FLAG_POINTOPOINT)
strlcat(buf, ",POINTOPOINT", sizeof(buf));
if (flags & INTF_FLAG_NOARP)
strlcat(buf, ",NOARP", sizeof(buf));
if (flags & INTF_FLAG_BROADCAST)
strlcat(buf, ",BROADCAST", sizeof(buf));
if (flags & INTF_FLAG_MULTICAST)
strlcat(buf, ",MULTICAST", sizeof(buf));
if (buf[0] != '\0')
return (buf + 1);
return (buf);
}
static int
print_intf(const struct intf_entry *entry, void *arg)
{
int i;
printf("%s:", entry->intf_name);
printf(" flags=0x%x<%s>", entry->intf_flags,
flags2string(entry->intf_flags));
if (entry->intf_mtu != 0)
printf(" mtu %d", entry->intf_mtu);
printf("\n");
if (entry->intf_addr.addr_type == ADDR_TYPE_IP) {
if (entry->intf_dst_addr.addr_type == ADDR_TYPE_IP) {
printf("\tinet %s --> %s\n",
addr_ntoa(&entry->intf_addr),
addr_ntoa(&entry->intf_dst_addr));
} else
printf("\tinet %s\n", addr_ntoa(&entry->intf_addr));
}
if (entry->intf_link_addr.addr_type == ADDR_TYPE_ETH)
printf("\tlink %s\n", addr_ntoa(&entry->intf_link_addr));
for (i = 0; i < entry->intf_alias_num; i++)
printf("\talias %s\n", addr_ntoa(&entry->intf_alias_addrs[i]));
return (0);
}
int
intf_main(int argc, char *argv[])
{
struct intf_entry *entry;
struct addr *ap, addr;
char *cmd, buf[1024];
if (argc < 2)
usage();
cmd = argv[1];
entry = (struct intf_entry *)buf;
memset(entry, 0, sizeof(*entry));
entry->intf_len = sizeof(buf);
if ((intf = intf_open()) == NULL)
err(1, "intf_open");
if (strcmp(cmd, "show") == 0) {
if (intf_loop(intf, print_intf, NULL) < 0)
err(1, "intf_loop");
} else if (strcmp(cmd, "get") == 0) {
if (argc < 3)
usage();
strlcpy(entry->intf_name, argv[2], sizeof(entry->intf_name));
if (intf_get(intf, entry) < 0)
err(1, "intf_get");
print_intf(entry, NULL);
} else if (strcmp(cmd, "src") == 0) {
if (argc < 3 || addr_aton(argv[2], &addr) < 0)
usage();
if (intf_get_src(intf, entry, &addr) < 0)
err(1, "intf_get_src");
print_intf(entry, NULL);
} else if (strcmp(cmd, "dst") == 0) {
if (argc < 3 || addr_aton(argv[2], &addr) < 0)
usage();
if (intf_get_dst(intf, entry, &addr) < 0)
err(1, "intf_get_dst");
print_intf(entry, NULL);
} else if (strcmp(cmd, "set") == 0) {
if (argc < 4)
usage();
strlcpy(entry->intf_name, argv[2], sizeof(entry->intf_name));
for (argv += 3, argc -= 3; argc > 1; argv += 2, argc -= 2) {
if (strcmp(argv[0], "alias") == 0) {
ap = &entry->intf_alias_addrs
[entry->intf_alias_num++];
} else if (strcmp(argv[0], "dst") == 0) {
ap = &entry->intf_dst_addr;
} else if (strcmp(argv[0], "inet") == 0) {
ap = &entry->intf_addr;
} else if (strcmp(argv[0], "link") == 0) {
ap = &entry->intf_link_addr;
} else
break;
if (addr_pton(argv[1], ap) < 0)
err(1, "invalid address: %s", argv[1]);
}
for ( ; argc > 0; argv++, argc--) {
if (strcmp(argv[0], "up") == 0)
entry->intf_flags |= INTF_FLAG_UP;
else if (strcmp(argv[0], "down") == 0)
entry->intf_flags &= ~INTF_FLAG_UP;
else if (strcmp(argv[0], "arp") == 0)
entry->intf_flags &= ~INTF_FLAG_NOARP;
else if (strcmp(argv[0], "noarp") == 0)
entry->intf_flags |= INTF_FLAG_NOARP;
else
usage();
}
if (intf_set(intf, entry) < 0)
err(1, "intf_set");
} else
usage();
intf_close(intf);
exit(0);
}
struct mod mod_intf = {
"intf",
MOD_TYPE_KERN,
intf_main
};
syntax highlighted by Code2HTML, v. 0.9.1