/* Wait for the client request for the server to execute some packet events. */ static int wire_server_receive_packets_start(struct wire_server *wire_server) { enum wire_op_t op = WIRE_INVALID; void *buf = NULL; int buf_len = -1; struct wire_packets_start start; if (wire_conn_read(wire_server->wire_conn, &op, &buf, &buf_len)) return STATUS_ERR; if (op != WIRE_PACKETS_START) { fprintf(stderr, "bad wire client: expected WIRE_PACKETS_START\n"); return STATUS_ERR; } if (buf_len != sizeof(start)) { fprintf(stderr, "bad wire client: bad WIRE_PACKETS_START length\n"); return STATUS_ERR; } memcpy(&start, buf, sizeof(start)); if (ntohl(start.num_events) != wire_server->num_events) { fprintf(stderr, "bad client event count; expected %d but got %d", wire_server->num_events, ntohl(start.num_events)); return STATUS_ERR; } return STATUS_OK; }
/* Receive the script we're about to run. */ static int wire_server_receive_script(struct wire_server *wire_server) { enum wire_op_t op = WIRE_INVALID; void *buf = NULL; int buf_len = -1; if (wire_conn_read(wire_server->wire_conn, &op, &buf, &buf_len)) return STATUS_ERR; if (op != WIRE_SCRIPT) { fprintf(stderr, "bad wire client: expected WIRE_SCRIPT\n"); return STATUS_ERR; } wire_server->script_buffer = strndup(buf, buf_len); return STATUS_OK; }
/* Receive a WIRE_COMMAND_LINE_ARGS message */ static int wire_server_receive_args(struct wire_server *wire_server) { enum wire_op_t op = WIRE_INVALID; void *buf = NULL; int buf_len = -1; if (wire_conn_read(wire_server->wire_conn, &op, &buf, &buf_len)) return STATUS_ERR; if (op != WIRE_COMMAND_LINE_ARGS) { fprintf(stderr, "bad wire client: expected WIRE_COMMAND_LINE_ARGS\n"); return STATUS_ERR; } wire_server_unserialize_argv(wire_server, buf, buf_len); return STATUS_OK; }
/* Receive server's message that the server is ready to execute the script. */ static void wire_client_receive_server_ready(struct wire_client *wire_client) { enum wire_op_t op = WIRE_INVALID; void *buf = NULL; int buf_len = -1; if (wire_conn_read(wire_client->wire_conn, &op, &buf, &buf_len)) wire_client_die(wire_client, "error reading WIRE_SERVER_READY"); if (op != WIRE_SERVER_READY) { wire_client_die(wire_client, "bad wire server: expected WIRE_SERVER_READY"); } if (buf_len != 0) { wire_client_die(wire_client, "bad wire server: bad WIRE_SERVER_READY len"); } }
/* Wait for the client to say it's starting script execution. */ static int wire_server_receive_client_starting(struct wire_server *wire_server) { enum wire_op_t op = WIRE_INVALID; void *buf = NULL; int buf_len = -1; if (wire_conn_read(wire_server->wire_conn, &op, &buf, &buf_len)) return STATUS_ERR; if (op != WIRE_CLIENT_STARTING) { fprintf(stderr, "bad wire client: expected WIRE_CLIENT_STARTING\n"); return STATUS_ERR; } if (buf_len != 0) { fprintf(stderr, "bad wire client: bad WIRE_CLIENT_STARTING length\n"); return STATUS_ERR; } return STATUS_OK; }
/* Receive the ethernet address to which the server should send packets. */ static int wire_server_receive_hw_address(struct wire_server *wire_server) { enum wire_op_t op = WIRE_INVALID; void *buf = NULL; int buf_len = -1; if (wire_conn_read(wire_server->wire_conn, &op, &buf, &buf_len)) return STATUS_ERR; if (op != WIRE_HARDWARE_ADDR) { fprintf(stderr, "bad wire client: expected WIRE_HARDWARE_ADDR\n"); return STATUS_ERR; } if (buf_len != sizeof(wire_server->client_ether_addr)) { fprintf(stderr, "bad wire client: bad hw address length\n"); return STATUS_ERR; } ether_copy(&wire_server->client_ether_addr, buf); return STATUS_OK; }
/* Receive a message from the server that the server is done executing * some packet events. Print any warnings we receive along the way. */ static void wire_client_receive_packets_done(struct wire_client *wire_client) { enum wire_op_t op; struct wire_packets_done done; void *buf = NULL; int buf_len = -1; DEBUGP("wire_client_receive_packets_done\n"); while (1) { if (wire_conn_read(wire_client->wire_conn, &op, &buf, &buf_len)) wire_client_die(wire_client, "error reading"); if (op == WIRE_PACKETS_DONE) break; else if (op == WIRE_PACKETS_WARN) { /* NULL-terminate the warning and print it. */ char *warning = strndup(buf, buf_len); fprintf(stderr, "%s", warning); free(warning); } else { wire_client_die( wire_client, "bad wire server: expected " "WIRE_PACKETS_DONE or WIRE_PACKETS_WARN"); } } if (buf_len < sizeof(done) + 1) { wire_client_die(wire_client, "bad wire server: bad WIRE_PACKETS_DONE len"); } if (((char *)buf)[buf_len - 1] != '\0') { wire_client_die(wire_client, "bad wire server: missing string terminator"); } memcpy(&done, buf, sizeof(done)); if (ntohl(done.result) == STATUS_ERR) { /* Die with the error message from the server, which * is a C string following the fixed "done" message. */ die("%s", (char *)(buf + sizeof(done))); } else if (ntohl(done.num_events) != wire_client->num_events) { char *msg = NULL; #ifdef ECOS int len = strlen("bad wire server: bad message count: got: vs expected: ") + 16; msg = malloc(len); snprintf(msg, len, "bad wire server: bad message count: got: %d vs expected: %d", ntohl(done.num_events), wire_client->num_events); #else asprintf(&msg, "bad wire server: bad message count: " "got: %d vs expected: %d", ntohl(done.num_events), wire_client->num_events); #endif wire_client_die(wire_client, msg); } }