static void _log_printf(log_t *log, cbuf_t cb, FILE *stream, const char *fmt, ...) { va_list ap; int fd = -1; /* If the fd is less than 0 just return since we can't do anything here. * This can happen if a calling program is the one that set up the io. */ if (stream) fd = fileno(stream); if (fd < 0) return; /* If the socket has gone away we just return like all is well. */ if (_fd_writeable(fd) != 1) return; va_start(ap, fmt); if (log->opt.buffered && (cb != NULL)) { char *buf = vxstrfmt(fmt, ap); int len = strlen(buf); int dropped; cbuf_write(cb, buf, len, &dropped); cbuf_read_to_fd(cb, fd, -1); xfree(buf); } else { vfprintf(stream, fmt, ap); } va_end(ap); }
static int certificate_subject_tag (cxml_handler_t* const _h, cxml_tag_t * const tag) { int rc = 0; cert_cxml_handler_t * h = (cert_cxml_handler_t *)_h; // write signer info if (cxml_tag_is_open(tag)){ int len; const char * v = cxml_tag_attr_value(tag, "type"); if(v == NULL){ fprintf(stderr, "Subject type must be set in Certificate profile\n"); return -1; } h->subject_type = STR2ENUM(_subject_type, v); if(h->subject_type < 0) { fprintf(stderr, "%s: Unknown subject type\n", v); return -1; } cint8_write(h->subject_type, &h->ptr, h->end, &rc); v = cxml_tag_attr_value(tag, "name"); len = cstrlen(v); if(0 == cintx_write(len, &h->ptr, h->end, &rc) && len > 0){ cbuf_write(v, len, &h->ptr, h->end, &rc); } bookmark_position(h, tag); }else{ apply_bookmark_size(h, tag); } return rc; }
/* * write data into zio buffer */ static int zio_write_data (zio_t *zio, void *buf, size_t len) { int n = 0; int ndropped = 0; /* * If buffer is empty, first try writing directly to dstfd * to avoid double-copy: */ if (zio_buffer_empty (zio)) { n = write (zio->dstfd, buf, len); if (n < 0) { if (errno == EAGAIN) n = 0; else return (-1); } /* * If we wrote everything, return early */ if (n == len) { if (zio_eof (zio)) zio_close (zio); return (len); } } /* * Otherwise, buffer any remaining data */ if ((len - n) && cbuf_write (zio->buf, buf+n, len-n, &ndropped) < 0) return (-1); return (0); }
/** * Write to a cbuf * * This function is compatible to the glip_write() function and can be used in * backend implementations using a cbuf for storing outgoing data. * * @param[in] buf the buffer to read from * @param[in] size how much data is supposed to be written * @param[in] data that is supposed to be written * @param[out] size_written how much data has been written * * @return 0 if writing was successful * @return any other value indicates failure * * @see glip_write() */ int gb_util_cbuf_write(struct cbuf *buf, size_t size, uint8_t *data, size_t *size_written) { unsigned int buf_size_free = cbuf_free_level(buf); *size_written = (size > buf_size_free ? buf_size_free : size); return cbuf_write(buf, data, *size_written); }
static int attribute_ssp_text(cxml_handler_t* const _h, char * const text, int length) { int rc=0; if(text && length){ cert_cxml_handler_t * h = (cert_cxml_handler_t *)_h; rc = cbuf_write(text, length, &h->ptr, h->end, NULL); } return rc; }
int cbuf_vprintf (cbuf_t* cb, const char* fmt, va_list ap) { size_t cbavail = cbuf_write_available(cb); if (cbavail + 1 > SPRINTBUFSIZE) cbavail = SPRINTBUFSIZE - 1; if (vsnprintf(sprintbuf, cbavail + 1, fmt, ap) >= cbavail + 1) tooshortbuf(sprintbuf, cbavail + 1); return cbuf_write(cb, sprintbuf, strlen(sprintbuf)); }
void sam3_uart_irq(void) { inc_critical_section(); unsigned char c; if (uart_read(UART, &c) == 0) { cbuf_write(&debug_rx_buf, &c, 1, false); cm3_trigger_preempt(); } dec_critical_section(); }
void write_vec_test() { cbuf_t out; u_int8_t small_buf[10]; u_int16_t i16; printf("write_vec_test1: binary BEGIN\n"); cbuf_init(&out, small_buf, sizeof(small_buf), 0, CBUF_FLAG_BINARY); for (i16 = 1; i16 <= 20; i16++) cbuf_write(&out, &i16, sizeof(i16)); cbuf_seg_add(&out); for (i16 = 21; i16 <= 40; i16++) cbuf_write(&out, &i16, sizeof(i16)); cbuf_seg_add(&out); for (i16 = 41; i16 <= 60; i16++) cbuf_write(&out, &i16, sizeof(i16)); cbuf_reset(&out, 0); print_u16(&out, 60); cbuf_print(&out, "out_i16"); cbuf_final(&out); printf("write_vec_test1: binary END\n"); printf("write_vec_test2: BEGIN\n"); cbuf_init(&out, small_buf, sizeof(small_buf), 0, 0); for (i16 = 1; i16 <= 20; i16++) cbuf_write(&out, &i16, sizeof(i16)); cbuf_seg_add(&out); for (i16 = 21; i16 <= 40; i16++) cbuf_write(&out, &i16, sizeof(i16)); cbuf_seg_add(&out); for (i16 = 41; i16 <= 60; i16++) cbuf_write(&out, &i16, sizeof(i16)); cbuf_seg_add(&out); for (i16 = 61; i16 <= 80; i16++) cbuf_write(&out, &i16, sizeof(i16)); cbuf_seg_add(&out); for (i16 = 81; i16 <= 100; i16++) cbuf_write(&out, &i16, sizeof(i16)); cbuf_reset(&out, 0); print_u16(&out, 100); cbuf_print(&out, "out_i16"); cbuf_final(&out); printf("write_vec_test2: END\n"); }
void Cbuf_write(cbuf_t buf, void *buffer, int len) { int rv, dropped = 0; assert(buf); assert(buffer); assert(len > 0); if ((rv = cbuf_write(buf, buffer, len, &dropped)) < 0) ierr_exit("Cbuf_write: %s", strerror(errno)); if (rv != len) ierr_exit("Cbuf_write: incorrect bytes written %d", rv); if (dropped) ierr_dbg("Cbuf_write: dropped %d bytes", dropped); }
static void _recvfrom (cbuf_t cbuf, int fd, struct sockaddr_in *srcaddr) { int n, rv, dropped = 0; uint8_t buf[IPMIPOWER_PACKET_BUFLEN]; struct sockaddr_in from; unsigned int fromlen = sizeof (struct sockaddr_in); do { /* For receive side, ipmi_lan_recvfrom and * ipmi_rmcpplus_recvfrom are identical. So we just use * ipmi_lan_recvfrom for both. * * In event of future change, should use util functions * ipmi_is_ipmi_1_5_packet or ipmi_is_ipmi_2_0_packet * appropriately. */ rv = ipmi_lan_recvfrom (fd, buf, IPMIPOWER_PACKET_BUFLEN, 0, (struct sockaddr *)&from, &fromlen); } while (rv < 0 && errno == EINTR); /* achu & hliebig: * * Premise from ipmitool (http://ipmitool.sourceforge.net/) * * On some OSes (it seems Unixes), the behavior is to not return * port denied errors up to the client for UDP responses (i.e. you * need to timeout). But on some OSes (it seems Windows), the * behavior is to return port denied errors up to the user for UDP * responses via ECONNRESET or ECONNREFUSED. * * If this were just the case, we could return or handle errors * properly and move on. However, it's not the case. * * According to Ipmitool, on some motherboards, both the OS and the * BMC are capable of responding to an IPMI request. That means you * can get an ECONNRESET or ECONNREFUSED, then later on, get your * real IPMI response. * * Our solution is copied from Ipmitool, we'll ignore some specific * errors and try to read again. * * If the ECONNREFUSED or ECONNRESET is from the OS, but we will get * an IPMI response later, the recvfrom later on gets the packet we * want. * * If the ECONNREFUSED or ECONNRESET is from the OS but there is no * BMC (or IPMI disabled, etc.), just do the recvfrom again to * eventually get a timeout, which is the behavior we'd like. */ if (rv < 0 && (errno == ECONNRESET || errno == ECONNREFUSED)) { IPMIPOWER_DEBUG (("ipmi_lan_recvfrom: connection refused: %s", strerror (errno))); return; } if (rv < 0) { IPMIPOWER_ERROR (("ipmi_lan_recvfrom: %s", strerror (errno))); exit (EXIT_FAILURE); } if (!rv) { IPMIPOWER_ERROR (("ipmi_lan_recvfrom: EOF")); exit (EXIT_FAILURE); } /* Don't store if this packet is strange for some reason */ if (from.sin_family != AF_INET || from.sin_addr.s_addr != srcaddr->sin_addr.s_addr) return; /* cbuf should be empty, but if it isn't, empty it */ if (!cbuf_is_empty (cbuf)) { IPMIPOWER_DEBUG (("cbuf not empty, draining")); do { uint8_t tempbuf[IPMIPOWER_PACKET_BUFLEN]; if (cbuf_read (cbuf, tempbuf, IPMIPOWER_PACKET_BUFLEN) < 0) { IPMIPOWER_ERROR (("cbuf_read: %s", strerror (errno))); exit (EXIT_FAILURE); } } while(!cbuf_is_empty (cbuf)); } if ((n = cbuf_write (cbuf, buf, rv, &dropped)) < 0) { IPMIPOWER_ERROR (("cbuf_write: %s", strerror (errno))); exit (EXIT_FAILURE); } if (n != rv) { IPMIPOWER_ERROR (("cbuf_write: rv=%d n=%d", rv, n)); exit (EXIT_FAILURE); } if (dropped) IPMIPOWER_DEBUG (("cbuf_write: read dropped %d bytes", dropped)); }
void write_buffer_test() { cbuf_t out; u_int8_t small_buf[10]; u_int8_t i8; u_int16_t i16; printf("write_buffer_test small_buf: BEGIN\n"); cbuf_init(&out, small_buf, sizeof(small_buf), 0, 0); for (i8 = 1; i8 <= 10; i8++) cbuf_write(&out, &i8, sizeof(i8)); cbuf_reset(&out, 0); print_u8(&out, 10); cbuf_print(&out, "out_i8"); cbuf_final(&out); printf("write_buffer_test: small_buf: END\n"); printf("write_buffer_test alloc_buf: BEGIN\n"); cbuf_init(&out, small_buf, sizeof(small_buf), 0, 0); for (i8 = 1; i8 <= 20; i8++) cbuf_write(&out, &i8, sizeof(i8)); cbuf_reset(&out, 0); print_u8(&out, 20); cbuf_print(&out, "out_i8"); cbuf_final(&out); printf("write_buffer_test: alloc_buf: END\n"); printf("write_buffer_test realloc_buf: BEGIN\n"); cbuf_init(&out, small_buf, sizeof(small_buf), 0, 0); cbuf_print(&out, "out_i16"); for (i16 = 1; i16 <= 200; i16++) cbuf_write(&out, &i16, sizeof(i16)); cbuf_reset(&out, 0); print_u16(&out, 200); cbuf_print(&out, "out_i16"); cbuf_final(&out); printf("write_buffer_test: realloc_buf: END\n"); // the same with empty inital buffer printf("write_buffer_test realloc_buf2: BEGIN\n"); cbuf_init(&out, 0, 0, 0, 0); cbuf_print(&out, "out_i16"); for (i16 = 1; i16 <= 200; i16++) cbuf_write(&out, &i16, sizeof(i16)); cbuf_reset(&out, 0); print_u16(&out, 200); cbuf_print(&out, "out_i16"); cbuf_final(&out); printf("write_buffer_test: realloc_buf2: END\n"); printf("write_buffer_test binary_realloc_buf: BEGIN\n"); cbuf_init(&out, small_buf, sizeof(small_buf), 0, CBUF_FLAG_BINARY); cbuf_print(&out, "out_i16"); for (i16 = 1; i16 <= 200; i16++) cbuf_write(&out, &i16, sizeof(i16)); cbuf_reset(&out, 0); print_u16(&out, 200); cbuf_print(&out, "out_i16"); cbuf_final(&out); printf("write_buffer_test: binary_realloc_buf: END\n"); }
static int _pstdout_print(pstdout_state_t pstate, int internal_to_pstdout, FILE *stream, const char *format, va_list ap) { char *buf = NULL; char *linebuf = NULL; size_t buflen = PSTDOUT_BUFLEN; size_t linebuflen = PSTDOUT_BUFLEN; cbuf_t whichcbuf; uint32_t whichdefaultmask; uint32_t whichprependmask; uint32_t whichbuffermask; uint32_t whichconsolidatemask; char **whichbuffer; unsigned int *whichbufferlen; int wlen; int linelen; int pstate_mutex_locked = 0; int rc, rv = -1; assert(pstate); assert(pstate->magic == PSTDOUT_STATE_MAGIC); assert(pstate->p_stdout); assert(pstate->p_stderr); assert(stream); assert(stream == stdout || stream == stderr); assert(format); assert(ap); if (stream == stdout) { whichcbuf = pstate->p_stdout; whichdefaultmask = PSTDOUT_OUTPUT_STDOUT_DEFAULT; whichprependmask = PSTDOUT_OUTPUT_STDOUT_PREPEND_HOSTNAME; whichbuffermask = PSTDOUT_OUTPUT_BUFFER_STDOUT; whichconsolidatemask = PSTDOUT_OUTPUT_STDOUT_CONSOLIDATE; whichbuffer = &(pstate->buffer_stdout); whichbufferlen = &(pstate->buffer_stdout_len); } else { whichcbuf = pstate->p_stderr; whichdefaultmask = PSTDOUT_OUTPUT_STDERR_DEFAULT; whichprependmask = PSTDOUT_OUTPUT_STDERR_PREPEND_HOSTNAME; whichbuffermask = PSTDOUT_OUTPUT_BUFFER_STDERR; whichconsolidatemask = PSTDOUT_OUTPUT_STDERR_CONSOLIDATE; whichbuffer = &(pstate->buffer_stderr); whichbufferlen = &(pstate->buffer_stderr_len); } while (1) { va_list vacpy; if (!(buf = (char *)realloc(buf, buflen))) { pstdout_errnum = PSTDOUT_ERR_OUTMEM; goto cleanup; } memset(buf, '\0', PSTDOUT_BUFLEN); va_copy(vacpy, ap); wlen = vsnprintf(buf, buflen, format, vacpy); va_end(vacpy); if (wlen < buflen) break; buflen += PSTDOUT_BUFLEN; } if ((rc = pthread_mutex_lock(&(pstate->mutex)))) { if (pstdout_debug_flags & PSTDOUT_DEBUG_STANDARD) fprintf(stderr, "pthread_mutex_lock: %s\n", strerror(rc)); pstdout_errnum = PSTDOUT_ERR_INTERNAL; goto cleanup; } pstate_mutex_locked++; /* Protect from racing output when we are in a Ctrl+C flushing * buffered output situation */ if (!internal_to_pstdout && pstate->no_more_external_output) goto cleanup; if (cbuf_write(whichcbuf, buf, wlen, NULL) < 0) { if (pstdout_debug_flags & PSTDOUT_DEBUG_STANDARD) fprintf(stderr, "cbuf_write: %s\n", strerror(errno)); pstdout_errnum = PSTDOUT_ERR_INTERNAL; goto cleanup; } while (1) { if (!(linebuf = (char *)realloc(linebuf, linebuflen))) { pstdout_errnum = PSTDOUT_ERR_OUTMEM; goto cleanup; } memset(linebuf, '\0', PSTDOUT_BUFLEN); while ((linelen = cbuf_read_line (whichcbuf, linebuf, linebuflen, 1)) > 0) { if (linelen >= linebuflen) break; if (!pstate->hostname || ((pstdout_output_flags & whichdefaultmask) && !(pstdout_output_flags & whichbuffermask) && !(pstdout_output_flags & whichconsolidatemask))) { rv = fprintf(stream, "%s", linebuf); fflush(stream); } else if (pstdout_output_flags & whichprependmask && !(pstdout_output_flags & whichbuffermask) && !(pstdout_output_flags & whichconsolidatemask)) { rv = fprintf(stream, "%s: %s", pstate->hostname, linebuf); fflush(stream); } else if (((pstdout_output_flags & whichdefaultmask) && (pstdout_output_flags & whichbuffermask)) || (pstdout_output_flags & whichconsolidatemask)) { if (!(*whichbuffer = (char *)realloc(*whichbuffer, *whichbufferlen + linelen))) { pstdout_errnum = PSTDOUT_ERR_OUTMEM; goto cleanup; } /* Don't use snprintf, it will truncate b/c "snprintf and vsnprintf do not write more than size bytes (including the trailing '\0'). " */ memcpy(*whichbuffer + *whichbufferlen, linebuf, linelen); *whichbufferlen += linelen; rv = linelen; } else if ((pstdout_output_flags & whichprependmask) && (pstdout_output_flags & whichbuffermask)) { unsigned int hostname_len; unsigned int extra_len; /* + 2 is for the ": " */ hostname_len = strlen(pstate->hostname); extra_len = hostname_len + 2; if (!(*whichbuffer = (char *)realloc(*whichbuffer, *whichbufferlen + linelen + extra_len))) { pstdout_errnum = PSTDOUT_ERR_OUTMEM; goto cleanup; } /* Don't use snprintf, it will truncate b/c "snprintf and vsnprintf do not write more than size bytes (including the trailing '\0'). " */ memcpy(*whichbuffer + *whichbufferlen, pstate->hostname, hostname_len); memcpy(*whichbuffer + *whichbufferlen + hostname_len, ": ", 2); memcpy(*whichbuffer + *whichbufferlen + hostname_len + 2, linebuf, linelen); *whichbufferlen += linelen + extra_len; rv = linelen + extra_len; } else { pstdout_errnum = PSTDOUT_ERR_INTERNAL; return -1; } } if (linelen < 0) { if (pstdout_debug_flags & PSTDOUT_DEBUG_STANDARD) fprintf(stderr, "cbuf_read_line: %s\n", strerror(errno)); pstdout_errnum = PSTDOUT_ERR_INTERNAL; goto cleanup; } if (!linelen) break; linebuflen += PSTDOUT_BUFLEN; } if (rv < 0) rv = 0; pstdout_errnum = PSTDOUT_ERR_SUCCESS; cleanup: if (pstate_mutex_locked) { if ((rc = pthread_mutex_unlock(&(pstate->mutex)))) { if (pstdout_debug_flags & PSTDOUT_DEBUG_STANDARD) fprintf(stderr, "pthread_mutex_unlock: %s\n", strerror(rc)); /* Don't change error code, just move on */ } } free(buf); free(linebuf); return rv; }
void ipmipower_ping_process_pings (int *timeout) { int i, send_pings_flag = 0; struct timeval cur_time, result; unsigned int ms_time; assert (timeout); if (!cmd_args.common_args.hostname) return; if (!cmd_args.ping_interval) return; if (gettimeofday (&cur_time, NULL) < 0) { IPMIPOWER_ERROR (("gettimeofday: %s", strerror (errno))); exit (EXIT_FAILURE); } if (timeval_gt (&cur_time, &next_ping_sends_time) || force_discovery_sweep) { force_discovery_sweep = 0; timeval_add_ms (&cur_time, cmd_args.ping_interval, &next_ping_sends_time); send_pings_flag++; } for (i = 0; i < ics_len; i++) { uint8_t buf[IPMIPOWER_PACKET_BUFLEN]; int ret, len; if (send_pings_flag) { int dropped = 0; memset (buf, '\0', IPMIPOWER_PACKET_BUFLEN); /* deal with packet heuristics */ if (cmd_args.ping_packet_count && cmd_args.ping_percent) { if (ics[i].ping_packet_count_send == cmd_args.ping_packet_count) { if ((((double)(ics[i].ping_packet_count_send - ics[i].ping_packet_count_recv))/ics[i].ping_packet_count_send) > ((double)cmd_args.ping_percent/100)) ics[i].link_state = IPMIPOWER_LINK_STATE_BAD; else ics[i].link_state = IPMIPOWER_LINK_STATE_GOOD; ics[i].ping_packet_count_send = 0; ics[i].ping_packet_count_recv = 0; } } if (cmd_args.ping_consec_count) { if (!ics[i].ping_last_packet_recv_flag) ics[i].ping_consec_count = 0; ics[i].ping_last_packet_recv_flag = 0; } /* must increment count before setting message tag, so we * can check sequence number correctly later on */ ics[i].ping_sequence_number_counter++; /* Workaround * * Some motherboards don't support RMCP ping/pong :-( * * Discovered on Intel Windmill, Quanta Winterfell, and Wiwynn Windmill */ if (cmd_args.common_args.section_specific_workaround_flags & IPMI_PARSE_SECTION_SPECIFIC_WORKAROUND_FLAGS_IPMIPING) { fiid_obj_t obj_rmcp_hdr = NULL; fiid_obj_t obj_lan_session_hdr = NULL; fiid_obj_t obj_lan_msg_hdr = NULL; fiid_obj_t obj_cmd = NULL; if (!(obj_rmcp_hdr = fiid_obj_create (tmpl_rmcp_hdr))) { IPMIPOWER_ERROR (("fiid_obj_create: %s", strerror (errno))); exit (EXIT_FAILURE); } if (!(obj_lan_session_hdr = fiid_obj_create (tmpl_lan_session_hdr))) { IPMIPOWER_ERROR (("fiid_obj_create: %s", strerror (errno))); exit (EXIT_FAILURE); } if (!(obj_lan_msg_hdr = fiid_obj_create (tmpl_lan_msg_hdr_rq))) { IPMIPOWER_ERROR (("fiid_obj_create: %s", strerror (errno))); exit (EXIT_FAILURE); } if (!(obj_cmd = fiid_obj_create (tmpl_cmd_get_channel_authentication_capabilities_rq))) { IPMIPOWER_ERROR (("fiid_obj_create: %s", strerror (errno))); exit (EXIT_FAILURE); } if (fill_rmcp_hdr_ipmi (obj_rmcp_hdr) < 0) { IPMIPOWER_ERROR (("fill_rmcp_hdr_ipmi: %s", strerror (errno))); exit (EXIT_FAILURE); } if (fill_lan_session_hdr (IPMI_AUTHENTICATION_TYPE_NONE, 0, 0, obj_lan_session_hdr) < 0) { IPMIPOWER_ERROR (("fill_lan_session_hdr: %s", strerror (errno))); exit (EXIT_FAILURE); } if (fill_lan_msg_hdr (IPMI_SLAVE_ADDRESS_BMC, IPMI_NET_FN_APP_RQ, IPMI_BMC_IPMB_LUN_BMC, (ics[i].ping_sequence_number_counter % (IPMI_RQ_SEQ_MAX + 1)), obj_lan_msg_hdr) < 0) { IPMIPOWER_ERROR (("fill_lan_msg_hdr: %s", strerror (errno))); exit (EXIT_FAILURE); } if (fill_cmd_get_channel_authentication_capabilities (IPMI_CHANNEL_NUMBER_CURRENT_CHANNEL, IPMI_PRIVILEGE_LEVEL_USER, IPMI_GET_IPMI_V15_DATA, obj_cmd) < 0) { IPMIPOWER_ERROR (("fill_cmd_get_channel_authentication_capabilities: %s", strerror (errno))); exit (EXIT_FAILURE); } if ((len = assemble_ipmi_lan_pkt (obj_rmcp_hdr, obj_lan_session_hdr, obj_lan_msg_hdr, obj_cmd, NULL, 0, buf, IPMIPOWER_PACKET_BUFLEN, IPMI_INTERFACE_FLAGS_DEFAULT)) < 0) { IPMIPOWER_ERROR (("assemble_ipmi_lan_pkt: %s", strerror (errno))); exit (EXIT_FAILURE); } #ifndef NDEBUG if (cmd_args.rmcpdump) { char hdrbuf[DEBUG_UTIL_HDR_BUFLEN]; const char *str_cmd = NULL; str_cmd = ipmi_cmd_str (IPMI_NET_FN_APP_RQ, IPMI_CMD_GET_CHANNEL_AUTHENTICATION_CAPABILITIES); debug_hdr_str (DEBUG_UTIL_TYPE_IPMI_1_5, DEBUG_UTIL_DIRECTION_REQUEST, DEBUG_UTIL_FLAGS_DEFAULT, str_cmd, hdrbuf, DEBUG_UTIL_HDR_BUFLEN); if (ipmi_dump_lan_packet (STDERR_FILENO, ics[i].hostname, hdrbuf, NULL, buf, len, tmpl_lan_msg_hdr_rq, tmpl_cmd_get_channel_authentication_capabilities_rq) < 0) IPMIPOWER_DEBUG (("ipmi_dump_lan_packet: %s", strerror (errno))); } #endif /* NDEBUG */ fiid_obj_destroy (obj_rmcp_hdr); fiid_obj_destroy (obj_lan_session_hdr); fiid_obj_destroy (obj_lan_msg_hdr); fiid_obj_destroy (obj_cmd); } else /* !IPMI_PARSE_SECTION_SPECIFIC_WORKAROUND_FLAGS_IPMIPING */ { fiid_obj_t rmcp_hdr = NULL; fiid_obj_t rmcp_ping = NULL; if (!(rmcp_hdr = fiid_obj_create (tmpl_rmcp_hdr))) { IPMIPOWER_ERROR (("fiid_obj_create: %s", strerror (errno))); exit (EXIT_FAILURE); } if (!(rmcp_ping = fiid_obj_create (tmpl_cmd_asf_presence_ping))) { IPMIPOWER_ERROR (("fiid_obj_create: %s", strerror (errno))); exit (EXIT_FAILURE); } if (fill_rmcp_hdr_asf (rmcp_hdr) < 0) { IPMIPOWER_ERROR (("fill_rmcp_hdr_asf: %s", strerror (errno))); exit (EXIT_FAILURE); } if (fill_cmd_asf_presence_ping ((ics[i].ping_sequence_number_counter % (RMCP_ASF_MESSAGE_TAG_MAX + 1)), rmcp_ping) < 0) { IPMIPOWER_ERROR (("fill_cmd_asf_presence_ping: %s", strerror (errno))); exit (EXIT_FAILURE); } if ((len = assemble_rmcp_pkt (rmcp_hdr, rmcp_ping, buf, IPMIPOWER_PACKET_BUFLEN, IPMI_INTERFACE_FLAGS_DEFAULT)) < 0) { IPMIPOWER_ERROR (("assemble_rmcp_pkt: %s", strerror (errno))); exit (EXIT_FAILURE); } #ifndef NDEBUG if (cmd_args.rmcpdump) { char hdrbuf[DEBUG_UTIL_HDR_BUFLEN]; debug_hdr_str (DEBUG_UTIL_TYPE_NONE, DEBUG_UTIL_DIRECTION_NONE, DEBUG_UTIL_FLAGS_DEFAULT, DEBUG_UTIL_RMCPPING_STR, hdrbuf, DEBUG_UTIL_HDR_BUFLEN); if (ipmi_dump_rmcp_packet (STDERR_FILENO, ics[i].hostname, hdrbuf, NULL, buf, len, tmpl_cmd_asf_presence_ping) < 0) IPMIPOWER_DEBUG (("ipmi_dump_rmcp_packet: %s", strerror (errno))); } #endif /* NDEBUG */ fiid_obj_destroy (rmcp_hdr); fiid_obj_destroy (rmcp_ping); } /* !IPMI_PARSE_SECTION_SPECIFIC_WORKAROUND_FLAGS_IPMIPING */ if ((ret = cbuf_write (ics[i].ping_out, buf, len, &dropped)) < 0) { IPMIPOWER_ERROR (("cbuf_write: %s", strerror (errno))); exit (EXIT_FAILURE); } if (ret != len) { IPMIPOWER_ERROR (("cbuf_write: incorrect bytes written %d", ret)); exit (EXIT_FAILURE); } if (dropped) IPMIPOWER_DEBUG (("cbuf_write: dropped %d bytes", dropped)); ics[i].last_ping_send.tv_sec = cur_time.tv_sec; ics[i].last_ping_send.tv_usec = cur_time.tv_usec; if (cmd_args.ping_packet_count && cmd_args.ping_percent) ics[i].ping_packet_count_send++; } /* Did we receive something? */ memset (buf, '\0', IPMIPOWER_PACKET_BUFLEN); len = ipmipower_cbuf_peek_and_drop (ics[i].ping_in, buf, IPMIPOWER_PACKET_BUFLEN); if (len > 0) { uint8_t message_type = 0, ipmi_supported = 0; uint64_t val; /* Workaround * * Some motherboards don't support RMCP ping/pong :-( * * Discovered on Intel Windmill, Quanta Winterfell, and Wiwynn Windmill */ if (cmd_args.common_args.section_specific_workaround_flags & IPMI_PARSE_SECTION_SPECIFIC_WORKAROUND_FLAGS_IPMIPING) { fiid_obj_t obj_rmcp_hdr = NULL; fiid_obj_t obj_lan_session_hdr = NULL; fiid_obj_t obj_lan_msg_hdr = NULL; fiid_obj_t obj_cmd = NULL; fiid_obj_t obj_lan_msg_trlr = NULL; int checksum_ret = 0; int unassemble_ret = 0; int cmd_ret = 0; if (!(obj_rmcp_hdr = fiid_obj_create (tmpl_rmcp_hdr))) { IPMIPOWER_ERROR (("fiid_obj_create: %s", strerror (errno))); exit (EXIT_FAILURE); } if (!(obj_lan_session_hdr = fiid_obj_create (tmpl_lan_session_hdr))) { IPMIPOWER_ERROR (("fiid_obj_create: %s", strerror (errno))); exit (EXIT_FAILURE); } if (!(obj_lan_msg_hdr = fiid_obj_create (tmpl_lan_msg_hdr_rs))) { IPMIPOWER_ERROR (("fiid_obj_create: %s", strerror (errno))); exit (EXIT_FAILURE); } if (!(obj_cmd = fiid_obj_create (tmpl_cmd_get_channel_authentication_capabilities_rs))) { IPMIPOWER_ERROR (("fiid_obj_create: %s", strerror (errno))); exit (EXIT_FAILURE); } if (!(obj_lan_msg_trlr = fiid_obj_create (tmpl_lan_msg_trlr))) { IPMIPOWER_ERROR (("fiid_obj_create: %s", strerror (errno))); exit (EXIT_FAILURE); } #ifndef NDEBUG if (cmd_args.rmcpdump) { char hdrbuf[DEBUG_UTIL_HDR_BUFLEN]; const char *str_cmd = NULL; str_cmd = ipmi_cmd_str (IPMI_NET_FN_APP_RQ, IPMI_CMD_GET_CHANNEL_AUTHENTICATION_CAPABILITIES); debug_hdr_str (DEBUG_UTIL_TYPE_IPMI_1_5, DEBUG_UTIL_DIRECTION_RESPONSE, DEBUG_UTIL_FLAGS_DEFAULT, str_cmd, hdrbuf, DEBUG_UTIL_HDR_BUFLEN); if (ipmi_dump_lan_packet (STDERR_FILENO, ics[i].hostname, hdrbuf, NULL, buf, len, tmpl_lan_msg_hdr_rs, tmpl_cmd_get_channel_authentication_capabilities_rs) < 0) IPMIPOWER_DEBUG (("ipmi_dump_lan_packet: %s", strerror (errno))); } #endif /* NDEBUG */ if ((checksum_ret = ipmi_lan_check_packet_checksum (buf, len)) < 0) { IPMIPOWER_ERROR (("ipmi_lan_check_packet_checksum: %s", strerror (errno))); exit (EXIT_FAILURE); } if (checksum_ret && ((unassemble_ret = unassemble_ipmi_lan_pkt (buf, len, obj_rmcp_hdr, obj_lan_session_hdr, obj_lan_msg_hdr, obj_cmd, obj_lan_msg_trlr, IPMI_INTERFACE_FLAGS_DEFAULT)) < 0)) { IPMIPOWER_ERROR (("unassemble_ipmi_lan_pkt: %s", strerror (errno))); exit (EXIT_FAILURE); } /* achu: check for cmd type, but don't bother checking * sequence numbers or completion code. The fact it * returns is sufficient. We just need to make sure we * get something back from the BMC to ensure the machine * is still there. */ if (checksum_ret && unassemble_ret && ((cmd_ret = ipmi_check_cmd (obj_cmd, IPMI_CMD_GET_CHANNEL_AUTHENTICATION_CAPABILITIES)) < 0)) { IPMIPOWER_ERROR (("ipmi_check_cmd: %s", strerror (errno))); exit (EXIT_FAILURE); } if (checksum_ret && unassemble_ret && cmd_ret) { /* We'll say this is equivalent to what pong response from RMCP */ message_type = RMCP_ASF_MESSAGE_TYPE_PRESENCE_PONG; ipmi_supported = 1; } fiid_obj_destroy (obj_rmcp_hdr); fiid_obj_destroy (obj_lan_session_hdr); fiid_obj_destroy (obj_lan_msg_hdr); fiid_obj_destroy (obj_cmd); fiid_obj_destroy (obj_lan_msg_trlr); } else /* !IPMI_PARSE_SECTION_SPECIFIC_WORKAROUND_FLAGS_IPMIPING */ { fiid_obj_t rmcp_hdr = NULL; fiid_obj_t rmcp_pong = NULL; if (!(rmcp_hdr = fiid_obj_create (tmpl_rmcp_hdr))) { IPMIPOWER_ERROR (("fiid_obj_create: %s", strerror (errno))); exit (EXIT_FAILURE); } if (!(rmcp_pong = fiid_obj_create (tmpl_cmd_asf_presence_pong))) { IPMIPOWER_ERROR (("fiid_obj_create: %s", strerror (errno))); exit (EXIT_FAILURE); } #ifndef NDEBUG if (cmd_args.rmcpdump) { char hdrbuf[DEBUG_UTIL_HDR_BUFLEN]; debug_hdr_str (DEBUG_UTIL_TYPE_NONE, DEBUG_UTIL_DIRECTION_NONE, DEBUG_UTIL_FLAGS_DEFAULT, DEBUG_UTIL_RMCPPING_STR, hdrbuf, DEBUG_UTIL_HDR_BUFLEN); if (ipmi_dump_rmcp_packet (STDERR_FILENO, ics[i].hostname, hdrbuf, NULL, buf, len, tmpl_cmd_asf_presence_pong) < 0) IPMIPOWER_DEBUG (("ipmi_dump_rmcp_packet: %s", strerror (errno))); } #endif /* NDEBUG */ if ((ret = unassemble_rmcp_pkt (buf, len, rmcp_hdr, rmcp_pong, IPMI_INTERFACE_FLAGS_DEFAULT)) < 0) { IPMIPOWER_ERROR (("unassemble_rmcp_pkt: %s", strerror (errno))); exit (EXIT_FAILURE); } if (ret) { /* achu: check for ipmi_support and pong type, but don't * check for message tag. On occassion, I have witnessed * BMCs send message tags "out of sync". For example, you * send 8, BMC returns 7. You send 9, BMC returns 8. We * really don't care if the BMC is out of sync. We just * need to make sure we get something back from the BMC to * ensure the machine is still there. */ if (FIID_OBJ_GET (rmcp_pong, "message_type", &val) < 0) { IPMIPOWER_ERROR (("FIID_OBJ_GET: 'message_type': %s", fiid_obj_errormsg (rmcp_pong))); exit (EXIT_FAILURE); } message_type = val; if (FIID_OBJ_GET (rmcp_pong, "supported_entities.ipmi_supported", &val) < 0) { IPMIPOWER_ERROR (("FIID_OBJ_GET: 'supported_entities.ipmi_supported': %s", fiid_obj_errormsg (rmcp_pong))); exit (EXIT_FAILURE); } ipmi_supported = val; } fiid_obj_destroy (rmcp_hdr); fiid_obj_destroy (rmcp_pong); } if (message_type == RMCP_ASF_MESSAGE_TYPE_PRESENCE_PONG && ipmi_supported) { if (cmd_args.ping_packet_count && cmd_args.ping_percent) ics[i].ping_packet_count_recv++; if (cmd_args.ping_consec_count) { /* Don't increment twice, its possible a previous pong * response was late, and we quickly receive two * pong responses */ if (!ics[i].ping_last_packet_recv_flag) ics[i].ping_consec_count++; ics[i].ping_last_packet_recv_flag++; } if (cmd_args.ping_packet_count && cmd_args.ping_percent) { if (ics[i].link_state == IPMIPOWER_LINK_STATE_GOOD) ics[i].discover_state = IPMIPOWER_DISCOVER_STATE_DISCOVERED; else { if (cmd_args.ping_consec_count && ics[i].ping_consec_count >= cmd_args.ping_consec_count) ics[i].discover_state = IPMIPOWER_DISCOVER_STATE_DISCOVERED; else ics[i].discover_state = IPMIPOWER_DISCOVER_STATE_BADCONNECTION; } } else { ics[i].discover_state = IPMIPOWER_DISCOVER_STATE_DISCOVERED; } ics[i].last_ping_recv.tv_sec = cur_time.tv_sec; ics[i].last_ping_recv.tv_usec = cur_time.tv_usec; } } /* !IPMI_PARSE_SECTION_SPECIFIC_WORKAROUND_FLAGS_IPMIPING */ /* Is the node gone?? */ timeval_sub (&cur_time, &ics[i].last_ping_recv, &result); timeval_millisecond_calc (&result, &ms_time); if (ms_time >= cmd_args.ping_timeout) ics[i].discover_state = IPMIPOWER_DISCOVER_STATE_UNDISCOVERED; } timeval_sub (&next_ping_sends_time, &cur_time, &result); timeval_millisecond_calc (&result, &ms_time); *timeout = ms_time; }
static int attribute_eccpoint_tag (cxml_handler_t* const _h, cxml_tag_t * const tag) { int rc = 0; cert_cxml_handler_t * h = (cert_cxml_handler_t *)_h; int pointtype; if (cxml_tag_is_open(tag)){ const char * v; pointtype = 0; v = cxml_tag_attr_value(tag, "type"); if (v){ pointtype = STR2ENUM(_point_types, v); if (pointtype < 0){ fprintf(stderr, "%s: Unknown point type\n", v); return -1; } if (pointtype == 1) pointtype = 2; } h->pk_ptype = pointtype; h->pk_data = NULL; h->pk_datasize = 0; } else{ void * key = h->key; pointtype = h->pk_ptype; // generate private and public key pair char x[32], y[32]; if (key == NULL){ if (h->pk_data){ if (h->pk_datasize < 32 || (h->pk_datasize < 64 && pointtype == 4)){ fprintf(stderr, "Insufficient size of public key\n"); return -1; } key = ecc_api_key_public_set(h->pk_alg, pointtype, h->pk_data, h->pk_data + 32); } else{ // generate PK if (h->pk_alg < 0 || h->pk_sym_alg < 0){ fprintf(stderr, "Public key algorythm must be specified\n"); return -1; } key = ecc_api_key_gen(h->pk_alg, h->pk_sym_alg); } } if (key){ h->key = key; rc = ecc_api_key_public(key, &x[0], &y[0]); if (rc >= 0){ if (pointtype == 2) pointtype |= (y[31] & 1); cint8_write(pointtype, &h->ptr, h->end, &rc); if (rc == 0)cbuf_write(&x[0], 32, &h->ptr, h->end, &rc); if (rc == 0 && pointtype == 4){ cbuf_write(&y[0], 32, &h->ptr, h->end, &rc); } } } if (h->pk_data){ free(h->pk_data); h->pk_data = NULL; } } return rc; }
static int certificate_signer_tag (cxml_handler_t* const _h, cxml_tag_t * const tag) { int rc = 0; // write signer info cert_cxml_handler_t * h = (cert_cxml_handler_t *)_h; if (cxml_tag_is_open(tag)){ h->signer_type = 1; // digest by default const char * v = cxml_tag_attr_value(tag, "type"); if(v){ h->signer_type = STR2ENUM(_signer_types, v); if(h->signer_type <0){ fprintf(stderr, "%s: Unknown signer type\n", v); return -1; } } cint8_write(h->signer_type, &h->ptr, h->end, &rc); if (h->signer_type > 0){ if (_signerName){ h->signer = _signerName; } else{ v = cxml_tag_attr_value(tag, "name"); if (v == NULL){ fprintf(stderr, "%s: Signer name shall be provided\n", v); return -1; } h->signer = v; } } }else{ // write signer info if (h->signer_type > 0){ if (h->signer_type > 2){ fprintf(stderr, "%d: signer method unsupported\n", h->signer_type); rc = -1; } else{ // load signer certificate int plen = strlen(_searchPath) + strlen(h->signer); char * path = malloc(plen + 16); cvstrncpy(path, plen + 16, _searchPath, "/", h->signer, ".crt", NULL); size_t size = load_certificate(path, h->ptr, h->end); if (size < 0){ fprintf(stderr, "%s: signer certificate not found or error\n", h->signer); rc = -1; } else{ if (h->signer_type == 1){ // digest char hash[sha256_hash_size]; // change eccpoint type of the signature to x_coordinate_only(0) // to follow canonical encoding h->ptr[size-65] = 0; sha256_calculate(hash, h->ptr, size); #ifdef DEBUG_DATA fprintf(stderr, "HASH (%s): ", h->signer); print_x(stderr, hash, sha256_hash_size); fprintf(stderr, "\n"); fprintf(stderr, "DIGEST (%s): ", h->signer); print_x(stderr, &hash[sha256_hash_size - 8], 8); fprintf(stderr, "\n"); #endif cbuf_write(hash + sha256_hash_size - 8, 8, &h->ptr, h->end, &rc); } else {// certificate h->ptr += size; } } free(path); } } } return rc; }
static size_t echo_recv (tcpservice_t* peer, const char* data, size_t len) { return cbuf_write(&peer->send_buffer, data, len); }