+extern void revive_home_server(void *ctx);
+extern void mark_home_server_dead(home_server *home, struct timeval *when);
+
+static int command_set_home_server_state(rad_listen_t *listener, int argc, char *argv[])
+{
+ int last;
+ home_server *home;
+
+ if (argc < 3) {
+ cprintf(listener, "ERROR: Must specify <ipaddr> <port> [proto] <state>\n");
+ return 0;
+ }
+
+ home = get_home_server(listener, argc, argv, &last);
+ if (!home) {
+ return 0;
+ }
+
+ if (strcmp(argv[last], "alive") == 0) {
+ revive_home_server(home);
+
+ } else if (strcmp(argv[last], "dead") == 0) {
+ struct timeval now;
+
+ gettimeofday(&now, NULL); /* we do this WAY too ofetn */
+ mark_home_server_dead(home, &now);
+
+ } else {
+ cprintf(listener, "ERROR: Unknown state \"%s\"\n", argv[last]);
+ return 0;
+ }
+
+ return 1;
+}
+
+static int command_show_home_server_state(rad_listen_t *listener, int argc, char *argv[])
+{
+ home_server *home;
+
+ home = get_home_server(listener, argc, argv, NULL);
+ if (!home) {
+ return 0;
+ }
+
+ switch (home->state) {
+ case HOME_STATE_ALIVE:
+ cprintf(listener, "alive\n");
+ break;
+
+ case HOME_STATE_IS_DEAD:
+ cprintf(listener, "dead\n");
+ break;
+
+ case HOME_STATE_ZOMBIE:
+ cprintf(listener, "zombie\n");
+ break;
+
+ default:
+ cprintf(listener, "unknown\n");
+ break;
+ }
+
+ return 1;
+}
+#endif
+
+/*
+ * For encode/decode stuff
+ */
+static int null_socket_dencode(UNUSED rad_listen_t *listener, UNUSED REQUEST *request)
+{
+ return 0;
+}
+
+static int null_socket_send(UNUSED rad_listen_t *listener, REQUEST *request)
+{
+ char *output_file;
+ FILE *fp;
+ VALUE_PAIR *vp;
+
+ output_file = request_data_reference(request, null_socket_send, 0);
+ if (!output_file) {
+ radlog(L_ERR, "WARNING: No output file for injected packet %d",
+ request->number);
+ return 0;
+ }
+
+ fp = fopen(output_file, "w");
+ if (!fp) {
+ radlog(L_ERR, "Failed to send injected file to %s: %s",
+ output_file, strerror(errno));
+ return 0;
+ }
+
+ if (request->reply->code != 0) {
+ const char *what = "reply";
+ char buffer[1024];
+
+ if (request->reply->code < FR_MAX_PACKET_CODE) {
+ what = fr_packet_codes[request->reply->code];
+ }
+
+ fprintf(fp, "%s\n", what);
+
+ if (debug_flag) {
+ request->radlog(L_DBG, 0, request,
+ "Injected %s packet to host %s port 0 code=%d, id=%d",
+ what,
+ inet_ntop(request->reply->src_ipaddr.af,
+ &request->reply->src_ipaddr.ipaddr,
+ buffer, sizeof(buffer)),
+ request->reply->code, request->reply->id);
+ }
+
+ for (vp = request->reply->vps; vp != NULL; vp = vp->next) {
+ vp_prints(buffer, sizeof(buffer), vp);
+ fprintf(fp, "%s\n", buffer);
+ if (debug_flag) {
+ request->radlog(L_DBG, 0, request, "\t%s",
+ buffer);
+ }
+ }
+ }
+ fclose(fp);
+
+ return 0;
+}
+
+static int command_inject_to(rad_listen_t *listener, int argc, char *argv[])
+{
+ int port;
+ RAD_LISTEN_TYPE type;
+ fr_command_socket_t *sock = listener->data;
+ fr_ipaddr_t ipaddr;
+ rad_listen_t *found = NULL;
+
+ if (argc < 1) {
+ cprintf(listener, "ERROR: Must specify [auth/acct]\n");
+ return 0;
+ }
+
+ if (strcmp(argv[0], "auth") == 0) {
+ type = RAD_LISTEN_AUTH;
+
+ } else if (strcmp(argv[0], "acct") == 0) {
+#ifdef WITH_ACCOUNTING
+ type = RAD_LISTEN_ACCT;
+#else
+ cprintf(listener, "ERROR: This server was built without accounting support.\n");
+ return 0;
+#endif
+
+ } else {
+ cprintf(listener, "ERROR: Unknown socket type\n");
+ return 0;
+ }
+
+ if (argc < 3) {
+ cprintf(listener, "ERROR: No <ipaddr> <port> was given\n");
+ return 0;
+ }
+
+ /*
+ * FIXME: Look for optional arg 4, and bind interface.
+ */
+
+ if (ip_hton(argv[1], AF_UNSPEC, &ipaddr) < 0) {
+ cprintf(listener, "ERROR: Failed parsing IP address; %s\n",
+ fr_strerror());
+ return 0;
+ }
+ port = atoi(argv[2]);
+
+ found = listener_find_byipaddr(&ipaddr, port);
+ if (!found) {
+ cprintf(listener, "ERROR: Could not find matching listener\n");
+ return 0;
+ }
+
+ sock->inject_listener = found;
+ sock->dst_ipaddr = ipaddr;
+ sock->dst_port = port;
+
+ return 1;
+}
+
+static int command_inject_from(rad_listen_t *listener, int argc, char *argv[])
+{
+ RADCLIENT *client;
+ fr_command_socket_t *sock = listener->data;
+
+ if (argc < 1) {
+ cprintf(listener, "ERROR: No <ipaddr> was given\n");
+ return 0;
+ }
+
+ if (!sock->inject_listener) {
+ cprintf(listener, "ERROR: You must specify \"inject to\" before using \"inject from\"\n");
+ return 0;
+ }
+
+ sock->src_ipaddr.af = AF_UNSPEC;
+ if (ip_hton(argv[0], AF_UNSPEC, &sock->src_ipaddr) < 0) {
+ cprintf(listener, "ERROR: Failed parsing IP address; %s\n",
+ fr_strerror());
+ return 0;
+ }
+
+ client = client_listener_find(sock->inject_listener, &sock->src_ipaddr,
+ 0);
+ if (!client) {
+ cprintf(listener, "ERROR: No such client %s\n", argv[0]);
+ return 0;
+ }
+ sock->inject_client = client;
+
+ return 1;
+}
+
+static int command_inject_file(rad_listen_t *listener, int argc, char *argv[])
+{
+ static int inject_id = 0;
+ int filedone;
+ fr_command_socket_t *sock = listener->data;
+ rad_listen_t *fake;
+ REQUEST *request = NULL;
+ RADIUS_PACKET *packet;
+ VALUE_PAIR *vp;
+ FILE *fp;
+ RAD_REQUEST_FUNP fun = NULL;
+ char buffer[2048];