00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "config.h"
00010
00011 #include <sys/types.h>
00012
00013 #include <err.h>
00014 #include <errno.h>
00015 #include <stdio.h>
00016 #include <stdlib.h>
00017 #include <string.h>
00018 #include <unistd.h>
00019
00020 #include "dnet.h"
00021 #include "mod.h"
00022
00023 static intf_t *intf;
00024
00025 static void
00026 usage(void)
00027 {
00028 fprintf(stderr, "Usage: dnet intf show\n"
00029 " dnet intf get <name>\n"
00030 " dnet intf set <name> "
00031 "[alias|dst|inet|link <addr> ...] [up|down|arp|noarp ...]\n"
00032 " dnet intf src <ip>\n"
00033 " dnet intf dst <ip>\n"
00034 );
00035 exit(1);
00036 }
00037
00038 static char *
00039 flags2string(u_short flags)
00040 {
00041 static char buf[256];
00042
00043 buf[0] = '\0';
00044
00045 if (flags & INTF_FLAG_UP)
00046 strlcat(buf, ",UP", sizeof(buf));
00047 if (flags & INTF_FLAG_LOOPBACK)
00048 strlcat(buf, ",LOOPBACK", sizeof(buf));
00049 if (flags & INTF_FLAG_POINTOPOINT)
00050 strlcat(buf, ",POINTOPOINT", sizeof(buf));
00051 if (flags & INTF_FLAG_NOARP)
00052 strlcat(buf, ",NOARP", sizeof(buf));
00053 if (flags & INTF_FLAG_BROADCAST)
00054 strlcat(buf, ",BROADCAST", sizeof(buf));
00055 if (flags & INTF_FLAG_MULTICAST)
00056 strlcat(buf, ",MULTICAST", sizeof(buf));
00057
00058 if (buf[0] != '\0')
00059 return (buf + 1);
00060
00061 return (buf);
00062 }
00063
00064 static int
00065 print_intf(const struct intf_entry *entry, void *arg)
00066 {
00067 int i;
00068
00069 printf("%s:", entry->intf_name);
00070
00071 printf(" flags=0x%x<%s>", entry->intf_flags,
00072 flags2string(entry->intf_flags));
00073
00074 if (entry->intf_mtu != 0)
00075 printf(" mtu %d", entry->intf_mtu);
00076
00077 printf("\n");
00078
00079 if (entry->intf_addr.addr_type == ADDR_TYPE_IP) {
00080 if (entry->intf_dst_addr.addr_type == ADDR_TYPE_IP) {
00081 printf("\tinet %s --> %s\n",
00082 addr_ntoa(&entry->intf_addr),
00083 addr_ntoa(&entry->intf_dst_addr));
00084 } else
00085 printf("\tinet %s\n", addr_ntoa(&entry->intf_addr));
00086 }
00087 if (entry->intf_link_addr.addr_type == ADDR_TYPE_ETH)
00088 printf("\tlink %s\n", addr_ntoa(&entry->intf_link_addr));
00089
00090 for (i = 0; i < entry->intf_alias_num; i++)
00091 printf("\talias %s\n", addr_ntoa(&entry->intf_alias_addrs[i]));
00092
00093 return (0);
00094 }
00095
00096 int
00097 intf_main(int argc, char *argv[])
00098 {
00099 struct intf_entry *entry;
00100 struct addr *ap, addr;
00101 char *cmd, buf[1024];
00102
00103 if (argc < 2)
00104 usage();
00105
00106 cmd = argv[1];
00107
00108 entry = (struct intf_entry *)buf;
00109 memset(entry, 0, sizeof(*entry));
00110 entry->intf_len = sizeof(buf);
00111
00112 if ((intf = intf_open()) == NULL)
00113 err(1, "intf_open");
00114
00115 if (strcmp(cmd, "show") == 0) {
00116 if (intf_loop(intf, print_intf, NULL) < 0)
00117 err(1, "intf_loop");
00118 } else if (strcmp(cmd, "get") == 0) {
00119 if (argc < 3)
00120 usage();
00121 strlcpy(entry->intf_name, argv[2], sizeof(entry->intf_name));
00122 if (intf_get(intf, entry) < 0)
00123 err(1, "intf_get");
00124 print_intf(entry, NULL);
00125 } else if (strcmp(cmd, "src") == 0) {
00126 if (argc < 3 || addr_aton(argv[2], &addr) < 0)
00127 usage();
00128 if (intf_get_src(intf, entry, &addr) < 0)
00129 err(1, "intf_get_src");
00130 print_intf(entry, NULL);
00131 } else if (strcmp(cmd, "dst") == 0) {
00132 if (argc < 3 || addr_aton(argv[2], &addr) < 0)
00133 usage();
00134 if (intf_get_dst(intf, entry, &addr) < 0)
00135 err(1, "intf_get_dst");
00136 print_intf(entry, NULL);
00137 } else if (strcmp(cmd, "set") == 0) {
00138 if (argc < 4)
00139 usage();
00140
00141 strlcpy(entry->intf_name, argv[2], sizeof(entry->intf_name));
00142
00143 for (argv += 3, argc -= 3; argc > 1; argv += 2, argc -= 2) {
00144 if (strcmp(argv[0], "alias") == 0) {
00145 ap = &entry->intf_alias_addrs
00146 [entry->intf_alias_num++];
00147 } else if (strcmp(argv[0], "dst") == 0) {
00148 ap = &entry->intf_dst_addr;
00149 } else if (strcmp(argv[0], "inet") == 0) {
00150 ap = &entry->intf_addr;
00151 } else if (strcmp(argv[0], "link") == 0) {
00152 ap = &entry->intf_link_addr;
00153 } else
00154 break;
00155
00156 if (addr_pton(argv[1], ap) < 0)
00157 err(1, "invalid address: %s", argv[1]);
00158 }
00159 for ( ; argc > 0; argv++, argc--) {
00160 if (strcmp(argv[0], "up") == 0)
00161 entry->intf_flags |= INTF_FLAG_UP;
00162 else if (strcmp(argv[0], "down") == 0)
00163 entry->intf_flags &= ~INTF_FLAG_UP;
00164 else if (strcmp(argv[0], "arp") == 0)
00165 entry->intf_flags &= ~INTF_FLAG_NOARP;
00166 else if (strcmp(argv[0], "noarp") == 0)
00167 entry->intf_flags |= INTF_FLAG_NOARP;
00168 else
00169 usage();
00170 }
00171 if (intf_set(intf, entry) < 0)
00172 err(1, "intf_set");
00173 } else
00174 usage();
00175
00176 intf_close(intf);
00177
00178 exit(0);
00179 }
00180
00181 struct mod mod_intf = {
00182 "intf",
00183 MOD_TYPE_KERN,
00184 intf_main
00185 };