int _deserialize_blockpairs_from_disk(int fd, struct block *b, struct hdr *hdr) { int r = NESS_ERR; uint32_t read_size; uint32_t align_size; struct buffer *rbuf; struct block_pair *pairs; read_size = hdr->blocksize; align_size = ALIGN(read_size); rbuf = buf_new(align_size); if (ness_os_pread(fd, rbuf->buf, align_size, hdr->blockoff) != (ssize_t)align_size) { r = NESS_READ_ERR; goto ERR; } if (!buf_seek(rbuf, read_size - CRC_SIZE)) goto ERR; uint32_t exp_xsum, act_xsum; if (!buf_getuint32(rbuf, &exp_xsum)) goto ERR; if (!buf_xsum(rbuf->buf, hdr->blocksize - CRC_SIZE, &act_xsum)) goto ERR; if (exp_xsum != act_xsum) { __ERROR("blockpairs xsum check error," "exp_xsum: [%" PRIu32 "]," "act_xsum: [%" PRIu32 "]", exp_xsum, act_xsum); goto ERR; } buf_seekfirst(rbuf); /* * skip magic with 8bytes */ if (!buf_skip(rbuf, 8)) goto ERR; uint32_t i; uint32_t block_count = 0U; if (!buf_getuint32(rbuf, &block_count)) goto ERR; pairs = xcalloc(block_count, sizeof(*pairs)); for (i = 0; i < block_count; i++) { if (!buf_getuint64(rbuf, &pairs[i].nid)) goto ERR1; if (!buf_getuint64(rbuf, &pairs[i].offset)) goto ERR1; if (!buf_getuint32(rbuf, &pairs[i].real_size)) goto ERR1; if (!buf_getuint32(rbuf, &pairs[i].skeleton_size)) goto ERR1; if (!buf_getuint32(rbuf, &pairs[i].height)) goto ERR1; pairs[i].used = 1; } if (block_count > 0) block_init(b, pairs, block_count); xfree(pairs); buf_free(rbuf); return NESS_OK; ERR: buf_free(rbuf); return r; ERR1: buf_free(rbuf); xfree(pairs); return r; }
int decode_icq(u_char *buf, int len, u_char *obuf, int olen) { struct buf inbuf, outbuf; u_short version, cmd; u_int32_t uin; u_char *p; buf_init(&inbuf, buf, len); buf_init(&outbuf, obuf, olen); if (buf_get(&inbuf, &version, sizeof(version)) != sizeof(version)) return (0); version = pletohs(&version); switch (version) { case 2: if (buf_seek(&inbuf, ICQ2_CMD_OFFSET, SEEK_SET) < 0) return (0); if (buf_get(&inbuf, &cmd, sizeof(cmd)) != sizeof(cmd)) return (0); if ((cmd = pletohs(&cmd)) != 1000) return (0); if (buf_seek(&inbuf, ICQ2_UIN_OFFSET, SEEK_SET) < 0) return (0); if (buf_get(&inbuf, &uin, sizeof(uin)) != sizeof(uin)) return (0); uin = pletohl(&uin); if (buf_seek(&inbuf, ICQ2_PASS_OFFSET, SEEK_SET) < 0) return (0); break; case 5: { u_int32_t a1, a2, a3, a4, a5, c, key, i, k; if (buf_seek(&inbuf, ICQ5_CKSUM_OFFSET, SEEK_SET) < 0) return (0); if (buf_get(&inbuf, &c, sizeof(c)) != sizeof(c)) return (0); c = pletohl(&c); a1 = c & 0x0001f000; a1 = a1 >> 0x0c; a2 = c & 0x07c007c0; a2 = a2 >> 0x01; a3 = c & 0x003e0001; a3 = a3 << 0x0a; a4 = c & 0xf8000000; a4 = a4 >> 0x10; a5 = c & 0x0000083e; a5 = a5 << 0x0f; key = len * 0x68656C6C; key += a1 + a2 + a3 + a4 + a5; p = inbuf.base; for (i = 0x0a; i < inbuf.end + 3; i += 4) { k = key + icq5_table[i & 0xff]; if (i != 0x16) { p[i] ^= (u_char)(k & 0xff); p[i + 1] ^= (u_char)((k & 0xff00) >> 8); } if (i != 0x12) { p[i + 2] ^= (u_char)((k & 0xff0000) >> 16); p[i + 3] ^= (u_char)((k & 0xff000000) >> 24); } } if (buf_seek(&inbuf, ICQ5_CMD_OFFSET, SEEK_SET) < 0) return (0); if (buf_get(&inbuf, &cmd, sizeof(cmd)) != sizeof(cmd)) return (0); if ((cmd = pletohs(&cmd)) != 1000) return (0); if (buf_seek(&inbuf, ICQ5_UIN_OFFSET, SEEK_SET) < 0) return (0); if (buf_get(&inbuf, &uin, sizeof(uin)) != sizeof(uin)) return (0); uin = pletohl(&uin); if (buf_seek(&inbuf, ICQ5_PASS_OFFSET, SEEK_SET) < 0) return (0); }
int read_hdr_from_disk(int fd, struct block *b, struct hdr **h, DISKOFF off) { int r = NESS_ERR; struct hdr *hdr = NULL; struct buffer *rbuf = NULL; uint32_t exp_xsum, act_xsum; uint32_t read_size, align_size; hdr = xcalloc(1, sizeof(*hdr)); read_size = ( + 8 /* magic */ + 8 /* last nid */ + 8 /* root nid */ + 4 /* version */ + 4 /* block size */ + 8 /* block offset */ + CRC_SIZE); /* checksum */ align_size = ALIGN(read_size); rbuf = buf_new(align_size); if (ness_os_pread(fd, rbuf->buf, align_size, off) != (ssize_t)align_size) { __ERROR("ness pread error, read size [%" PRIu32 "], " "offset [%" PRIu64 "]", align_size, 0UL); r = NESS_READ_ERR; goto ERR; } if (!buf_seek(rbuf, read_size - CRC_SIZE)) goto ERR; if (!buf_getuint32(rbuf, &exp_xsum)) goto ERR; if (!buf_xsum(rbuf->buf, read_size - CRC_SIZE, &act_xsum)) goto ERR; if (exp_xsum != act_xsum) { __ERROR("header xsum check error, " "exp_xsum: [%" PRIu32 "], " "act_xsum: [%" PRIu32 "], ", exp_xsum, act_xsum); r = NESS_HDR_XSUM_ERR; goto ERR; } buf_seekfirst(rbuf); if (!buf_skip(rbuf, 8)) goto ERR; if (!buf_getuint32(rbuf, &hdr->version)) goto ERR; if (!buf_getuint64(rbuf, &hdr->last_nid)) goto ERR; if (!buf_getuint64(rbuf, &hdr->root_nid)) goto ERR; if (!buf_getuint32(rbuf, &hdr->blocksize)) goto ERR; if (!buf_getuint64(rbuf, &hdr->blockoff)) goto ERR; nassert(hdr->root_nid >= NID_START); if (hdr->version < LAYOUT_MIN_SUPPORTED_VERSION) { r = NESS_LAYOUT_VERSION_OLDER_ERR; __ERROR("tree layout too older [%d], " "min_support_version [%d]", hdr->version, LAYOUT_MIN_SUPPORTED_VERSION); goto ERR; } /* block pairs */ r = _deserialize_blockpairs_from_disk(fd, b, hdr); if (r != NESS_OK) { r = NESS_DESERIAL_BLOCKPAIR_ERR; goto ERR; } *h = hdr; buf_free(rbuf); return NESS_OK; ERR: buf_free(rbuf); xfree(hdr); return r; }