int packet_fxp_fsetstat(Buffer *buff, Buffer *preped_buff) { u_int msg_len; u_int xmsg_len; // File names u_int file_len; u_char *handle; // Copy first part of packet over to prepared buffer msg_len = get_u32(buffer_ptr(buff)); xmsg_len = msg_len; buffer_append(preped_buff, buffer_ptr(buff), 9); buffer_consume(buff, 9); xmsg_len -= 5; // Copy handle handle = buffer_get_string(buff, &file_len); buffer_put_string(preped_buff, (char*) handle, file_len); xmsg_len -= (file_len + 4); // Copy attributes through, cleaning extensions where required parse_attrs(buff, preped_buff, &msg_len, &xmsg_len); // Copy any remaining packet data over buffer_append(preped_buff, buffer_ptr(buff), xmsg_len); buffer_consume(buff, xmsg_len); // Rewrite message length put_u32(buffer_end(preped_buff)-msg_len-4, msg_len); return 1; }
void _parse_aiff_comm(Buffer *buf, uint32_t chunk_size, HV *info) { uint16_t channels = buffer_get_short(buf); uint32_t frames = buffer_get_int(buf); uint16_t bits_per_sample = buffer_get_short(buf); double samplerate = buffer_get_ieee_float(buf); my_hv_store( info, "channels", newSVuv(channels) ); my_hv_store( info, "bits_per_sample", newSVuv(bits_per_sample) ); my_hv_store( info, "samplerate", newSVuv(samplerate) ); my_hv_store( info, "bitrate", newSVuv( samplerate * channels * bits_per_sample ) ); my_hv_store( info, "song_length_ms", newSVuv( ((frames * 1.0) / samplerate) * 1000 ) ); my_hv_store( info, "block_align", newSVuv( channels * bits_per_sample / 8 ) ); if (chunk_size > 18) { // AIFC extra data my_hv_store( info, "compression_type", newSVpvn( buffer_ptr(buf), 4 ) ); buffer_consume(buf, 4); my_hv_store( info, "compression_name", newSVpvn( buffer_ptr(buf), chunk_size - 22 ) ); buffer_consume(buf, chunk_size - 22); } }
uint16_t packet_peek_session_id(uint8_t *data, size_t length) { buffer_t *buffer = NULL; uint16_t session_id = -1; /* Create a buffer of the first 5 bytes. */ if(length < 5) { LOG_FATAL("Packet is too short!\n"); return -1; } /* Create a buffer with the first 5 bytes of data. */ buffer = buffer_create_with_data(BO_BIG_ENDIAN, data, 5); /* Discard packet_id. */ buffer_consume(buffer, 2); /* Discard packet_type. */ buffer_consume(buffer, 1); /* Finally, get the session_id. */ session_id = buffer_read_next_int16(buffer); /* Kill the buffer. */ buffer_destroy(buffer); /* Done! */ return session_id; }
static Key * keygrab_ssh1(con *c) { static Key *rsa; static Buffer msg; if (rsa == NULL) { buffer_init(&msg); rsa = key_new(KEY_RSA1); } buffer_append(&msg, c->c_data, c->c_plen); buffer_consume(&msg, 8 - (c->c_plen & 7)); /* padding */ if (buffer_get_char(&msg) != (int) SSH_SMSG_PUBLIC_KEY) { error("%s: invalid packet type", c->c_name); buffer_clear(&msg); return NULL; } buffer_consume(&msg, 8); /* cookie */ /* server key */ (void) buffer_get_int(&msg); buffer_get_bignum(&msg, rsa->rsa->e); buffer_get_bignum(&msg, rsa->rsa->n); /* host key */ (void) buffer_get_int(&msg); buffer_get_bignum(&msg, rsa->rsa->e); buffer_get_bignum(&msg, rsa->rsa->n); buffer_clear(&msg); return (rsa); }
int packet_fxp_realpath(Buffer *buff, Buffer *preped_buff) { u_int msg_len, xmsg_len; u_int file_len; u_char *filename; // Copy first part of packet over to prepared buffer msg_len = get_u32(buffer_ptr(buff)); xmsg_len = msg_len; buffer_append(preped_buff, buffer_ptr(buff), 9); buffer_consume(buff, 9); xmsg_len -= 5; // Rewrite path filename = buffer_get_string(buff, &file_len); filename = unchroot_filename(filename, (u_char*) user_homedir); buffer_put_cstring(preped_buff, (char*) filename); xmsg_len -= (file_len + 4); msg_len += (strlen((char*) filename) - file_len); // Copy packet over to prepared buffer buffer_append(preped_buff, buffer_ptr(buff), xmsg_len); buffer_consume(buff, xmsg_len); // Replace length with new length put_u32(buffer_end(preped_buff)-msg_len-4, msg_len); return 1; }
int packet_fxp_mkdir(Buffer *buff, Buffer *preped_buff) { u_int msg_len; u_int xmsg_len; // File names u_int file_len; u_char *filename; // Copy first part of packet over to prepared buffer msg_len = get_u32(buffer_ptr(buff)); xmsg_len = msg_len; buffer_append(preped_buff, buffer_ptr(buff), 9); buffer_consume(buff, 9); xmsg_len -= 5; // Rewrite path filename = buffer_get_string(buff, &file_len); filename = unchroot_filename(filename, (u_char*) user_homedir); buffer_put_cstring(preped_buff, (char*) filename); xmsg_len -= (file_len + 4); msg_len += (strlen((char*) filename) - file_len); // Copy attributes through, cleaning extensions where required parse_attrs(buff, preped_buff, &msg_len, &xmsg_len); // Copy any remaining packet data over buffer_append(preped_buff, buffer_ptr(buff), xmsg_len); buffer_consume(buff, xmsg_len); // Rewrite message length put_u32(buffer_end(preped_buff)-msg_len-4, msg_len); return 1; }
int read_and_callback(struct reader *rdr, void *arg) { ssize_t ret; ssize_t i; char *cur; int msglen; cur = rdr->buf->data + rdr->buf->used; /* Read attempt. */ while ((ret = read(*(rdr->fd), cur, buffer_remaining(rdr->buf))) == -1 && errno == EINTR) ; /* EOF or read error. */ if (ret == 0 || ret == -1) return ret; assert(buffer_append(rdr->buf, cur, ret) == 0); /* Process each read character and update internal state. */ for (i = 0; i < ret; ++i) { switch (rdr->state) { case RS_NORMAL: if (*cur == '\n') { /* Callback on new message. */ msglen = cur - rdr->buf->data + 1; if (msglen > 2) /* Nonempty message. */ rdr->cb(*(rdr->fd), rdr->buf->data, msglen, arg); /* Consume message. */ buffer_consume(rdr->buf, msglen); cur = rdr->buf->data; continue; } break; case RS_GREEDY: if (*cur == '\n') { buffer_consume(rdr->buf, cur - rdr->buf->data + 1); cur = rdr->buf->data; rdr->state = RS_NORMAL; continue; } break; } ++cur; } /* Change to greedy mode if buffer filled. */ if (buffer_remaining(rdr->buf) == 0 && rdr->state != RS_GREEDY) rdr->state = RS_GREEDY; /* Discard buffer data if in greedy mode. */ if (rdr->state == RS_GREEDY) buffer_consume(rdr->buf, -1); return ret; }
static int methodline_parse(struct buffer *bu, struct methodline_state *ms, struct buffer *method, struct buffer *uri, struct buffer *version) { const char *s = bu->data; unsigned rem = bu->cur; char ch; while (rem > 0) { ch = *s; s++; rem--; switch (ms->state) { case 0: /* method */ if (ch == ' ') ms->state = 1; else buffer_addch(method, ch); break; case 1: /* uri */ if (ch == ' ') ms->state = 2; else buffer_addch(uri, ch); break; case 2: /* version */ if (ch == '\r') ms->state = 3; else if (isspace(ch)) goto parse_error; else buffer_addch(version, ch); break; case 3: /* CR */ if (ch == '\n') goto complete; else goto parse_error; break; default: assert(0); } } buffer_consume(bu, s - bu->data); return 0; complete: ms->done = true; buffer_consume(bu, s - bu->data); return 0; parse_error: Error("%s():parse failure (%.*s)\n", __func__, bu->cur, bu->data); buffer_consume(bu, s - bu->data); Error("%s():parse failure @ %d (state=%d)\n", __func__, bu->cur, ms->state); return -1; }
// Parses body. Returns true iff progress was made. bool frameparser_parse_body(frameparser *fp, buffer *b) { log_printf(LOG_LEVEL_DEBUG, "frameparser_parse_body\n"); if (fp->length_left == FP_LENGTH_UNKNOWN) { // Look for NUL terminator int nulpos = buffer_find_byte(b, '\x00'); if (nulpos < 0) { // No NUL, so grab everything int count = buffer_get_length(b); bytestring *body = frame_ensure_body(fp->cur_frame); buffer_append_bytestring(b, body, 0, count); buffer_consume(b, count); return true; } else if (nulpos == 0) { // NUL as next character, so the frame is complete fp->state = FP_STATE_END; return true; } else { // NUL after some other bytes, so grab them and the frame is complete bytestring *body = frame_ensure_body(fp->cur_frame); buffer_append_bytestring(b, body, 0, nulpos); buffer_consume(b, nulpos); fp->state = FP_STATE_END; return true; } } else { // Remaining length is known. Figure out how many bytes to grab. int count = buffer_get_length(b); if (fp->length_left < count) count = fp->length_left; // Grab the bytes bytestring *body = frame_ensure_body(fp->cur_frame); buffer_append_bytestring(b, body, 0, count); buffer_consume(b, count); fp->length_left -= count; // If we satisfied the expected length then the frame is complete if (fp->length_left == 0) fp->state = FP_STATE_END; return true; } }
int packet_fxp_init(Buffer *buff, Buffer *preped_buff) { u_char *cp; u_int msg_len; u_int xmsg_len; u_int msg_ver; cp = buffer_ptr(buff); // 1. Ensure extensions are not forwarded. Drop packet size down to 5 bytes + 4 byte length. Later byte are ignored through buffer_consume. msg_len = get_u32(cp); xmsg_len = 5; put_u32(cp, xmsg_len); // 2. Ensure client version number presented is not greater than that supported. cp += 5; msg_ver = get_u32(cp); if (msg_ver > 3) msg_ver = 3; put_u32(cp, msg_ver); // Copy packet over to prepared buffer buffer_append(preped_buff, buffer_ptr(buff), xmsg_len + sizeof(u_int)); buffer_consume(buff, msg_len + sizeof(u_int)); return 1; }
static boolean buf_src_fill_input_buffer(j_decompress_ptr cinfo) { static JOCTET mybuffer[4]; buf_src_mgr *src = (buf_src_mgr *)cinfo->src; // Consume the entire buffer, even if bytes are still in bytes_in_buffer buffer_consume(src->buf, buffer_len(src->buf)); if (!buffer_check_load(src->buf, src->fp, 1, BUF_SIZE)) goto eof; cinfo->src->next_input_byte = (JOCTET *)buffer_ptr(src->buf); cinfo->src->bytes_in_buffer = buffer_len(src->buf); goto ok; eof: // Insert a fake EOI marker if we can't read enough data LOG_DEBUG(" EOF filling input buffer, returning EOI marker\n"); mybuffer[0] = (JOCTET)0xFF; mybuffer[1] = (JOCTET)JPEG_EOI; cinfo->src->next_input_byte = mybuffer; cinfo->src->bytes_in_buffer = 2; ok: return TRUE; }
static int monitor_valid_userblob(u_char *data, u_int datalen) { Buffer b; u_char *p; char *userstyle, *cp; u_int len; int fail = 0; buffer_init(&b); buffer_append(&b, data, datalen); if (datafellows & SSH_OLD_SESSIONID) { p = buffer_ptr(&b); len = buffer_len(&b); if ((session_id2 == NULL) || (len < session_id2_len) || (timingsafe_bcmp(p, session_id2, session_id2_len) != 0)) fail++; buffer_consume(&b, session_id2_len); } else { p = buffer_get_string(&b, &len); if ((session_id2 == NULL) || (len != session_id2_len) || (timingsafe_bcmp(p, session_id2, session_id2_len) != 0)) fail++; free(p); } if (buffer_get_char(&b) != SSH2_MSG_USERAUTH_REQUEST) fail++; cp = buffer_get_cstring(&b, NULL); xasprintf(&userstyle, "%s%s%s", authctxt->user, authctxt->style ? ":" : "", authctxt->style ? authctxt->style : ""); if (strcmp(userstyle, cp) != 0) { logit("wrong user name passed to monitor: " "expected %s != %.100s", userstyle, cp); fail++; } free(userstyle); free(cp); buffer_skip_string(&b); if (datafellows & SSH_BUG_PKAUTH) { if (!buffer_get_char(&b)) fail++; } else { cp = buffer_get_cstring(&b, NULL); if (strcmp("publickey", cp) != 0) fail++; free(cp); if (!buffer_get_char(&b)) fail++; buffer_skip_string(&b); } buffer_skip_string(&b); if (buffer_len(&b) != 0) fail++; buffer_free(&b); return (fail == 0); }
// Parses trailing NUL character. Returns true iff progress was made. bool frameparser_parse_end(frameparser *fp, buffer *b) { // Valid input in this state is simply a single NUL character log_printf(LOG_LEVEL_DEBUG, "frameparser_parse_end\n"); // If there is already a parsed frame that hasn't been picked up yet, we // don't want to overwrite it, so refrain from finishing this frame. if (fp->fin_frame) return false; // No progress // Check for the NUL uint8_t byte = buffer_get_byte(b, 0); if (byte != '\x00') { frameparser_set_error(fp, "Expected trailing NUL at end of frame"); return false; } // Consume it buffer_consume(b, 1); // All done with the current frame fp->fin_frame = fp->cur_frame; fp->cur_frame = NULL; fp->state = FP_STATE_IDLE; return true; }
void SFTP::send_msg(Buffer *m) { size_t mlen = buffer_len(m); toChannel->put (buffer_ptr (m), mlen); buffer_consume(m, mlen); }
static int image_gif_read_buf(GifFileType *gif, GifByteType *data, int len) { image *im = (image *)gif->UserData; //DEBUG_TRACE("GIF read_buf wants %d bytes, %d in buffer\n", len, buffer_len(im->buf)); if (im->fh != NULL) { if ( !_check_buf(im->fh, im->buf, len, MAX(len, BUFFER_SIZE)) ) { warn("Image::Scale not enough GIF data (%s)\n", SvPVX(im->path)); return 0; } } else { if (len > buffer_len(im->buf)) { // read from SV into buffer int sv_readlen = len - buffer_len(im->buf); if (sv_readlen > sv_len(im->sv_data) - im->sv_offset) { warn("Image::Scale not enough GIF data (%s)\n", SvPVX(im->path)); return 0; } DEBUG_TRACE(" Reading %d bytes of SV data @ %d\n", sv_readlen, im->sv_offset); buffer_append(im->buf, SvPVX(im->sv_data) + im->sv_offset, sv_readlen); im->sv_offset += sv_readlen; } } memcpy(data, buffer_ptr(im->buf), len); buffer_consume(im->buf, len); return len; }
void *consumer_function(void *b) { buffer *buff = (buffer *)b; int i; for (i = 0; i < 100; i++) { pthread_mutex_lock(buff->mut); if(buff->empty) { printf("buffer empty, waiting...\n"); pthread_cond_wait(buff->notEmpty, buff->mut); } int consumed = buffer_consume(buff); printf("consumed %d\n", consumed); pthread_mutex_unlock(buff->mut); /* Sleep either 1s or 5s (50% chance for each) */ if (generate_random_number(99) < 50) { usleep(1000000); } else { usleep(5000000); } } return NULL; }
static void _parse_wav_peak(ScanData s, Buffer *buf, uint32_t chunk_size, uint8_t big_endian) { uint16_t channels = 0; AV *peaklist = newAV(); SV **entry = my_hv_fetch( info, "channels" ); if ( entry != NULL ) { channels = SvIV(*entry); } // Skip version/timestamp buffer_consume(buf, 8); while ( channels-- ) { HV *peak = newHV(); my_hv_store( peak, "value", newSVnv( big_endian ? buffer_get_float32(buf) : buffer_get_float32_le(buf) ) ); my_hv_store( peak, "position", newSVuv( big_endian ? buffer_get_int(buf) : buffer_get_int_le(buf) ) ); av_push( peaklist, newRV_noinc( (SV *)peak) ); } my_hv_store( info, "peak", newRV_noinc( (SV *)peaklist ) ); }
/* scans forward to the next aac frame and makes sure * the entire frame is in the buffer. */ static int buffer_fill_frame(struct aac_data *data) { unsigned char *datap; int rc, n, len; int max = 32768; while (1) { /* need at least 6 bytes of data */ rc = buffer_fill_min(data, 6); if (rc <= 0) break; len = buffer_length(data); datap = buffer_data(data); /* scan for a frame */ for (n = 0; n < len - 5; n++) { /* give up after 32KB */ if (max-- == 0) { logit ("no frame found!"); /* FIXME: set errno? */ return -1; } /* see if there's a frame at this location */ rc = parse_frame(datap + n); if (rc == 0) continue; /* found a frame, consume all data up to the frame */ buffer_consume (data, n); /* rc == frame length */ rc = buffer_fill_min (data, rc); if (rc <= 0) goto end; return 1; } /* consume what we used */ buffer_consume (data, n); } end: return rc; }
void buffer_add(bufferADT buffer, char c) { if(buffer_is_full(buffer)) { buffer_consume(buffer); } buffer->mem_start[buffer->head] = c; buffer->head = buffer_next_index(buffer, buffer->head); }
char * octstr_drop(octstr_t *octstr, size_t n) { assert(octstr != NULL); buffer_consume(octstr->buf, n); return buffer_ptr(octstr->buf); }
static void send_msg(Buffer *m) { int mlen = buffer_len(m); buffer_put_int(&oqueue, mlen); buffer_append(&oqueue, buffer_ptr(m), mlen); buffer_consume(m, mlen); }
char *buffer_readline(buffer_t *buffer) { char *newline = memchr(buffer->data + buffer->offset, '\n', buffer->len - buffer->offset); if(!newline) return NULL; int len = newline + 1 - (buffer->data + buffer->offset); *newline = 0; return buffer_consume(buffer, len); }
static int monitor_valid_userblob(u_char *data, u_int datalen) { Buffer b; char *p; u_int len; int fail = 0; buffer_init(&b); buffer_append(&b, data, datalen); if (datafellows & SSH_OLD_SESSIONID) { p = buffer_ptr(&b); len = buffer_len(&b); if ((session_id2 == NULL) || (len < session_id2_len) || (memcmp(p, session_id2, session_id2_len) != 0)) fail++; buffer_consume(&b, session_id2_len); } else { p = buffer_get_string(&b, &len); if ((session_id2 == NULL) || (len != session_id2_len) || (memcmp(p, session_id2, session_id2_len) != 0)) fail++; xfree(p); } if (buffer_get_char(&b) != SSH2_MSG_USERAUTH_REQUEST) fail++; p = buffer_get_string(&b, NULL); if (strcmp(authctxt->user, p) != 0) { logit("wrong user name passed to monitor: expected %s != %.100s", authctxt->user, p); fail++; } xfree(p); buffer_skip_string(&b); if (datafellows & SSH_BUG_PKAUTH) { if (!buffer_get_char(&b)) fail++; } else { p = buffer_get_string(&b, NULL); if (strcmp("publickey", p) != 0) fail++; xfree(p); if (!buffer_get_char(&b)) fail++; buffer_skip_string(&b); } buffer_skip_string(&b); if (buffer_len(&b) != 0) fail++; buffer_free(&b); return (fail == 0); }
// Parses a frame's command. Returns true iff progress was made. bool frameparser_parse_command(frameparser *fp, buffer *b) { log_printf(LOG_LEVEL_DEBUG, "frameparser_parse_command\n"); // Valid input in this state is a string followed by CR/LF or LF, which matches a known frame command // Try to find LF line terminator int lfpos = buffer_find_byte(b, '\x0A'); if (lfpos < 0) // No LF yet? { if (buffer_get_length(b) > LIMIT_FRAME_CMD_LINE_LEN) frameparser_set_error(fp, "Line length limit exceeded waiting for command"); return false; // No progress } else if (lfpos == 0) abort(); // Should never happen in this state // Figure out number of bytes in command string int len = lfpos; if (buffer_get_byte(b, len - 1) == '\x0D') len--; // Extract the command into a new bytestring bytestring *bs = bytestring_new(len); buffer_append_bytestring(b, bs, 0, len); bytestring_dump(bs); // Consume the current line buffer_consume(b, lfpos + 1); // Find the command code for this command frame_command cmd = frame_command_code(bytestring_get_bytes(bs), bytestring_get_length(bs)); // Clean up the bytestring bytestring_free(bs); // Make sure command is valid if (cmd == CMD_NONE) { frameparser_set_error(fp, "Unknown command"); return false; } // Set up a new frame structure to hold parsed data if (!fp->cur_frame) fp->cur_frame = frame_new(); // Store parsed data frame_set_command(fp->cur_frame, cmd); // Got a valid command, so headers should be next fp->state = FP_STATE_HEADER; return true; }
/* This should be called with a unique decoder instance as the seeking * it does triggers an FAAD bug which results in distorted audio due to * retained state being corrupted. (One suspects NeAACDecPostSeekReset() * should resolve the problem but experimentation suggests not and no * documentation exists describing its use.) */ static int aac_count_time (struct aac_data *data) { NeAACDecFrameInfo frame_info; int samples = 0, bytes = 0, frames = 0; off_t file_size; int16_t *sample_buf; file_size = io_file_size (data->stream); if (file_size == -1) return -1; if (io_seek(data->stream, file_size / 2, SEEK_SET) == -1) return -1; buffer_flush (data); /* Guess track length by decoding the middle 50 frames which have * more than 25% of samples having absolute values greater than 16. */ while (frames < 50) { if (buffer_fill_frame (data) <= 0) break; sample_buf = NeAACDecDecode (data->decoder, &frame_info, buffer_data (data), buffer_length (data)); if (frame_info.error == 0 && frame_info.samples > 0) { unsigned int ix, zeroes = 0; for (ix = 0; ix < frame_info.samples; ix += 1) { if (RANGE(-16, sample_buf[ix], 16)) zeroes += 1; } if (zeroes * 4 < frame_info.samples) { samples += frame_info.samples; bytes += frame_info.bytesconsumed; frames += 1; } } if (frame_info.bytesconsumed == 0) break; buffer_consume (data, frame_info.bytesconsumed); } if (frames == 0) return -1; samples /= frames; samples /= data->channels; bytes /= frames; return ((file_size / bytes) * samples) / data->sample_rate; }
int packet_fxp_symlink(Buffer *buff, Buffer *preped_buff) { u_int msg_len; u_int xmsg_len; // File names u_int file_len; u_char *filename; // Copy first part of packet over to prepared buffer msg_len = get_u32(buffer_ptr(buff)); xmsg_len = msg_len; buffer_append(preped_buff, buffer_ptr(buff), 9); buffer_consume(buff, 9); xmsg_len -= 5; // Rewrite link path filename = buffer_get_string(buff, &file_len); filename = unchroot_filename(filename, (u_char*) user_homedir); buffer_put_cstring(preped_buff, (char*) filename); xmsg_len -= (file_len + 4); msg_len += (strlen((char*) filename) - file_len); // Rewrite target path filename = buffer_get_string(buff, &file_len); filename = unchroot_filename(filename, (u_char*) user_homedir); buffer_put_cstring(preped_buff, (char*) filename); xmsg_len -= (file_len + 4); msg_len += (strlen((char*) filename) - file_len); // Copy any remaining packet data over buffer_append(preped_buff, buffer_ptr(buff), xmsg_len); buffer_consume(buff, xmsg_len); // Rewrite message length put_u32(buffer_end(preped_buff)-msg_len-4, msg_len); return 1; }
static void send_msg(Buffer *m) { u_char buf[4]; int mlen = buffer_len(m); put_u32(buf, mlen); if (atomicio(vwrite, fd, buf, 4) != 4 || atomicio(vwrite, fd, buffer_ptr(m), buffer_len(m)) != buffer_len(m)) error("write to helper failed"); buffer_consume(m, mlen); }
int packet_fxp_readlink(Buffer *buff, Buffer *preped_buff) { u_int msg_len; u_int xmsg_len; // 1. Rewrite the filename requested to the users home directory. Ensure the packet length is updated. msg_len = get_u32(buffer_ptr(buff)); xmsg_len = msg_len; // Copy packet over to prepared buffer buffer_append(preped_buff, buffer_ptr(buff), xmsg_len + sizeof(u_int)); buffer_consume(buff, msg_len + sizeof(u_int)); return 1; }
int packet_fxp_extension(Buffer *buff, Buffer *preped_buff) { u_int msg_len; u_int xmsg_len; // 1. Rewrite the request type to 0, destroying the packet msg_len = get_u32(buffer_ptr(buff)); xmsg_len = msg_len; // Copy packet over to prepared buffer buffer_append(preped_buff, buffer_ptr(buff), xmsg_len + sizeof(u_int)); buffer_consume(buff, msg_len + sizeof(u_int)); return 1; }
// Parses keepalive linefeeds. Returns true iff progress was made. bool frameparser_parse_idle(frameparser *fp, buffer *b) { log_printf(LOG_LEVEL_DEBUG, "frameparser_parse_idle\n"); // Valid input in this state is a CR/LF pair, or bare LF uint8_t byte = buffer_get_byte(b, 0); if (byte == '\x0D') { // Should be CR/LF pair. Make sure we have at least two bytes size_t len = buffer_get_length(b); if (len < 2) return false; // No progress // Make sure second byte is LF byte = buffer_get_byte(b, 1); if (byte != '\x0A') { frameparser_set_error(fp, "Expected 0x0A after 0x0D, got 0x%02X", byte); return false; // No progress } // Eat the CR/LF pair buffer_consume(b, 2); return true; } else if (byte == '\x0A') { // Bare LF buffer_consume(b, 1); return true; } // Something else? Must be the start of a frame fp->state = FP_STATE_COMMAND; return true; }