static int get_port(int s, struct lldpd_port *port, char *interface, int nb) { struct hmsg *h; void *p; if ((h = (struct hmsg *)malloc(MAX_HMSGSIZE)) == NULL) fatal(NULL); ctl_msg_init(h, HMSG_GET_PORT); strlcpy((char *)&h->data, interface, IFNAMSIZ); memcpy((char*)&h->data + IFNAMSIZ, &nb, sizeof(int)); h->hdr.len += IFNAMSIZ + sizeof(int); if (ctl_msg_send(s, h) == -1) fatalx("get_port: unable to send request to get port"); if (ctl_msg_recv(s, h) == -1) fatalx("get_port: unable to receive answer to get port"); if (h->hdr.type == HMSG_NONE) /* No port */ return -1; p = &h->data; if (ctl_msg_unpack_structure(STRUCT_LLDPD_PORT, port, sizeof(struct lldpd_port), h, &p) == -1) { LLOG_WARNX("unable to retrieve port information for %s", interface); fatalx("get_chassis: abort"); } return 1; }
int ctl_msg_send_recv(int fd, enum hmsg_type type, void *input, struct marshal_info *input_mi, void **output, struct marshal_info *output_mi) { int n, input_len = 0; void *input_buffer = NULL; void *serialized = NULL; enum hmsg_type received_type; /* Serialize */ if (input) { input_len = marshal_serialize_(input_mi, input, &input_buffer, 0, NULL, 0); if (input_len <= 0) { LLOG_WARNX("unable to serialize input data"); return -1; } } /* Send request */ if (ctl_msg_send(fd, type, input_buffer, input_len) == -1) { LLOG_WARN("unable to send request"); goto send_recv_error; } free(input_buffer); input_buffer = NULL; /* Receive answer */ if ((n = ctl_msg_recv(fd, &received_type, &serialized)) == -1) goto send_recv_error; /* Check type */ if (received_type != type) { LLOG_WARNX("incorrect received message type (expected: %d, received: %d)", type, received_type); goto send_recv_error; } /* Unserialize */ if (output == NULL) { free(serialized); return 0; } if (n == 0) { LLOG_WARNX("no payload available in answer"); goto send_recv_error; } if (marshal_unserialize_(output_mi, serialized, n, output, NULL, 0, 0) <= 0) { LLOG_WARNX("unable to deserialize received data"); goto send_recv_error; } /* All done. */ return 0; send_recv_error: free(serialized); free(input_buffer); return -1; }
void get_interfaces(int s, struct interfaces *ifs) { void *p; struct hmsg *h; if ((h = (struct hmsg *)malloc(MAX_HMSGSIZE)) == NULL) fatal(NULL); ctl_msg_init(h, HMSG_GET_INTERFACES); if (ctl_msg_send(s, h) == -1) fatalx("get_interfaces: unable to send request"); if (ctl_msg_recv(s, h) == -1) fatalx("get_interfaces: unable to receive answer"); if (h->hdr.type != HMSG_GET_INTERFACES) fatalx("get_interfaces: unknown answer type received"); p = &h->data; if (ctl_msg_unpack_list(STRUCT_LLDPD_INTERFACE, ifs, sizeof(struct lldpd_interface), h, &p) == -1) fatalx("get_interfaces: unable to retrieve the list of interfaces"); }
static int get_nb_port(int s, char *interface) { struct hmsg *h; int nb; if ((h = (struct hmsg *)malloc(MAX_HMSGSIZE)) == NULL) fatal(NULL); ctl_msg_init(h, HMSG_GET_NB_PORTS); strlcpy((char *)&h->data, interface, IFNAMSIZ); h->hdr.len += IFNAMSIZ; if (ctl_msg_send(s, h) == -1) fatalx("get_nb_port: unable to send request to get number of ports"); if (ctl_msg_recv(s, h) == -1) fatalx("get_nb_port: unable to receive answer to get number of ports"); if (h->hdr.type == HMSG_NONE) return -1; if (h->hdr.len != sizeof(int)) fatalx("get_nb_port: bad message length"); memcpy(&nb, &h->data, sizeof(int)); return nb; }
static int get_vlans(int s, struct vlans *vls, char *interface, int nb) { void *p; struct hmsg *h; if ((h = (struct hmsg *)malloc(MAX_HMSGSIZE)) == NULL) fatal(NULL); ctl_msg_init(h, HMSG_GET_VLANS); strlcpy((char *)&h->data, interface, IFNAMSIZ); memcpy((char*)&h->data + IFNAMSIZ, &nb, sizeof(int)); h->hdr.len += IFNAMSIZ + sizeof(int); if (ctl_msg_send(s, h) == -1) fatalx("get_vlans: unable to send request"); if (ctl_msg_recv(s, h) == -1) fatalx("get_vlans: unable to receive answer"); if (h->hdr.type != HMSG_GET_VLANS) fatalx("get_vlans: unknown answer type received"); p = &h->data; if (ctl_msg_unpack_list(STRUCT_LLDPD_VLAN, vls, sizeof(struct lldpd_vlan), h, &p) == -1) fatalx("get_vlans: unable to retrieve the list of vlans"); return 1; }
int main(int ac, char **av) { int ret, fd, is_server = 1; int peer_fd = 0; if(ac != 2){ printf("start server\n"); }else{ is_server = 0; } if(is_server){ fd = ff_ctl_open(5678); }else{ fd = ff_ctl_open2(av[1], 5678); } struct pollfd *entry, table[8] = {{0}}; for(;;) { entry = table; if(fd){ entry->fd = fd; entry->events = POLLIN|POLLOUT; entry++; } if(peer_fd){ entry->fd = peer_fd; entry->events = POLLIN|POLLOUT; entry++; } do { ret = poll(table, entry - table, 1000); } while (ret < 0); for(entry = table; entry->fd; ++entry){ if(entry->revents & POLLIN){ if(is_server && entry->fd == fd && peer_fd <= 0){ peer_fd = ctl_msg_open(fd); }else{ ctl_msg_recv(); ff_ctl_recv(ctl_msg_cb); } }else if(entry->revents & POLLOUT){ char line[128] = ""; printf("> "); fflush(stdout); fgets(line, sizeof(line), stdin); strip(line); ff_ctl_send_string(2, "cmd", line); ctl_msg_send(); } } } }
static int http_server(void) { int server_fd = 0; int ctrl_fd = 0, ctrl_fd2 = 0; int ret, delay; struct pollfd *poll_table, *poll_entry; HTTPContext *c, *c_next; if(!(poll_table = av_mallocz_array(nb_max_http_connections + 1, sizeof(*poll_table)))) { http_log("Impossible to allocate a poll table handling %d connections.\n", nb_max_http_connections); return -1; } #if defined(PLUGIN_DVB) ctrl_fd = ff_ctl_open(1234); if (ctrl_fd < 0) { av_free(poll_table); return -1; } #endif if (my_http_addr.sin_port) { server_fd = socket_open_listen(&my_http_addr); if (server_fd < 0) { av_free(poll_table); return -1; } } if ( !server_fd) { http_log("HTTP disabled.\n"); av_free(poll_table); return -1; } #if defined(PLUGIN_SSDP) ssdp_fd = mcast_open(ssdp_ip, ssdp_port); if(ssdp_fd <= 0){ http_log("ssdp disabled\n"); } ssdp_notify(ssdp_fd, ssdp_ip, ssdp_port, "ssdp:alive"); #endif http_log("FFserver started.\n"); for(;;) { poll_entry = poll_table; #if defined(PLUGIN_DVB) if(ctrl_fd){ poll_entry->fd = ctrl_fd; poll_entry->events = POLLIN; poll_entry++; } if(ctrl_fd2){ poll_entry->fd = ctrl_fd2; poll_entry->events = POLLIN; if(ctl_msg_pending() > 0){ poll_entry->events |= POLLOUT; } poll_entry++; } #endif if (server_fd) { poll_entry->fd = server_fd; poll_entry->events = POLLIN; poll_entry++; } #if defined(PLUGIN_SSDP) if(ssdp_fd){ poll_entry->fd = ssdp_fd; poll_entry->events = POLLIN; poll_entry++; } #endif /* wait for events on each HTTP handle */ c = first_http_ctx; delay = 1500; while (c != NULL) { int fd; fd = c->fd; switch(c->state) { case HTTPSTATE_SEND_HEADER: c->poll_entry = poll_entry; poll_entry->fd = fd; poll_entry->events = POLLOUT; poll_entry++; break; case HTTPSTATE_SEND_DATA_HEADER: case HTTPSTATE_SEND_DATA: case HTTPSTATE_SEND_DATA_TRAILER: /*for TCP, we output as much as we can*/ c->poll_entry = poll_entry; poll_entry->fd = fd; poll_entry->events = POLLOUT; poll_entry++; break; case HTTPSTATE_WAIT_REQUEST: case HTTPSTATE_RECEIVE_DATA: case HTTPSTATE_WAIT_FEED: /* need to catch errors */ c->poll_entry = poll_entry; poll_entry->fd = fd; poll_entry->events = POLLIN;/* Maybe this will work */ poll_entry++; break; default: c->poll_entry = NULL; break; } c = c->next; } /* wait for an event on one connection. We poll at least every second to handle timeouts */ do { ret = poll(poll_table, poll_entry - poll_table, delay); if (ret < 0 && ff_neterrno() != AVERROR(EAGAIN) && ff_neterrno() != AVERROR(EINTR)) { av_free(poll_table); return -1; } } while (ret < 0); cur_time = av_gettime() / 1000; /* now handle the events */ for(c = first_http_ctx; c != NULL; c = c_next) { c_next = c->next; if (handle_connection(c) < 0) { log_connection(c); close_connection(c); } } poll_entry = poll_table; #if defined(PLUGIN_DVB) if(ctrl_fd){ if(poll_entry->revents & POLLIN){ ctrl_fd2 = ctl_msg_open(ctrl_fd); } poll_entry++; } if(ctrl_fd2 && poll_entry->fd == ctrl_fd2){ if(poll_entry->revents & POLLIN){ ctl_msg_recv(); ff_ctl_recv(ctl_msg_cb); }else if(poll_entry->revents & POLLOUT){ ctl_msg_send(); } poll_entry++; } #endif if(poll_entry->fd != server_fd){ printf("bad entry\n"); } if (server_fd) { if (poll_entry->revents & POLLIN) new_connection(server_fd, 0); poll_entry++; } #if defined(PLUGIN_SSDP) if (ssdp_fd) { if (poll_entry->revents & POLLIN) ssdp_response(ssdp_fd); poll_entry++; } #endif } }