/* DO NOT EDIT THIS FILE! This file was automatically generated by the bproto generator. */ #include #include #include #include #include #define msg_SIZEtype (sizeof(struct BProto_header_s) + sizeof(struct BProto_uint16_s)) #define msg_SIZEpayload(_len) (sizeof(struct BProto_header_s) + sizeof(struct BProto_data_header_s) + (_len)) typedef struct { uint8_t *out; int used; int type_count; int payload_count; } msgWriter; static void msgWriter_Init (msgWriter *o, uint8_t *out); static int msgWriter_Finish (msgWriter *o); static void msgWriter_Addtype (msgWriter *o, uint16_t v); static uint8_t * msgWriter_Addpayload (msgWriter *o, int len); typedef struct { uint8_t *buf; int buf_len; int type_start; int type_span; int type_pos; int payload_start; int payload_span; int payload_pos; } msgParser; static int msgParser_Init (msgParser *o, uint8_t *buf, int buf_len); static int msgParser_GotEverything (msgParser *o); static int msgParser_Gettype (msgParser *o, uint16_t *v); static void msgParser_Resettype (msgParser *o); static void msgParser_Forwardtype (msgParser *o); static int msgParser_Getpayload (msgParser *o, uint8_t **data, int *data_len); static void msgParser_Resetpayload (msgParser *o); static void msgParser_Forwardpayload (msgParser *o); void msgWriter_Init (msgWriter *o, uint8_t *out) { o->out = out; o->used = 0; o->type_count = 0; o->payload_count = 0; } int msgWriter_Finish (msgWriter *o) { ASSERT(o->used >= 0) ASSERT(o->type_count == 1) ASSERT(o->payload_count == 1) return o->used; } void msgWriter_Addtype (msgWriter *o, uint16_t v) { ASSERT(o->used >= 0) ASSERT(o->type_count == 0) struct BProto_header_s header; header.id = htol16(1); header.type = htol16(BPROTO_TYPE_UINT16); memcpy(o->out + o->used, &header, sizeof(header)); o->used += sizeof(struct BProto_header_s); struct BProto_uint16_s data; data.v = htol16(v); memcpy(o->out + o->used, &data, sizeof(data)); o->used += sizeof(struct BProto_uint16_s); o->type_count++; } uint8_t * msgWriter_Addpayload (msgWriter *o, int len) { ASSERT(o->used >= 0) ASSERT(o->payload_count == 0) ASSERT(len >= 0 && len <= UINT32_MAX) struct BProto_header_s header; header.id = htol16(2); header.type = htol16(BPROTO_TYPE_DATA); memcpy(o->out + o->used, &header, sizeof(header)); o->used += sizeof(struct BProto_header_s); struct BProto_data_header_s data; data.len = htol32(len); memcpy(o->out + o->used, &data, sizeof(data)); o->used += sizeof(struct BProto_data_header_s); uint8_t *dest = (o->out + o->used); o->used += len; o->payload_count++; return dest; } int msgParser_Init (msgParser *o, uint8_t *buf, int buf_len) { ASSERT(buf_len >= 0) o->buf = buf; o->buf_len = buf_len; o->type_start = o->buf_len; o->type_span = 0; o->type_pos = 0; o->payload_start = o->buf_len; o->payload_span = 0; o->payload_pos = 0; int type_count = 0; int payload_count = 0; int pos = 0; int left = o->buf_len; while (left > 0) { int entry_pos = pos; if (!(left >= sizeof(struct BProto_header_s))) { return 0; } struct BProto_header_s header; memcpy(&header, o->buf + pos, sizeof(header)); pos += sizeof(struct BProto_header_s); left -= sizeof(struct BProto_header_s); uint16_t type = ltoh16(header.type); uint16_t id = ltoh16(header.id); switch (type) { case BPROTO_TYPE_UINT8: { if (!(left >= sizeof(struct BProto_uint8_s))) { return 0; } pos += sizeof(struct BProto_uint8_s); left -= sizeof(struct BProto_uint8_s); switch (id) { default: return 0; } } break; case BPROTO_TYPE_UINT16: { if (!(left >= sizeof(struct BProto_uint16_s))) { return 0; } pos += sizeof(struct BProto_uint16_s); left -= sizeof(struct BProto_uint16_s); switch (id) { case 1: if (o->type_start == o->buf_len) { o->type_start = entry_pos; } o->type_span = pos - o->type_start; type_count++; break; default: return 0; } } break; case BPROTO_TYPE_UINT32: { if (!(left >= sizeof(struct BProto_uint32_s))) { return 0; } pos += sizeof(struct BProto_uint32_s); left -= sizeof(struct BProto_uint32_s); switch (id) { default: return 0; } } break; case BPROTO_TYPE_UINT64: { if (!(left >= sizeof(struct BProto_uint64_s))) { return 0; } pos += sizeof(struct BProto_uint64_s); left -= sizeof(struct BProto_uint64_s); switch (id) { default: return 0; } } break; case BPROTO_TYPE_DATA: case BPROTO_TYPE_CONSTDATA: { if (!(left >= sizeof(struct BProto_data_header_s))) { return 0; } struct BProto_data_header_s val; memcpy(&val, o->buf + pos, sizeof(val)); pos += sizeof(struct BProto_data_header_s); left -= sizeof(struct BProto_data_header_s); uint32_t payload_len = ltoh32(val.len); if (!(left >= payload_len)) { return 0; } pos += payload_len; left -= payload_len; switch (id) { case 2: if (!(type == BPROTO_TYPE_DATA)) { return 0; } if (o->payload_start == o->buf_len) { o->payload_start = entry_pos; } o->payload_span = pos - o->payload_start; payload_count++; break; default: return 0; } } break; default: return 0; } } if (!(type_count == 1)) { return 0; } if (!(payload_count == 1)) { return 0; } return 1; } int msgParser_GotEverything (msgParser *o) { return ( o->type_pos == o->type_span && o->payload_pos == o->payload_span ); } int msgParser_Gettype (msgParser *o, uint16_t *v) { ASSERT(o->type_pos >= 0) ASSERT(o->type_pos <= o->type_span) int left = o->type_span - o->type_pos; while (left > 0) { ASSERT(left >= sizeof(struct BProto_header_s)) struct BProto_header_s header; memcpy(&header, o->buf + o->type_start + o->type_pos, sizeof(header)); o->type_pos += sizeof(struct BProto_header_s); left -= sizeof(struct BProto_header_s); uint16_t type = ltoh16(header.type); uint16_t id = ltoh16(header.id); switch (type) { case BPROTO_TYPE_UINT8: { ASSERT(left >= sizeof(struct BProto_uint8_s)) o->type_pos += sizeof(struct BProto_uint8_s); left -= sizeof(struct BProto_uint8_s); } break; case BPROTO_TYPE_UINT16: { ASSERT(left >= sizeof(struct BProto_uint16_s)) struct BProto_uint16_s val; memcpy(&val, o->buf + o->type_start + o->type_pos, sizeof(val)); o->type_pos += sizeof(struct BProto_uint16_s); left -= sizeof(struct BProto_uint16_s); if (id == 1) { *v = ltoh16(val.v); return 1; } } break; case BPROTO_TYPE_UINT32: { ASSERT(left >= sizeof(struct BProto_uint32_s)) o->type_pos += sizeof(struct BProto_uint32_s); left -= sizeof(struct BProto_uint32_s); } break; case BPROTO_TYPE_UINT64: { ASSERT(left >= sizeof(struct BProto_uint64_s)) o->type_pos += sizeof(struct BProto_uint64_s); left -= sizeof(struct BProto_uint64_s); } break; case BPROTO_TYPE_DATA: case BPROTO_TYPE_CONSTDATA: { ASSERT(left >= sizeof(struct BProto_data_header_s)) struct BProto_data_header_s val; memcpy(&val, o->buf + o->type_start + o->type_pos, sizeof(val)); o->type_pos += sizeof(struct BProto_data_header_s); left -= sizeof(struct BProto_data_header_s); uint32_t payload_len = ltoh32(val.len); ASSERT(left >= payload_len) o->type_pos += payload_len; left -= payload_len; } break; default: ASSERT(0); } } return 0; } void msgParser_Resettype (msgParser *o) { o->type_pos = 0; } void msgParser_Forwardtype (msgParser *o) { o->type_pos = o->type_span; } int msgParser_Getpayload (msgParser *o, uint8_t **data, int *data_len) { ASSERT(o->payload_pos >= 0) ASSERT(o->payload_pos <= o->payload_span) int left = o->payload_span - o->payload_pos; while (left > 0) { ASSERT(left >= sizeof(struct BProto_header_s)) struct BProto_header_s header; memcpy(&header, o->buf + o->payload_start + o->payload_pos, sizeof(header)); o->payload_pos += sizeof(struct BProto_header_s); left -= sizeof(struct BProto_header_s); uint16_t type = ltoh16(header.type); uint16_t id = ltoh16(header.id); switch (type) { case BPROTO_TYPE_UINT8: { ASSERT(left >= sizeof(struct BProto_uint8_s)) o->payload_pos += sizeof(struct BProto_uint8_s); left -= sizeof(struct BProto_uint8_s); } break; case BPROTO_TYPE_UINT16: { ASSERT(left >= sizeof(struct BProto_uint16_s)) o->payload_pos += sizeof(struct BProto_uint16_s); left -= sizeof(struct BProto_uint16_s); } break; case BPROTO_TYPE_UINT32: { ASSERT(left >= sizeof(struct BProto_uint32_s)) o->payload_pos += sizeof(struct BProto_uint32_s); left -= sizeof(struct BProto_uint32_s); } break; case BPROTO_TYPE_UINT64: { ASSERT(left >= sizeof(struct BProto_uint64_s)) o->payload_pos += sizeof(struct BProto_uint64_s); left -= sizeof(struct BProto_uint64_s); } break; case BPROTO_TYPE_DATA: case BPROTO_TYPE_CONSTDATA: { ASSERT(left >= sizeof(struct BProto_data_header_s)) struct BProto_data_header_s val; memcpy(&val, o->buf + o->payload_start + o->payload_pos, sizeof(val)); o->payload_pos += sizeof(struct BProto_data_header_s); left -= sizeof(struct BProto_data_header_s); uint32_t payload_len = ltoh32(val.len); ASSERT(left >= payload_len) uint8_t *payload = o->buf + o->payload_start + o->payload_pos; o->payload_pos += payload_len; left -= payload_len; if (type == BPROTO_TYPE_DATA && id == 2) { *data = payload; *data_len = payload_len; return 1; } } break; default: ASSERT(0); } } return 0; } void msgParser_Resetpayload (msgParser *o) { o->payload_pos = 0; } void msgParser_Forwardpayload (msgParser *o) { o->payload_pos = o->payload_span; } #define msg_youconnect_SIZEaddr(_len) (sizeof(struct BProto_header_s) + sizeof(struct BProto_data_header_s) + (_len)) #define msg_youconnect_SIZEkey(_len) (sizeof(struct BProto_header_s) + sizeof(struct BProto_data_header_s) + (_len)) #define msg_youconnect_SIZEpassword (sizeof(struct BProto_header_s) + sizeof(struct BProto_uint64_s)) typedef struct { uint8_t *out; int used; int addr_count; int key_count; int password_count; } msg_youconnectWriter; static void msg_youconnectWriter_Init (msg_youconnectWriter *o, uint8_t *out); static int msg_youconnectWriter_Finish (msg_youconnectWriter *o); static uint8_t * msg_youconnectWriter_Addaddr (msg_youconnectWriter *o, int len); static uint8_t * msg_youconnectWriter_Addkey (msg_youconnectWriter *o, int len); static void msg_youconnectWriter_Addpassword (msg_youconnectWriter *o, uint64_t v); typedef struct { uint8_t *buf; int buf_len; int addr_start; int addr_span; int addr_pos; int key_start; int key_span; int key_pos; int password_start; int password_span; int password_pos; } msg_youconnectParser; static int msg_youconnectParser_Init (msg_youconnectParser *o, uint8_t *buf, int buf_len); static int msg_youconnectParser_GotEverything (msg_youconnectParser *o); static int msg_youconnectParser_Getaddr (msg_youconnectParser *o, uint8_t **data, int *data_len); static void msg_youconnectParser_Resetaddr (msg_youconnectParser *o); static void msg_youconnectParser_Forwardaddr (msg_youconnectParser *o); static int msg_youconnectParser_Getkey (msg_youconnectParser *o, uint8_t **data, int *data_len); static void msg_youconnectParser_Resetkey (msg_youconnectParser *o); static void msg_youconnectParser_Forwardkey (msg_youconnectParser *o); static int msg_youconnectParser_Getpassword (msg_youconnectParser *o, uint64_t *v); static void msg_youconnectParser_Resetpassword (msg_youconnectParser *o); static void msg_youconnectParser_Forwardpassword (msg_youconnectParser *o); void msg_youconnectWriter_Init (msg_youconnectWriter *o, uint8_t *out) { o->out = out; o->used = 0; o->addr_count = 0; o->key_count = 0; o->password_count = 0; } int msg_youconnectWriter_Finish (msg_youconnectWriter *o) { ASSERT(o->used >= 0) ASSERT(o->addr_count >= 1) ASSERT(o->key_count >= 0 && o->key_count <= 1) ASSERT(o->password_count >= 0 && o->password_count <= 1) return o->used; } uint8_t * msg_youconnectWriter_Addaddr (msg_youconnectWriter *o, int len) { ASSERT(o->used >= 0) ASSERT(len >= 0 && len <= UINT32_MAX) struct BProto_header_s header; header.id = htol16(1); header.type = htol16(BPROTO_TYPE_DATA); memcpy(o->out + o->used, &header, sizeof(header)); o->used += sizeof(struct BProto_header_s); struct BProto_data_header_s data; data.len = htol32(len); memcpy(o->out + o->used, &data, sizeof(data)); o->used += sizeof(struct BProto_data_header_s); uint8_t *dest = (o->out + o->used); o->used += len; o->addr_count++; return dest; } uint8_t * msg_youconnectWriter_Addkey (msg_youconnectWriter *o, int len) { ASSERT(o->used >= 0) ASSERT(o->key_count == 0) ASSERT(len >= 0 && len <= UINT32_MAX) struct BProto_header_s header; header.id = htol16(2); header.type = htol16(BPROTO_TYPE_DATA); memcpy(o->out + o->used, &header, sizeof(header)); o->used += sizeof(struct BProto_header_s); struct BProto_data_header_s data; data.len = htol32(len); memcpy(o->out + o->used, &data, sizeof(data)); o->used += sizeof(struct BProto_data_header_s); uint8_t *dest = (o->out + o->used); o->used += len; o->key_count++; return dest; } void msg_youconnectWriter_Addpassword (msg_youconnectWriter *o, uint64_t v) { ASSERT(o->used >= 0) ASSERT(o->password_count == 0) struct BProto_header_s header; header.id = htol16(3); header.type = htol16(BPROTO_TYPE_UINT64); memcpy(o->out + o->used, &header, sizeof(header)); o->used += sizeof(struct BProto_header_s); struct BProto_uint64_s data; data.v = htol64(v); memcpy(o->out + o->used, &data, sizeof(data)); o->used += sizeof(struct BProto_uint64_s); o->password_count++; } int msg_youconnectParser_Init (msg_youconnectParser *o, uint8_t *buf, int buf_len) { ASSERT(buf_len >= 0) o->buf = buf; o->buf_len = buf_len; o->addr_start = o->buf_len; o->addr_span = 0; o->addr_pos = 0; o->key_start = o->buf_len; o->key_span = 0; o->key_pos = 0; o->password_start = o->buf_len; o->password_span = 0; o->password_pos = 0; int addr_count = 0; int key_count = 0; int password_count = 0; int pos = 0; int left = o->buf_len; while (left > 0) { int entry_pos = pos; if (!(left >= sizeof(struct BProto_header_s))) { return 0; } struct BProto_header_s header; memcpy(&header, o->buf + pos, sizeof(header)); pos += sizeof(struct BProto_header_s); left -= sizeof(struct BProto_header_s); uint16_t type = ltoh16(header.type); uint16_t id = ltoh16(header.id); switch (type) { case BPROTO_TYPE_UINT8: { if (!(left >= sizeof(struct BProto_uint8_s))) { return 0; } pos += sizeof(struct BProto_uint8_s); left -= sizeof(struct BProto_uint8_s); switch (id) { default: return 0; } } break; case BPROTO_TYPE_UINT16: { if (!(left >= sizeof(struct BProto_uint16_s))) { return 0; } pos += sizeof(struct BProto_uint16_s); left -= sizeof(struct BProto_uint16_s); switch (id) { default: return 0; } } break; case BPROTO_TYPE_UINT32: { if (!(left >= sizeof(struct BProto_uint32_s))) { return 0; } pos += sizeof(struct BProto_uint32_s); left -= sizeof(struct BProto_uint32_s); switch (id) { default: return 0; } } break; case BPROTO_TYPE_UINT64: { if (!(left >= sizeof(struct BProto_uint64_s))) { return 0; } pos += sizeof(struct BProto_uint64_s); left -= sizeof(struct BProto_uint64_s); switch (id) { case 3: if (o->password_start == o->buf_len) { o->password_start = entry_pos; } o->password_span = pos - o->password_start; password_count++; break; default: return 0; } } break; case BPROTO_TYPE_DATA: case BPROTO_TYPE_CONSTDATA: { if (!(left >= sizeof(struct BProto_data_header_s))) { return 0; } struct BProto_data_header_s val; memcpy(&val, o->buf + pos, sizeof(val)); pos += sizeof(struct BProto_data_header_s); left -= sizeof(struct BProto_data_header_s); uint32_t payload_len = ltoh32(val.len); if (!(left >= payload_len)) { return 0; } pos += payload_len; left -= payload_len; switch (id) { case 1: if (!(type == BPROTO_TYPE_DATA)) { return 0; } if (o->addr_start == o->buf_len) { o->addr_start = entry_pos; } o->addr_span = pos - o->addr_start; addr_count++; break; case 2: if (!(type == BPROTO_TYPE_DATA)) { return 0; } if (o->key_start == o->buf_len) { o->key_start = entry_pos; } o->key_span = pos - o->key_start; key_count++; break; default: return 0; } } break; default: return 0; } } if (!(addr_count >= 1)) { return 0; } if (!(key_count <= 1)) { return 0; } if (!(password_count <= 1)) { return 0; } return 1; } int msg_youconnectParser_GotEverything (msg_youconnectParser *o) { return ( o->addr_pos == o->addr_span && o->key_pos == o->key_span && o->password_pos == o->password_span ); } int msg_youconnectParser_Getaddr (msg_youconnectParser *o, uint8_t **data, int *data_len) { ASSERT(o->addr_pos >= 0) ASSERT(o->addr_pos <= o->addr_span) int left = o->addr_span - o->addr_pos; while (left > 0) { ASSERT(left >= sizeof(struct BProto_header_s)) struct BProto_header_s header; memcpy(&header, o->buf + o->addr_start + o->addr_pos, sizeof(header)); o->addr_pos += sizeof(struct BProto_header_s); left -= sizeof(struct BProto_header_s); uint16_t type = ltoh16(header.type); uint16_t id = ltoh16(header.id); switch (type) { case BPROTO_TYPE_UINT8: { ASSERT(left >= sizeof(struct BProto_uint8_s)) o->addr_pos += sizeof(struct BProto_uint8_s); left -= sizeof(struct BProto_uint8_s); } break; case BPROTO_TYPE_UINT16: { ASSERT(left >= sizeof(struct BProto_uint16_s)) o->addr_pos += sizeof(struct BProto_uint16_s); left -= sizeof(struct BProto_uint16_s); } break; case BPROTO_TYPE_UINT32: { ASSERT(left >= sizeof(struct BProto_uint32_s)) o->addr_pos += sizeof(struct BProto_uint32_s); left -= sizeof(struct BProto_uint32_s); } break; case BPROTO_TYPE_UINT64: { ASSERT(left >= sizeof(struct BProto_uint64_s)) o->addr_pos += sizeof(struct BProto_uint64_s); left -= sizeof(struct BProto_uint64_s); } break; case BPROTO_TYPE_DATA: case BPROTO_TYPE_CONSTDATA: { ASSERT(left >= sizeof(struct BProto_data_header_s)) struct BProto_data_header_s val; memcpy(&val, o->buf + o->addr_start + o->addr_pos, sizeof(val)); o->addr_pos += sizeof(struct BProto_data_header_s); left -= sizeof(struct BProto_data_header_s); uint32_t payload_len = ltoh32(val.len); ASSERT(left >= payload_len) uint8_t *payload = o->buf + o->addr_start + o->addr_pos; o->addr_pos += payload_len; left -= payload_len; if (type == BPROTO_TYPE_DATA && id == 1) { *data = payload; *data_len = payload_len; return 1; } } break; default: ASSERT(0); } } return 0; } void msg_youconnectParser_Resetaddr (msg_youconnectParser *o) { o->addr_pos = 0; } void msg_youconnectParser_Forwardaddr (msg_youconnectParser *o) { o->addr_pos = o->addr_span; } int msg_youconnectParser_Getkey (msg_youconnectParser *o, uint8_t **data, int *data_len) { ASSERT(o->key_pos >= 0) ASSERT(o->key_pos <= o->key_span) int left = o->key_span - o->key_pos; while (left > 0) { ASSERT(left >= sizeof(struct BProto_header_s)) struct BProto_header_s header; memcpy(&header, o->buf + o->key_start + o->key_pos, sizeof(header)); o->key_pos += sizeof(struct BProto_header_s); left -= sizeof(struct BProto_header_s); uint16_t type = ltoh16(header.type); uint16_t id = ltoh16(header.id); switch (type) { case BPROTO_TYPE_UINT8: { ASSERT(left >= sizeof(struct BProto_uint8_s)) o->key_pos += sizeof(struct BProto_uint8_s); left -= sizeof(struct BProto_uint8_s); } break; case BPROTO_TYPE_UINT16: { ASSERT(left >= sizeof(struct BProto_uint16_s)) o->key_pos += sizeof(struct BProto_uint16_s); left -= sizeof(struct BProto_uint16_s); } break; case BPROTO_TYPE_UINT32: { ASSERT(left >= sizeof(struct BProto_uint32_s)) o->key_pos += sizeof(struct BProto_uint32_s); left -= sizeof(struct BProto_uint32_s); } break; case BPROTO_TYPE_UINT64: { ASSERT(left >= sizeof(struct BProto_uint64_s)) o->key_pos += sizeof(struct BProto_uint64_s); left -= sizeof(struct BProto_uint64_s); } break; case BPROTO_TYPE_DATA: case BPROTO_TYPE_CONSTDATA: { ASSERT(left >= sizeof(struct BProto_data_header_s)) struct BProto_data_header_s val; memcpy(&val, o->buf + o->key_start + o->key_pos, sizeof(val)); o->key_pos += sizeof(struct BProto_data_header_s); left -= sizeof(struct BProto_data_header_s); uint32_t payload_len = ltoh32(val.len); ASSERT(left >= payload_len) uint8_t *payload = o->buf + o->key_start + o->key_pos; o->key_pos += payload_len; left -= payload_len; if (type == BPROTO_TYPE_DATA && id == 2) { *data = payload; *data_len = payload_len; return 1; } } break; default: ASSERT(0); } } return 0; } void msg_youconnectParser_Resetkey (msg_youconnectParser *o) { o->key_pos = 0; } void msg_youconnectParser_Forwardkey (msg_youconnectParser *o) { o->key_pos = o->key_span; } int msg_youconnectParser_Getpassword (msg_youconnectParser *o, uint64_t *v) { ASSERT(o->password_pos >= 0) ASSERT(o->password_pos <= o->password_span) int left = o->password_span - o->password_pos; while (left > 0) { ASSERT(left >= sizeof(struct BProto_header_s)) struct BProto_header_s header; memcpy(&header, o->buf + o->password_start + o->password_pos, sizeof(header)); o->password_pos += sizeof(struct BProto_header_s); left -= sizeof(struct BProto_header_s); uint16_t type = ltoh16(header.type); uint16_t id = ltoh16(header.id); switch (type) { case BPROTO_TYPE_UINT8: { ASSERT(left >= sizeof(struct BProto_uint8_s)) o->password_pos += sizeof(struct BProto_uint8_s); left -= sizeof(struct BProto_uint8_s); } break; case BPROTO_TYPE_UINT16: { ASSERT(left >= sizeof(struct BProto_uint16_s)) o->password_pos += sizeof(struct BProto_uint16_s); left -= sizeof(struct BProto_uint16_s); } break; case BPROTO_TYPE_UINT32: { ASSERT(left >= sizeof(struct BProto_uint32_s)) o->password_pos += sizeof(struct BProto_uint32_s); left -= sizeof(struct BProto_uint32_s); } break; case BPROTO_TYPE_UINT64: { ASSERT(left >= sizeof(struct BProto_uint64_s)) struct BProto_uint64_s val; memcpy(&val, o->buf + o->password_start + o->password_pos, sizeof(val)); o->password_pos += sizeof(struct BProto_uint64_s); left -= sizeof(struct BProto_uint64_s); if (id == 3) { *v = ltoh64(val.v); return 1; } } break; case BPROTO_TYPE_DATA: case BPROTO_TYPE_CONSTDATA: { ASSERT(left >= sizeof(struct BProto_data_header_s)) struct BProto_data_header_s val; memcpy(&val, o->buf + o->password_start + o->password_pos, sizeof(val)); o->password_pos += sizeof(struct BProto_data_header_s); left -= sizeof(struct BProto_data_header_s); uint32_t payload_len = ltoh32(val.len); ASSERT(left >= payload_len) o->password_pos += payload_len; left -= payload_len; } break; default: ASSERT(0); } } return 0; } void msg_youconnectParser_Resetpassword (msg_youconnectParser *o) { o->password_pos = 0; } void msg_youconnectParser_Forwardpassword (msg_youconnectParser *o) { o->password_pos = o->password_span; } #define msg_youconnect_addr_SIZEname(_len) (sizeof(struct BProto_header_s) + sizeof(struct BProto_data_header_s) + (_len)) #define msg_youconnect_addr_SIZEaddr(_len) (sizeof(struct BProto_header_s) + sizeof(struct BProto_data_header_s) + (_len)) typedef struct { uint8_t *out; int used; int name_count; int addr_count; } msg_youconnect_addrWriter; static void msg_youconnect_addrWriter_Init (msg_youconnect_addrWriter *o, uint8_t *out); static int msg_youconnect_addrWriter_Finish (msg_youconnect_addrWriter *o); static uint8_t * msg_youconnect_addrWriter_Addname (msg_youconnect_addrWriter *o, int len); static uint8_t * msg_youconnect_addrWriter_Addaddr (msg_youconnect_addrWriter *o, int len); typedef struct { uint8_t *buf; int buf_len; int name_start; int name_span; int name_pos; int addr_start; int addr_span; int addr_pos; } msg_youconnect_addrParser; static int msg_youconnect_addrParser_Init (msg_youconnect_addrParser *o, uint8_t *buf, int buf_len); static int msg_youconnect_addrParser_GotEverything (msg_youconnect_addrParser *o); static int msg_youconnect_addrParser_Getname (msg_youconnect_addrParser *o, uint8_t **data, int *data_len); static void msg_youconnect_addrParser_Resetname (msg_youconnect_addrParser *o); static void msg_youconnect_addrParser_Forwardname (msg_youconnect_addrParser *o); static int msg_youconnect_addrParser_Getaddr (msg_youconnect_addrParser *o, uint8_t **data, int *data_len); static void msg_youconnect_addrParser_Resetaddr (msg_youconnect_addrParser *o); static void msg_youconnect_addrParser_Forwardaddr (msg_youconnect_addrParser *o); void msg_youconnect_addrWriter_Init (msg_youconnect_addrWriter *o, uint8_t *out) { o->out = out; o->used = 0; o->name_count = 0; o->addr_count = 0; } int msg_youconnect_addrWriter_Finish (msg_youconnect_addrWriter *o) { ASSERT(o->used >= 0) ASSERT(o->name_count == 1) ASSERT(o->addr_count == 1) return o->used; } uint8_t * msg_youconnect_addrWriter_Addname (msg_youconnect_addrWriter *o, int len) { ASSERT(o->used >= 0) ASSERT(o->name_count == 0) ASSERT(len >= 0 && len <= UINT32_MAX) struct BProto_header_s header; header.id = htol16(1); header.type = htol16(BPROTO_TYPE_DATA); memcpy(o->out + o->used, &header, sizeof(header)); o->used += sizeof(struct BProto_header_s); struct BProto_data_header_s data; data.len = htol32(len); memcpy(o->out + o->used, &data, sizeof(data)); o->used += sizeof(struct BProto_data_header_s); uint8_t *dest = (o->out + o->used); o->used += len; o->name_count++; return dest; } uint8_t * msg_youconnect_addrWriter_Addaddr (msg_youconnect_addrWriter *o, int len) { ASSERT(o->used >= 0) ASSERT(o->addr_count == 0) ASSERT(len >= 0 && len <= UINT32_MAX) struct BProto_header_s header; header.id = htol16(2); header.type = htol16(BPROTO_TYPE_DATA); memcpy(o->out + o->used, &header, sizeof(header)); o->used += sizeof(struct BProto_header_s); struct BProto_data_header_s data; data.len = htol32(len); memcpy(o->out + o->used, &data, sizeof(data)); o->used += sizeof(struct BProto_data_header_s); uint8_t *dest = (o->out + o->used); o->used += len; o->addr_count++; return dest; } int msg_youconnect_addrParser_Init (msg_youconnect_addrParser *o, uint8_t *buf, int buf_len) { ASSERT(buf_len >= 0) o->buf = buf; o->buf_len = buf_len; o->name_start = o->buf_len; o->name_span = 0; o->name_pos = 0; o->addr_start = o->buf_len; o->addr_span = 0; o->addr_pos = 0; int name_count = 0; int addr_count = 0; int pos = 0; int left = o->buf_len; while (left > 0) { int entry_pos = pos; if (!(left >= sizeof(struct BProto_header_s))) { return 0; } struct BProto_header_s header; memcpy(&header, o->buf + pos, sizeof(header)); pos += sizeof(struct BProto_header_s); left -= sizeof(struct BProto_header_s); uint16_t type = ltoh16(header.type); uint16_t id = ltoh16(header.id); switch (type) { case BPROTO_TYPE_UINT8: { if (!(left >= sizeof(struct BProto_uint8_s))) { return 0; } pos += sizeof(struct BProto_uint8_s); left -= sizeof(struct BProto_uint8_s); switch (id) { default: return 0; } } break; case BPROTO_TYPE_UINT16: { if (!(left >= sizeof(struct BProto_uint16_s))) { return 0; } pos += sizeof(struct BProto_uint16_s); left -= sizeof(struct BProto_uint16_s); switch (id) { default: return 0; } } break; case BPROTO_TYPE_UINT32: { if (!(left >= sizeof(struct BProto_uint32_s))) { return 0; } pos += sizeof(struct BProto_uint32_s); left -= sizeof(struct BProto_uint32_s); switch (id) { default: return 0; } } break; case BPROTO_TYPE_UINT64: { if (!(left >= sizeof(struct BProto_uint64_s))) { return 0; } pos += sizeof(struct BProto_uint64_s); left -= sizeof(struct BProto_uint64_s); switch (id) { default: return 0; } } break; case BPROTO_TYPE_DATA: case BPROTO_TYPE_CONSTDATA: { if (!(left >= sizeof(struct BProto_data_header_s))) { return 0; } struct BProto_data_header_s val; memcpy(&val, o->buf + pos, sizeof(val)); pos += sizeof(struct BProto_data_header_s); left -= sizeof(struct BProto_data_header_s); uint32_t payload_len = ltoh32(val.len); if (!(left >= payload_len)) { return 0; } pos += payload_len; left -= payload_len; switch (id) { case 1: if (!(type == BPROTO_TYPE_DATA)) { return 0; } if (o->name_start == o->buf_len) { o->name_start = entry_pos; } o->name_span = pos - o->name_start; name_count++; break; case 2: if (!(type == BPROTO_TYPE_DATA)) { return 0; } if (o->addr_start == o->buf_len) { o->addr_start = entry_pos; } o->addr_span = pos - o->addr_start; addr_count++; break; default: return 0; } } break; default: return 0; } } if (!(name_count == 1)) { return 0; } if (!(addr_count == 1)) { return 0; } return 1; } int msg_youconnect_addrParser_GotEverything (msg_youconnect_addrParser *o) { return ( o->name_pos == o->name_span && o->addr_pos == o->addr_span ); } int msg_youconnect_addrParser_Getname (msg_youconnect_addrParser *o, uint8_t **data, int *data_len) { ASSERT(o->name_pos >= 0) ASSERT(o->name_pos <= o->name_span) int left = o->name_span - o->name_pos; while (left > 0) { ASSERT(left >= sizeof(struct BProto_header_s)) struct BProto_header_s header; memcpy(&header, o->buf + o->name_start + o->name_pos, sizeof(header)); o->name_pos += sizeof(struct BProto_header_s); left -= sizeof(struct BProto_header_s); uint16_t type = ltoh16(header.type); uint16_t id = ltoh16(header.id); switch (type) { case BPROTO_TYPE_UINT8: { ASSERT(left >= sizeof(struct BProto_uint8_s)) o->name_pos += sizeof(struct BProto_uint8_s); left -= sizeof(struct BProto_uint8_s); } break; case BPROTO_TYPE_UINT16: { ASSERT(left >= sizeof(struct BProto_uint16_s)) o->name_pos += sizeof(struct BProto_uint16_s); left -= sizeof(struct BProto_uint16_s); } break; case BPROTO_TYPE_UINT32: { ASSERT(left >= sizeof(struct BProto_uint32_s)) o->name_pos += sizeof(struct BProto_uint32_s); left -= sizeof(struct BProto_uint32_s); } break; case BPROTO_TYPE_UINT64: { ASSERT(left >= sizeof(struct BProto_uint64_s)) o->name_pos += sizeof(struct BProto_uint64_s); left -= sizeof(struct BProto_uint64_s); } break; case BPROTO_TYPE_DATA: case BPROTO_TYPE_CONSTDATA: { ASSERT(left >= sizeof(struct BProto_data_header_s)) struct BProto_data_header_s val; memcpy(&val, o->buf + o->name_start + o->name_pos, sizeof(val)); o->name_pos += sizeof(struct BProto_data_header_s); left -= sizeof(struct BProto_data_header_s); uint32_t payload_len = ltoh32(val.len); ASSERT(left >= payload_len) uint8_t *payload = o->buf + o->name_start + o->name_pos; o->name_pos += payload_len; left -= payload_len; if (type == BPROTO_TYPE_DATA && id == 1) { *data = payload; *data_len = payload_len; return 1; } } break; default: ASSERT(0); } } return 0; } void msg_youconnect_addrParser_Resetname (msg_youconnect_addrParser *o) { o->name_pos = 0; } void msg_youconnect_addrParser_Forwardname (msg_youconnect_addrParser *o) { o->name_pos = o->name_span; } int msg_youconnect_addrParser_Getaddr (msg_youconnect_addrParser *o, uint8_t **data, int *data_len) { ASSERT(o->addr_pos >= 0) ASSERT(o->addr_pos <= o->addr_span) int left = o->addr_span - o->addr_pos; while (left > 0) { ASSERT(left >= sizeof(struct BProto_header_s)) struct BProto_header_s header; memcpy(&header, o->buf + o->addr_start + o->addr_pos, sizeof(header)); o->addr_pos += sizeof(struct BProto_header_s); left -= sizeof(struct BProto_header_s); uint16_t type = ltoh16(header.type); uint16_t id = ltoh16(header.id); switch (type) { case BPROTO_TYPE_UINT8: { ASSERT(left >= sizeof(struct BProto_uint8_s)) o->addr_pos += sizeof(struct BProto_uint8_s); left -= sizeof(struct BProto_uint8_s); } break; case BPROTO_TYPE_UINT16: { ASSERT(left >= sizeof(struct BProto_uint16_s)) o->addr_pos += sizeof(struct BProto_uint16_s); left -= sizeof(struct BProto_uint16_s); } break; case BPROTO_TYPE_UINT32: { ASSERT(left >= sizeof(struct BProto_uint32_s)) o->addr_pos += sizeof(struct BProto_uint32_s); left -= sizeof(struct BProto_uint32_s); } break; case BPROTO_TYPE_UINT64: { ASSERT(left >= sizeof(struct BProto_uint64_s)) o->addr_pos += sizeof(struct BProto_uint64_s); left -= sizeof(struct BProto_uint64_s); } break; case BPROTO_TYPE_DATA: case BPROTO_TYPE_CONSTDATA: { ASSERT(left >= sizeof(struct BProto_data_header_s)) struct BProto_data_header_s val; memcpy(&val, o->buf + o->addr_start + o->addr_pos, sizeof(val)); o->addr_pos += sizeof(struct BProto_data_header_s); left -= sizeof(struct BProto_data_header_s); uint32_t payload_len = ltoh32(val.len); ASSERT(left >= payload_len) uint8_t *payload = o->buf + o->addr_start + o->addr_pos; o->addr_pos += payload_len; left -= payload_len; if (type == BPROTO_TYPE_DATA && id == 2) { *data = payload; *data_len = payload_len; return 1; } } break; default: ASSERT(0); } } return 0; } void msg_youconnect_addrParser_Resetaddr (msg_youconnect_addrParser *o) { o->addr_pos = 0; } void msg_youconnect_addrParser_Forwardaddr (msg_youconnect_addrParser *o) { o->addr_pos = o->addr_span; } #define msg_seed_SIZEseed_id (sizeof(struct BProto_header_s) + sizeof(struct BProto_uint16_s)) #define msg_seed_SIZEkey(_len) (sizeof(struct BProto_header_s) + sizeof(struct BProto_data_header_s) + (_len)) #define msg_seed_SIZEiv(_len) (sizeof(struct BProto_header_s) + sizeof(struct BProto_data_header_s) + (_len)) typedef struct { uint8_t *out; int used; int seed_id_count; int key_count; int iv_count; } msg_seedWriter; static void msg_seedWriter_Init (msg_seedWriter *o, uint8_t *out); static int msg_seedWriter_Finish (msg_seedWriter *o); static void msg_seedWriter_Addseed_id (msg_seedWriter *o, uint16_t v); static uint8_t * msg_seedWriter_Addkey (msg_seedWriter *o, int len); static uint8_t * msg_seedWriter_Addiv (msg_seedWriter *o, int len); typedef struct { uint8_t *buf; int buf_len; int seed_id_start; int seed_id_span; int seed_id_pos; int key_start; int key_span; int key_pos; int iv_start; int iv_span; int iv_pos; } msg_seedParser; static int msg_seedParser_Init (msg_seedParser *o, uint8_t *buf, int buf_len); static int msg_seedParser_GotEverything (msg_seedParser *o); static int msg_seedParser_Getseed_id (msg_seedParser *o, uint16_t *v); static void msg_seedParser_Resetseed_id (msg_seedParser *o); static void msg_seedParser_Forwardseed_id (msg_seedParser *o); static int msg_seedParser_Getkey (msg_seedParser *o, uint8_t **data, int *data_len); static void msg_seedParser_Resetkey (msg_seedParser *o); static void msg_seedParser_Forwardkey (msg_seedParser *o); static int msg_seedParser_Getiv (msg_seedParser *o, uint8_t **data, int *data_len); static void msg_seedParser_Resetiv (msg_seedParser *o); static void msg_seedParser_Forwardiv (msg_seedParser *o); void msg_seedWriter_Init (msg_seedWriter *o, uint8_t *out) { o->out = out; o->used = 0; o->seed_id_count = 0; o->key_count = 0; o->iv_count = 0; } int msg_seedWriter_Finish (msg_seedWriter *o) { ASSERT(o->used >= 0) ASSERT(o->seed_id_count == 1) ASSERT(o->key_count == 1) ASSERT(o->iv_count == 1) return o->used; } void msg_seedWriter_Addseed_id (msg_seedWriter *o, uint16_t v) { ASSERT(o->used >= 0) ASSERT(o->seed_id_count == 0) struct BProto_header_s header; header.id = htol16(1); header.type = htol16(BPROTO_TYPE_UINT16); memcpy(o->out + o->used, &header, sizeof(header)); o->used += sizeof(struct BProto_header_s); struct BProto_uint16_s data; data.v = htol16(v); memcpy(o->out + o->used, &data, sizeof(data)); o->used += sizeof(struct BProto_uint16_s); o->seed_id_count++; } uint8_t * msg_seedWriter_Addkey (msg_seedWriter *o, int len) { ASSERT(o->used >= 0) ASSERT(o->key_count == 0) ASSERT(len >= 0 && len <= UINT32_MAX) struct BProto_header_s header; header.id = htol16(2); header.type = htol16(BPROTO_TYPE_DATA); memcpy(o->out + o->used, &header, sizeof(header)); o->used += sizeof(struct BProto_header_s); struct BProto_data_header_s data; data.len = htol32(len); memcpy(o->out + o->used, &data, sizeof(data)); o->used += sizeof(struct BProto_data_header_s); uint8_t *dest = (o->out + o->used); o->used += len; o->key_count++; return dest; } uint8_t * msg_seedWriter_Addiv (msg_seedWriter *o, int len) { ASSERT(o->used >= 0) ASSERT(o->iv_count == 0) ASSERT(len >= 0 && len <= UINT32_MAX) struct BProto_header_s header; header.id = htol16(3); header.type = htol16(BPROTO_TYPE_DATA); memcpy(o->out + o->used, &header, sizeof(header)); o->used += sizeof(struct BProto_header_s); struct BProto_data_header_s data; data.len = htol32(len); memcpy(o->out + o->used, &data, sizeof(data)); o->used += sizeof(struct BProto_data_header_s); uint8_t *dest = (o->out + o->used); o->used += len; o->iv_count++; return dest; } int msg_seedParser_Init (msg_seedParser *o, uint8_t *buf, int buf_len) { ASSERT(buf_len >= 0) o->buf = buf; o->buf_len = buf_len; o->seed_id_start = o->buf_len; o->seed_id_span = 0; o->seed_id_pos = 0; o->key_start = o->buf_len; o->key_span = 0; o->key_pos = 0; o->iv_start = o->buf_len; o->iv_span = 0; o->iv_pos = 0; int seed_id_count = 0; int key_count = 0; int iv_count = 0; int pos = 0; int left = o->buf_len; while (left > 0) { int entry_pos = pos; if (!(left >= sizeof(struct BProto_header_s))) { return 0; } struct BProto_header_s header; memcpy(&header, o->buf + pos, sizeof(header)); pos += sizeof(struct BProto_header_s); left -= sizeof(struct BProto_header_s); uint16_t type = ltoh16(header.type); uint16_t id = ltoh16(header.id); switch (type) { case BPROTO_TYPE_UINT8: { if (!(left >= sizeof(struct BProto_uint8_s))) { return 0; } pos += sizeof(struct BProto_uint8_s); left -= sizeof(struct BProto_uint8_s); switch (id) { default: return 0; } } break; case BPROTO_TYPE_UINT16: { if (!(left >= sizeof(struct BProto_uint16_s))) { return 0; } pos += sizeof(struct BProto_uint16_s); left -= sizeof(struct BProto_uint16_s); switch (id) { case 1: if (o->seed_id_start == o->buf_len) { o->seed_id_start = entry_pos; } o->seed_id_span = pos - o->seed_id_start; seed_id_count++; break; default: return 0; } } break; case BPROTO_TYPE_UINT32: { if (!(left >= sizeof(struct BProto_uint32_s))) { return 0; } pos += sizeof(struct BProto_uint32_s); left -= sizeof(struct BProto_uint32_s); switch (id) { default: return 0; } } break; case BPROTO_TYPE_UINT64: { if (!(left >= sizeof(struct BProto_uint64_s))) { return 0; } pos += sizeof(struct BProto_uint64_s); left -= sizeof(struct BProto_uint64_s); switch (id) { default: return 0; } } break; case BPROTO_TYPE_DATA: case BPROTO_TYPE_CONSTDATA: { if (!(left >= sizeof(struct BProto_data_header_s))) { return 0; } struct BProto_data_header_s val; memcpy(&val, o->buf + pos, sizeof(val)); pos += sizeof(struct BProto_data_header_s); left -= sizeof(struct BProto_data_header_s); uint32_t payload_len = ltoh32(val.len); if (!(left >= payload_len)) { return 0; } pos += payload_len; left -= payload_len; switch (id) { case 2: if (!(type == BPROTO_TYPE_DATA)) { return 0; } if (o->key_start == o->buf_len) { o->key_start = entry_pos; } o->key_span = pos - o->key_start; key_count++; break; case 3: if (!(type == BPROTO_TYPE_DATA)) { return 0; } if (o->iv_start == o->buf_len) { o->iv_start = entry_pos; } o->iv_span = pos - o->iv_start; iv_count++; break; default: return 0; } } break; default: return 0; } } if (!(seed_id_count == 1)) { return 0; } if (!(key_count == 1)) { return 0; } if (!(iv_count == 1)) { return 0; } return 1; } int msg_seedParser_GotEverything (msg_seedParser *o) { return ( o->seed_id_pos == o->seed_id_span && o->key_pos == o->key_span && o->iv_pos == o->iv_span ); } int msg_seedParser_Getseed_id (msg_seedParser *o, uint16_t *v) { ASSERT(o->seed_id_pos >= 0) ASSERT(o->seed_id_pos <= o->seed_id_span) int left = o->seed_id_span - o->seed_id_pos; while (left > 0) { ASSERT(left >= sizeof(struct BProto_header_s)) struct BProto_header_s header; memcpy(&header, o->buf + o->seed_id_start + o->seed_id_pos, sizeof(header)); o->seed_id_pos += sizeof(struct BProto_header_s); left -= sizeof(struct BProto_header_s); uint16_t type = ltoh16(header.type); uint16_t id = ltoh16(header.id); switch (type) { case BPROTO_TYPE_UINT8: { ASSERT(left >= sizeof(struct BProto_uint8_s)) o->seed_id_pos += sizeof(struct BProto_uint8_s); left -= sizeof(struct BProto_uint8_s); } break; case BPROTO_TYPE_UINT16: { ASSERT(left >= sizeof(struct BProto_uint16_s)) struct BProto_uint16_s val; memcpy(&val, o->buf + o->seed_id_start + o->seed_id_pos, sizeof(val)); o->seed_id_pos += sizeof(struct BProto_uint16_s); left -= sizeof(struct BProto_uint16_s); if (id == 1) { *v = ltoh16(val.v); return 1; } } break; case BPROTO_TYPE_UINT32: { ASSERT(left >= sizeof(struct BProto_uint32_s)) o->seed_id_pos += sizeof(struct BProto_uint32_s); left -= sizeof(struct BProto_uint32_s); } break; case BPROTO_TYPE_UINT64: { ASSERT(left >= sizeof(struct BProto_uint64_s)) o->seed_id_pos += sizeof(struct BProto_uint64_s); left -= sizeof(struct BProto_uint64_s); } break; case BPROTO_TYPE_DATA: case BPROTO_TYPE_CONSTDATA: { ASSERT(left >= sizeof(struct BProto_data_header_s)) struct BProto_data_header_s val; memcpy(&val, o->buf + o->seed_id_start + o->seed_id_pos, sizeof(val)); o->seed_id_pos += sizeof(struct BProto_data_header_s); left -= sizeof(struct BProto_data_header_s); uint32_t payload_len = ltoh32(val.len); ASSERT(left >= payload_len) o->seed_id_pos += payload_len; left -= payload_len; } break; default: ASSERT(0); } } return 0; } void msg_seedParser_Resetseed_id (msg_seedParser *o) { o->seed_id_pos = 0; } void msg_seedParser_Forwardseed_id (msg_seedParser *o) { o->seed_id_pos = o->seed_id_span; } int msg_seedParser_Getkey (msg_seedParser *o, uint8_t **data, int *data_len) { ASSERT(o->key_pos >= 0) ASSERT(o->key_pos <= o->key_span) int left = o->key_span - o->key_pos; while (left > 0) { ASSERT(left >= sizeof(struct BProto_header_s)) struct BProto_header_s header; memcpy(&header, o->buf + o->key_start + o->key_pos, sizeof(header)); o->key_pos += sizeof(struct BProto_header_s); left -= sizeof(struct BProto_header_s); uint16_t type = ltoh16(header.type); uint16_t id = ltoh16(header.id); switch (type) { case BPROTO_TYPE_UINT8: { ASSERT(left >= sizeof(struct BProto_uint8_s)) o->key_pos += sizeof(struct BProto_uint8_s); left -= sizeof(struct BProto_uint8_s); } break; case BPROTO_TYPE_UINT16: { ASSERT(left >= sizeof(struct BProto_uint16_s)) o->key_pos += sizeof(struct BProto_uint16_s); left -= sizeof(struct BProto_uint16_s); } break; case BPROTO_TYPE_UINT32: { ASSERT(left >= sizeof(struct BProto_uint32_s)) o->key_pos += sizeof(struct BProto_uint32_s); left -= sizeof(struct BProto_uint32_s); } break; case BPROTO_TYPE_UINT64: { ASSERT(left >= sizeof(struct BProto_uint64_s)) o->key_pos += sizeof(struct BProto_uint64_s); left -= sizeof(struct BProto_uint64_s); } break; case BPROTO_TYPE_DATA: case BPROTO_TYPE_CONSTDATA: { ASSERT(left >= sizeof(struct BProto_data_header_s)) struct BProto_data_header_s val; memcpy(&val, o->buf + o->key_start + o->key_pos, sizeof(val)); o->key_pos += sizeof(struct BProto_data_header_s); left -= sizeof(struct BProto_data_header_s); uint32_t payload_len = ltoh32(val.len); ASSERT(left >= payload_len) uint8_t *payload = o->buf + o->key_start + o->key_pos; o->key_pos += payload_len; left -= payload_len; if (type == BPROTO_TYPE_DATA && id == 2) { *data = payload; *data_len = payload_len; return 1; } } break; default: ASSERT(0); } } return 0; } void msg_seedParser_Resetkey (msg_seedParser *o) { o->key_pos = 0; } void msg_seedParser_Forwardkey (msg_seedParser *o) { o->key_pos = o->key_span; } int msg_seedParser_Getiv (msg_seedParser *o, uint8_t **data, int *data_len) { ASSERT(o->iv_pos >= 0) ASSERT(o->iv_pos <= o->iv_span) int left = o->iv_span - o->iv_pos; while (left > 0) { ASSERT(left >= sizeof(struct BProto_header_s)) struct BProto_header_s header; memcpy(&header, o->buf + o->iv_start + o->iv_pos, sizeof(header)); o->iv_pos += sizeof(struct BProto_header_s); left -= sizeof(struct BProto_header_s); uint16_t type = ltoh16(header.type); uint16_t id = ltoh16(header.id); switch (type) { case BPROTO_TYPE_UINT8: { ASSERT(left >= sizeof(struct BProto_uint8_s)) o->iv_pos += sizeof(struct BProto_uint8_s); left -= sizeof(struct BProto_uint8_s); } break; case BPROTO_TYPE_UINT16: { ASSERT(left >= sizeof(struct BProto_uint16_s)) o->iv_pos += sizeof(struct BProto_uint16_s); left -= sizeof(struct BProto_uint16_s); } break; case BPROTO_TYPE_UINT32: { ASSERT(left >= sizeof(struct BProto_uint32_s)) o->iv_pos += sizeof(struct BProto_uint32_s); left -= sizeof(struct BProto_uint32_s); } break; case BPROTO_TYPE_UINT64: { ASSERT(left >= sizeof(struct BProto_uint64_s)) o->iv_pos += sizeof(struct BProto_uint64_s); left -= sizeof(struct BProto_uint64_s); } break; case BPROTO_TYPE_DATA: case BPROTO_TYPE_CONSTDATA: { ASSERT(left >= sizeof(struct BProto_data_header_s)) struct BProto_data_header_s val; memcpy(&val, o->buf + o->iv_start + o->iv_pos, sizeof(val)); o->iv_pos += sizeof(struct BProto_data_header_s); left -= sizeof(struct BProto_data_header_s); uint32_t payload_len = ltoh32(val.len); ASSERT(left >= payload_len) uint8_t *payload = o->buf + o->iv_start + o->iv_pos; o->iv_pos += payload_len; left -= payload_len; if (type == BPROTO_TYPE_DATA && id == 3) { *data = payload; *data_len = payload_len; return 1; } } break; default: ASSERT(0); } } return 0; } void msg_seedParser_Resetiv (msg_seedParser *o) { o->iv_pos = 0; } void msg_seedParser_Forwardiv (msg_seedParser *o) { o->iv_pos = o->iv_span; } #define msg_confirmseed_SIZEseed_id (sizeof(struct BProto_header_s) + sizeof(struct BProto_uint16_s)) typedef struct { uint8_t *out; int used; int seed_id_count; } msg_confirmseedWriter; static void msg_confirmseedWriter_Init (msg_confirmseedWriter *o, uint8_t *out); static int msg_confirmseedWriter_Finish (msg_confirmseedWriter *o); static void msg_confirmseedWriter_Addseed_id (msg_confirmseedWriter *o, uint16_t v); typedef struct { uint8_t *buf; int buf_len; int seed_id_start; int seed_id_span; int seed_id_pos; } msg_confirmseedParser; static int msg_confirmseedParser_Init (msg_confirmseedParser *o, uint8_t *buf, int buf_len); static int msg_confirmseedParser_GotEverything (msg_confirmseedParser *o); static int msg_confirmseedParser_Getseed_id (msg_confirmseedParser *o, uint16_t *v); static void msg_confirmseedParser_Resetseed_id (msg_confirmseedParser *o); static void msg_confirmseedParser_Forwardseed_id (msg_confirmseedParser *o); void msg_confirmseedWriter_Init (msg_confirmseedWriter *o, uint8_t *out) { o->out = out; o->used = 0; o->seed_id_count = 0; } int msg_confirmseedWriter_Finish (msg_confirmseedWriter *o) { ASSERT(o->used >= 0) ASSERT(o->seed_id_count == 1) return o->used; } void msg_confirmseedWriter_Addseed_id (msg_confirmseedWriter *o, uint16_t v) { ASSERT(o->used >= 0) ASSERT(o->seed_id_count == 0) struct BProto_header_s header; header.id = htol16(1); header.type = htol16(BPROTO_TYPE_UINT16); memcpy(o->out + o->used, &header, sizeof(header)); o->used += sizeof(struct BProto_header_s); struct BProto_uint16_s data; data.v = htol16(v); memcpy(o->out + o->used, &data, sizeof(data)); o->used += sizeof(struct BProto_uint16_s); o->seed_id_count++; } int msg_confirmseedParser_Init (msg_confirmseedParser *o, uint8_t *buf, int buf_len) { ASSERT(buf_len >= 0) o->buf = buf; o->buf_len = buf_len; o->seed_id_start = o->buf_len; o->seed_id_span = 0; o->seed_id_pos = 0; int seed_id_count = 0; int pos = 0; int left = o->buf_len; while (left > 0) { int entry_pos = pos; if (!(left >= sizeof(struct BProto_header_s))) { return 0; } struct BProto_header_s header; memcpy(&header, o->buf + pos, sizeof(header)); pos += sizeof(struct BProto_header_s); left -= sizeof(struct BProto_header_s); uint16_t type = ltoh16(header.type); uint16_t id = ltoh16(header.id); switch (type) { case BPROTO_TYPE_UINT8: { if (!(left >= sizeof(struct BProto_uint8_s))) { return 0; } pos += sizeof(struct BProto_uint8_s); left -= sizeof(struct BProto_uint8_s); switch (id) { default: return 0; } } break; case BPROTO_TYPE_UINT16: { if (!(left >= sizeof(struct BProto_uint16_s))) { return 0; } pos += sizeof(struct BProto_uint16_s); left -= sizeof(struct BProto_uint16_s); switch (id) { case 1: if (o->seed_id_start == o->buf_len) { o->seed_id_start = entry_pos; } o->seed_id_span = pos - o->seed_id_start; seed_id_count++; break; default: return 0; } } break; case BPROTO_TYPE_UINT32: { if (!(left >= sizeof(struct BProto_uint32_s))) { return 0; } pos += sizeof(struct BProto_uint32_s); left -= sizeof(struct BProto_uint32_s); switch (id) { default: return 0; } } break; case BPROTO_TYPE_UINT64: { if (!(left >= sizeof(struct BProto_uint64_s))) { return 0; } pos += sizeof(struct BProto_uint64_s); left -= sizeof(struct BProto_uint64_s); switch (id) { default: return 0; } } break; case BPROTO_TYPE_DATA: case BPROTO_TYPE_CONSTDATA: { if (!(left >= sizeof(struct BProto_data_header_s))) { return 0; } struct BProto_data_header_s val; memcpy(&val, o->buf + pos, sizeof(val)); pos += sizeof(struct BProto_data_header_s); left -= sizeof(struct BProto_data_header_s); uint32_t payload_len = ltoh32(val.len); if (!(left >= payload_len)) { return 0; } pos += payload_len; left -= payload_len; switch (id) { default: return 0; } } break; default: return 0; } } if (!(seed_id_count == 1)) { return 0; } return 1; } int msg_confirmseedParser_GotEverything (msg_confirmseedParser *o) { return ( o->seed_id_pos == o->seed_id_span ); } int msg_confirmseedParser_Getseed_id (msg_confirmseedParser *o, uint16_t *v) { ASSERT(o->seed_id_pos >= 0) ASSERT(o->seed_id_pos <= o->seed_id_span) int left = o->seed_id_span - o->seed_id_pos; while (left > 0) { ASSERT(left >= sizeof(struct BProto_header_s)) struct BProto_header_s header; memcpy(&header, o->buf + o->seed_id_start + o->seed_id_pos, sizeof(header)); o->seed_id_pos += sizeof(struct BProto_header_s); left -= sizeof(struct BProto_header_s); uint16_t type = ltoh16(header.type); uint16_t id = ltoh16(header.id); switch (type) { case BPROTO_TYPE_UINT8: { ASSERT(left >= sizeof(struct BProto_uint8_s)) o->seed_id_pos += sizeof(struct BProto_uint8_s); left -= sizeof(struct BProto_uint8_s); } break; case BPROTO_TYPE_UINT16: { ASSERT(left >= sizeof(struct BProto_uint16_s)) struct BProto_uint16_s val; memcpy(&val, o->buf + o->seed_id_start + o->seed_id_pos, sizeof(val)); o->seed_id_pos += sizeof(struct BProto_uint16_s); left -= sizeof(struct BProto_uint16_s); if (id == 1) { *v = ltoh16(val.v); return 1; } } break; case BPROTO_TYPE_UINT32: { ASSERT(left >= sizeof(struct BProto_uint32_s)) o->seed_id_pos += sizeof(struct BProto_uint32_s); left -= sizeof(struct BProto_uint32_s); } break; case BPROTO_TYPE_UINT64: { ASSERT(left >= sizeof(struct BProto_uint64_s)) o->seed_id_pos += sizeof(struct BProto_uint64_s); left -= sizeof(struct BProto_uint64_s); } break; case BPROTO_TYPE_DATA: case BPROTO_TYPE_CONSTDATA: { ASSERT(left >= sizeof(struct BProto_data_header_s)) struct BProto_data_header_s val; memcpy(&val, o->buf + o->seed_id_start + o->seed_id_pos, sizeof(val)); o->seed_id_pos += sizeof(struct BProto_data_header_s); left -= sizeof(struct BProto_data_header_s); uint32_t payload_len = ltoh32(val.len); ASSERT(left >= payload_len) o->seed_id_pos += payload_len; left -= payload_len; } break; default: ASSERT(0); } } return 0; } void msg_confirmseedParser_Resetseed_id (msg_confirmseedParser *o) { o->seed_id_pos = 0; } void msg_confirmseedParser_Forwardseed_id (msg_confirmseedParser *o) { o->seed_id_pos = o->seed_id_span; }