int main(int argc, char *argv[]) { struct sockaddr_un sun; struct parse_result *res; struct imsg imsg; int ctl_sock; int done = 0; int n, verbose = 0; /* parse options */ if ((res = parse(argc - 1, argv + 1)) == NULL) exit(1); /* connect to relayd control socket */ if ((ctl_sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) err(1, "socket"); bzero(&sun, sizeof(sun)); sun.sun_family = AF_UNIX; strlcpy(sun.sun_path, RELAYD_SOCKET, sizeof(sun.sun_path)); reconnect: if (connect(ctl_sock, (struct sockaddr *)&sun, sizeof(sun)) == -1) { /* Keep retrying if running in monitor mode */ if (res->action == MONITOR && (errno == ENOENT || errno == ECONNREFUSED)) { usleep(100); goto reconnect; } err(1, "connect: %s", RELAYD_SOCKET); } if ((ibuf = malloc(sizeof(struct imsgbuf))) == NULL) err(1, NULL); imsg_init(ibuf, ctl_sock); done = 0; /* process user request */ switch (res->action) { case NONE: usage(); /* not reached */ case SHOW_SUM: case SHOW_HOSTS: case SHOW_RDRS: case SHOW_RELAYS: case SHOW_ROUTERS: imsg_compose(ibuf, IMSG_CTL_SHOW_SUM, 0, 0, -1, NULL, 0); printf("%-4s\t%-8s\t%-24s\t%-7s\tStatus\n", "Id", "Type", "Name", "Avlblty"); break; case SHOW_SESSIONS: imsg_compose(ibuf, IMSG_CTL_SESSION, 0, 0, -1, NULL, 0); break; case RDR_ENABLE: imsg_compose(ibuf, IMSG_CTL_RDR_ENABLE, 0, 0, -1, &res->id, sizeof(res->id)); break; case RDR_DISABLE: imsg_compose(ibuf, IMSG_CTL_RDR_DISABLE, 0, 0, -1, &res->id, sizeof(res->id)); break; case TABLE_ENABLE: imsg_compose(ibuf, IMSG_CTL_TABLE_ENABLE, 0, 0, -1, &res->id, sizeof(res->id)); break; case TABLE_DISABLE: imsg_compose(ibuf, IMSG_CTL_TABLE_DISABLE, 0, 0, -1, &res->id, sizeof(res->id)); break; case HOST_ENABLE: imsg_compose(ibuf, IMSG_CTL_HOST_ENABLE, 0, 0, -1, &res->id, sizeof(res->id)); break; case HOST_DISABLE: imsg_compose(ibuf, IMSG_CTL_HOST_DISABLE, 0, 0, -1, &res->id, sizeof(res->id)); break; case SHUTDOWN: imsg_compose(ibuf, IMSG_CTL_SHUTDOWN, 0, 0, -1, NULL, 0); break; case POLL: imsg_compose(ibuf, IMSG_CTL_POLL, 0, 0, -1, NULL, 0); break; case LOAD: imsg_compose(ibuf, IMSG_CTL_RELOAD, 0, 0, -1, res->path, strlen(res->path)); done = 1; break; case RELOAD: imsg_compose(ibuf, IMSG_CTL_RELOAD, 0, 0, -1, NULL, 0); done = 1; break; case MONITOR: imsg_compose(ibuf, IMSG_CTL_NOTIFY, 0, 0, -1, NULL, 0); break; case LOG_VERBOSE: verbose = 2; /* FALLTHROUGH */ case LOG_BRIEF: imsg_compose(ibuf, IMSG_CTL_VERBOSE, 0, 0, -1, &verbose, sizeof(verbose)); printf("logging request sent.\n"); done = 1; break; } while (ibuf->w.queued) if (msgbuf_write(&ibuf->w) <= 0 && errno != EAGAIN) err(1, "write error"); while (!done) { if ((n = imsg_read(ibuf)) == -1) errx(1, "imsg_read error"); if (n == 0) errx(1, "pipe closed"); while (!done) { if ((n = imsg_get(ibuf, &imsg)) == -1) errx(1, "imsg_get error"); if (n == 0) break; switch (res->action) { case SHOW_SUM: case SHOW_HOSTS: case SHOW_RDRS: case SHOW_RELAYS: case SHOW_ROUTERS: done = show_summary_msg(&imsg, res->action); break; case SHOW_SESSIONS: done = show_session_msg(&imsg); break; case RDR_DISABLE: case RDR_ENABLE: case TABLE_DISABLE: case TABLE_ENABLE: case HOST_DISABLE: case HOST_ENABLE: case POLL: case SHUTDOWN: done = show_command_output(&imsg); break; case NONE: case LOG_VERBOSE: case LOG_BRIEF: case RELOAD: case LOAD: break; case MONITOR: done = monitor(&imsg); break; } imsg_free(&imsg); } } close(ctl_sock); free(ibuf); return (error ? 1 : 0); }
int main(int argc, char *argv[]) { struct sockaddr_un sun; struct parse_result *res; struct imsg imsg; unsigned int ifidx = 0; int ctl_sock; int done = 0, verbose = 0; int n; int ch; char *sockname; sockname = OSPF6D_SOCKET; while ((ch = getopt(argc, argv, "s:")) != -1) { switch (ch) { case 's': sockname = optarg; break; default: usage(); /* NOTREACHED */ } } argc -= optind; argv += optind; /* parse options */ if ((res = parse(argc, argv)) == NULL) exit(1); /* connect to ospf6d control socket */ if ((ctl_sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) err(1, "socket"); bzero(&sun, sizeof(sun)); sun.sun_family = AF_UNIX; strlcpy(sun.sun_path, sockname, sizeof(sun.sun_path)); if (connect(ctl_sock, (struct sockaddr *)&sun, sizeof(sun)) == -1) err(1, "connect: %s", sockname); if (pledge("stdio", NULL) == -1) err(1, "pledge"); if ((ibuf = malloc(sizeof(struct imsgbuf))) == NULL) err(1, NULL); imsg_init(ibuf, ctl_sock); done = 0; /* process user request */ switch (res->action) { case NONE: usage(); /* not reached */ case SHOW: case SHOW_SUM: imsg_compose(ibuf, IMSG_CTL_SHOW_SUM, 0, 0, -1, NULL, 0); break; case SHOW_IFACE: printf("%-11s %-29s %-6s %-10s %-10s %-8s\n", "Interface", "Address", "State", "HelloTimer", "Linkstate", "Uptime"); /*FALLTHROUGH*/ case SHOW_IFACE_DTAIL: if (*res->ifname) { ifidx = if_nametoindex(res->ifname); if (ifidx == 0) errx(1, "no such interface %s", res->ifname); } imsg_compose(ibuf, IMSG_CTL_SHOW_INTERFACE, 0, 0, -1, &ifidx, sizeof(ifidx)); break; case SHOW_NBR: printf("%-15s %-3s %-12s %-9s %-11s %s\n", "ID", "Pri", "State", "DeadTime", "Iface","Uptime"); /*FALLTHROUGH*/ case SHOW_NBR_DTAIL: imsg_compose(ibuf, IMSG_CTL_SHOW_NBR, 0, 0, -1, NULL, 0); break; case SHOW_DB: imsg_compose(ibuf, IMSG_CTL_SHOW_DATABASE, 0, 0, -1, NULL, 0); break; case SHOW_DBBYAREA: imsg_compose(ibuf, IMSG_CTL_SHOW_DATABASE, 0, 0, -1, &res->addr, sizeof(res->addr)); break; case SHOW_DBEXT: imsg_compose(ibuf, IMSG_CTL_SHOW_DB_EXT, 0, 0, -1, NULL, 0); break; case SHOW_DBLINK: imsg_compose(ibuf, IMSG_CTL_SHOW_DB_LINK, 0, 0, -1, NULL, 0); break; case SHOW_DBNET: imsg_compose(ibuf, IMSG_CTL_SHOW_DB_NET, 0, 0, -1, NULL, 0); break; case SHOW_DBRTR: imsg_compose(ibuf, IMSG_CTL_SHOW_DB_RTR, 0, 0, -1, NULL, 0); break; case SHOW_DBINTRA: imsg_compose(ibuf, IMSG_CTL_SHOW_DB_INTRA, 0, 0, -1, NULL, 0); break; case SHOW_DBSELF: imsg_compose(ibuf, IMSG_CTL_SHOW_DB_SELF, 0, 0, -1, NULL, 0); break; case SHOW_DBSUM: imsg_compose(ibuf, IMSG_CTL_SHOW_DB_SUM, 0, 0, -1, NULL, 0); break; case SHOW_DBASBR: imsg_compose(ibuf, IMSG_CTL_SHOW_DB_ASBR, 0, 0, -1, NULL, 0); break; case SHOW_RIB: printf("%-20s %-17s %-12s %-9s %-7s %-8s\n", "Destination", "Nexthop", "Path Type", "Type", "Cost", "Uptime"); /*FALLTHROUGH*/ case SHOW_RIB_DTAIL: imsg_compose(ibuf, IMSG_CTL_SHOW_RIB, 0, 0, -1, NULL, 0); break; case SHOW_FIB: if (IN6_IS_ADDR_UNSPECIFIED(&res->addr)) imsg_compose(ibuf, IMSG_CTL_KROUTE, 0, 0, -1, &res->flags, sizeof(res->flags)); else imsg_compose(ibuf, IMSG_CTL_KROUTE_ADDR, 0, 0, -1, &res->addr, sizeof(res->addr)); show_fib_head(); break; case FIB: errx(1, "fib couple|decouple"); break; case FIB_COUPLE: imsg_compose(ibuf, IMSG_CTL_FIB_COUPLE, 0, 0, -1, NULL, 0); printf("couple request sent.\n"); done = 1; break; case FIB_DECOUPLE: imsg_compose(ibuf, IMSG_CTL_FIB_DECOUPLE, 0, 0, -1, NULL, 0); printf("decouple request sent.\n"); done = 1; break; case LOG_VERBOSE: verbose = 1; /* FALLTHROUGH */ case LOG_BRIEF: imsg_compose(ibuf, IMSG_CTL_LOG_VERBOSE, 0, 0, -1, &verbose, sizeof(verbose)); printf("logging request sent.\n"); done = 1; break; case RELOAD: imsg_compose(ibuf, IMSG_CTL_RELOAD, 0, 0, -1, NULL, 0); printf("reload request sent.\n"); done = 1; break; } while (ibuf->w.queued) if (msgbuf_write(&ibuf->w) <= 0 && errno != EAGAIN) err(1, "write error"); while (!done) { if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN) errx(1, "imsg_read error"); if (n == 0) errx(1, "pipe closed"); while (!done) { if ((n = imsg_get(ibuf, &imsg)) == -1) errx(1, "imsg_get error"); if (n == 0) break; switch (res->action) { case SHOW: case SHOW_SUM: done = show_summary_msg(&imsg); break; case SHOW_IFACE: done = show_interface_msg(&imsg); break; case SHOW_IFACE_DTAIL: done = show_interface_detail_msg(&imsg); break; case SHOW_NBR: done = show_nbr_msg(&imsg); break; case SHOW_NBR_DTAIL: done = show_nbr_detail_msg(&imsg); break; case SHOW_DB: case SHOW_DBBYAREA: case SHOW_DBSELF: done = show_database_msg(&imsg); break; case SHOW_DBEXT: case SHOW_DBLINK: case SHOW_DBNET: case SHOW_DBRTR: case SHOW_DBINTRA: case SHOW_DBSUM: case SHOW_DBASBR: done = show_db_msg_detail(&imsg); break; case SHOW_RIB: done = show_rib_msg(&imsg); break; case SHOW_RIB_DTAIL: done = show_rib_detail_msg(&imsg); break; case SHOW_FIB: done = show_fib_msg(&imsg); break; case NONE: case FIB: case FIB_COUPLE: case FIB_DECOUPLE: case LOG_VERBOSE: case LOG_BRIEF: case RELOAD: break; } imsg_free(&imsg); } } close(ctl_sock); free(ibuf); return (0); }