Beispiel #1
0
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;
}
Beispiel #2
0
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);
	}
Beispiel #3
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;
}