Ejemplo n.º 1
0
void
zap_leaf_byteswap(zap_leaf_phys_t *buf, int size)
{
	int i;
	zap_leaf_t l;
	l.l_bs = highbit(size)-1;
	l.l_phys = buf;

	buf->l_hdr.lh_block_type = 	BSWAP_64(buf->l_hdr.lh_block_type);
	buf->l_hdr.lh_prefix = 		BSWAP_64(buf->l_hdr.lh_prefix);
	buf->l_hdr.lh_magic = 		BSWAP_32(buf->l_hdr.lh_magic);
	buf->l_hdr.lh_nfree = 		BSWAP_16(buf->l_hdr.lh_nfree);
	buf->l_hdr.lh_nentries = 	BSWAP_16(buf->l_hdr.lh_nentries);
	buf->l_hdr.lh_prefix_len = 	BSWAP_16(buf->l_hdr.lh_prefix_len);
	buf->l_hdr.lh_freelist = 	BSWAP_16(buf->l_hdr.lh_freelist);

	for (i = 0; i < ZAP_LEAF_HASH_NUMENTRIES(&l); i++)
		buf->l_hash[i] = BSWAP_16(buf->l_hash[i]);

	for (i = 0; i < ZAP_LEAF_NUMCHUNKS(&l); i++) {
		zap_leaf_chunk_t *lc = &ZAP_LEAF_CHUNK(&l, i);
		struct zap_leaf_entry *le;

		switch (lc->l_free.lf_type) {
		case ZAP_CHUNK_ENTRY:
			le = &lc->l_entry;

			le->le_type =		BSWAP_8(le->le_type);
			le->le_value_intlen =	BSWAP_8(le->le_value_intlen);
			le->le_next =		BSWAP_16(le->le_next);
			le->le_name_chunk =	BSWAP_16(le->le_name_chunk);
			le->le_name_numints =	BSWAP_16(le->le_name_numints);
			le->le_value_chunk =	BSWAP_16(le->le_value_chunk);
			le->le_value_numints =	BSWAP_16(le->le_value_numints);
			le->le_cd =		BSWAP_32(le->le_cd);
			le->le_hash =		BSWAP_64(le->le_hash);
			break;
		case ZAP_CHUNK_FREE:
			lc->l_free.lf_type =	BSWAP_8(lc->l_free.lf_type);
			lc->l_free.lf_next =	BSWAP_16(lc->l_free.lf_next);
			break;
		case ZAP_CHUNK_ARRAY:
			lc->l_array.la_type =	BSWAP_8(lc->l_array.la_type);
			lc->l_array.la_next =	BSWAP_16(lc->l_array.la_next);
			/* la_array doesn't need swapping */
			break;
		default:
			ASSERT(!"bad leaf type");
		}
	}
}
Ejemplo n.º 2
0
/* 
 * multi-session authcode generation for MD2
 * H(password + session_id + msg + session_seq + password)
 *
 * Use OpenSSL implementation of MD2 algorithm if found.
 * This function is analogous to ipmi_auth_md5
 */
uint8_t * ipmi_auth_md2(struct ipmi_session * s, uint8_t * data, int data_len)
{
#ifdef HAVE_CRYPTO_MD2
	MD2_CTX ctx;
	static uint8_t md[16];
	uint32_t temp;

#if WORDS_BIGENDIAN
	temp = BSWAP_32(s->in_seq);
#else
	temp = s->in_seq;
#endif
	memset(md, 0, 16);
	memset(&ctx, 0, sizeof(MD2_CTX));

	MD2_Init(&ctx);
	MD2_Update(&ctx, (const uint8_t *)s->authcode, 16);
	MD2_Update(&ctx, (const uint8_t *)&s->session_id, 4);
	MD2_Update(&ctx, (const uint8_t *)data, data_len);
	MD2_Update(&ctx, (const uint8_t *)&temp, sizeof(uint32_t));
	MD2_Update(&ctx, (const uint8_t *)s->authcode, 16);
	MD2_Final(md, &ctx);

	//if (verbose > 3)
	//	printf("  MD2 AuthCode    : %s\n", buf2str(md, 16));

	return md;
#else /*HAVE_CRYPTO_MD2*/
	static uint8_t md[16];
	memset(md, 0, 16);
	printf("WARNING: No internal support for MD2!  "
	       "Please re-compile with OpenSSL.\n");
	return md;
#endif /*HAVE_CRYPTO_MD2*/
}
Ejemplo n.º 3
0
/*
 * multi-session authcode generation for MD5
 * H(password + session_id + msg + session_seq + password)
 *
 * Use OpenSSL implementation of MD5 algorithm if found
 */
uint8_t * ipmi_auth_md5(struct ipmi_session * s, uint8_t * data, int data_len)
{
	md5_state_t state;
	static md5_byte_t digest[16];
	uint32_t temp;

	memset(digest, 0, 16);
	memset(&state, 0, sizeof(md5_state_t));

	md5_init(&state);

	md5_append(&state, (const md5_byte_t *)s->authcode, 16);
	md5_append(&state, (const md5_byte_t *)&s->session_id, 4);
	md5_append(&state, (const md5_byte_t *)data, data_len);

        if(!isLittleEndian())
	 temp = BSWAP_32(s->in_seq);
        else
	 temp = s->in_seq;

	md5_append(&state, (const md5_byte_t *)&temp, 4);
	md5_append(&state, (const md5_byte_t *)s->authcode, 16);

	md5_finish(&state, digest);

	if (verbose > 3)
		printf("  MD5 AuthCode    : %s\n", buf2str(digest, 16));
	return digest;
}
Ejemplo n.º 4
0
static int
decode (const void *ptr)
{
#if defined(sun) && defined(__SVR4)
    if (sizeof (int) == 4)
#ifdef _BIG_ENDIAN
        return *(const int *) ptr;
#else
        return BSWAP_32 (*(const int *) ptr);
#endif
#else
    if ((BYTE_ORDER == BIG_ENDIAN) && sizeof (int) == 4)
        return *(const int *) ptr;
    else if (BYTE_ORDER == LITTLE_ENDIAN && sizeof (int) == 4)
        return bswap_32 (*(const int *) ptr);
#endif
	else
	{
		const unsigned char *p = ptr;
		int result = *p & (1 << (CHAR_BIT - 1)) ? ~0 : 0;

		result = (result << 8) | *p++;
		result = (result << 8) | *p++;
		result = (result << 8) | *p++;
		result = (result << 8) | *p++;

		return result;
	}
}
Ejemplo n.º 5
0
void union_test() {
    union {
        uint64_t ull;
        uint8_t c[8];
        double d;
    } x = { .ull = 0x123456789abcdef0 };

    printf("%02X %02X %02X %02X %02X %02X %02X %02X\n",
            x.c[0], x.c[1], x.c[2], x.c[3],
            x.c[4], x.c[5], x.c[6], x.c[7]);

    printf("%llu\n", x.ull);

    x.d = 1.2344999991522893623141499119810760021209716796875;
    printf("%02X %02X %02X %02X %02X %02X %02X %02X\n",
            x.c[0], x.c[1], x.c[2], x.c[3],
            x.c[4], x.c[5], x.c[6], x.c[7]);
    printf("%e\n", x.d);

    x.ull = 0x3FF3C08312345678;
    printf("%02X %02X %02X %02X %02X %02X %02X %02X\n",
            x.c[0], x.c[1], x.c[2], x.c[3],
            x.c[4], x.c[5], x.c[6], x.c[7]);
}

static void test_b32() {
    unsigned char * c;
    uint32_t x = 0x12345678;
    c = (unsigned char *)&x;
    printf("%02X %02X %02X %02X\n", c[0], c[1], c[2], c[3]);
    uint32_t y = BSWAP_32(x);
    c = (unsigned char *)&y;
    printf("%02X %02X %02X %02X\n", c[0], c[1], c[2], c[3]);

}
Ejemplo n.º 6
0
static int
sa_build_index(sa_handle_t *hdl, sa_buf_type_t buftype)
{
	sa_hdr_phys_t *sa_hdr_phys;
	dmu_buf_impl_t *db = SA_GET_DB(hdl, buftype);
	dmu_object_type_t bonustype = SA_BONUSTYPE_FROM_DB(db);
	sa_os_t *sa = hdl->sa_os->os_sa;
	sa_idx_tab_t *idx_tab;

	sa_hdr_phys = SA_GET_HDR(hdl, buftype);

	mutex_enter(&sa->sa_lock);

	/* Do we need to byteswap? */

	/* only check if not old znode */
	if (IS_SA_BONUSTYPE(bonustype) && sa_hdr_phys->sa_magic != SA_MAGIC &&
	    sa_hdr_phys->sa_magic != 0) {
		VERIFY(BSWAP_32(sa_hdr_phys->sa_magic) == SA_MAGIC);
		sa_byteswap(hdl, buftype);
	}

	idx_tab = sa_find_idx_tab(hdl->sa_os, bonustype, sa_hdr_phys);

	if (buftype == SA_BONUS)
		hdl->sa_bonus_tab = idx_tab;
	else
		hdl->sa_spill_tab = idx_tab;

	mutex_exit(&sa->sa_lock);
	return (0);
}
Ejemplo n.º 7
0
static void
ipmi_pef_get_status(struct ipmi_intf * intf)
{	/*
	// report the PEF status
	*/
	struct ipmi_rs * rsp;
	struct ipmi_rq req;
	struct pef_cfgparm_selector psel;
	char tbuf[40];
	uint32_t timei;
	time_t ts;

	memset(&req, 0, sizeof(req));
	req.msg.netfn = IPMI_NETFN_SE;
	req.msg.cmd = IPMI_CMD_GET_LAST_PROCESSED_EVT_ID;
	rsp = ipmi_pef_msg_exchange(intf, &req, "Last S/W processed ID");
	if (!rsp) {
		lprintf(LOG_ERR, " **Error retrieving %s",
			"Last S/W processed ID");
		return;
	}
	memcpy(&timei, rsp->data, sizeof(timei));
#if WORDS_BIGENDIAN
	timei = BSWAP_32(timei);
#endif
	ts = (time_t)timei;

	strftime(tbuf, sizeof(tbuf), "%m/%d/%Y %H:%M:%S", gmtime(&ts));

	ipmi_pef_print_str("Last SEL addition", tbuf);
	ipmi_pef_print_2xd("Last SEL record ID", rsp->data[5], rsp->data[4]);
	ipmi_pef_print_2xd("Last S/W processed ID", rsp->data[7], rsp->data[6]);
	ipmi_pef_print_2xd("Last BMC processed ID", rsp->data[9], rsp->data[8]);

	memset(&psel, 0, sizeof(psel));
	psel.id = PEF_CFGPARM_ID_PEF_CONTROL;
	memset(&req, 0, sizeof(req));
	req.msg.netfn = IPMI_NETFN_SE;
	req.msg.cmd = IPMI_CMD_GET_PEF_CONFIG_PARMS;
	req.msg.data = (uint8_t *)&psel;
	req.msg.data_len = sizeof(psel);
	rsp = ipmi_pef_msg_exchange(intf, &req, "PEF control");
	if (!rsp) {
		lprintf(LOG_ERR, " **Error retrieving %s",
			"PEF control");
		return;
	}
	ipmi_pef_print_flags(&pef_b2s_control, P_ABLE, rsp->data[1]);

	psel.id = PEF_CFGPARM_ID_PEF_ACTION;
	rsp = ipmi_pef_msg_exchange(intf, &req, "PEF action");
	if (!rsp) {
		lprintf(LOG_ERR, " **Error retrieving %s",
			"PEF action");
		return;
	}
	ipmi_pef_print_flags(&pef_b2s_actions, P_ACTV, rsp->data[1]);
}
Ejemplo n.º 8
0
void
zfs_znode_byteswap(void *buf, size_t size)
{
	znode_phys_t *zp = buf;

	ASSERT(size >= sizeof (znode_phys_t));

	zp->zp_crtime[0] = BSWAP_64(zp->zp_crtime[0]);
	zp->zp_crtime[1] = BSWAP_64(zp->zp_crtime[1]);
	zp->zp_atime[0] = BSWAP_64(zp->zp_atime[0]);
	zp->zp_atime[1] = BSWAP_64(zp->zp_atime[1]);
	zp->zp_mtime[0] = BSWAP_64(zp->zp_mtime[0]);
	zp->zp_mtime[1] = BSWAP_64(zp->zp_mtime[1]);
	zp->zp_ctime[0] = BSWAP_64(zp->zp_ctime[0]);
	zp->zp_ctime[1] = BSWAP_64(zp->zp_ctime[1]);
	zp->zp_gen = BSWAP_64(zp->zp_gen);
	zp->zp_mode = BSWAP_64(zp->zp_mode);
	zp->zp_size = BSWAP_64(zp->zp_size);
	zp->zp_parent = BSWAP_64(zp->zp_parent);
	zp->zp_links = BSWAP_64(zp->zp_links);
	zp->zp_xattr = BSWAP_64(zp->zp_xattr);
	zp->zp_rdev = BSWAP_64(zp->zp_rdev);
	zp->zp_flags = BSWAP_64(zp->zp_flags);
	zp->zp_uid = BSWAP_64(zp->zp_uid);
	zp->zp_gid = BSWAP_64(zp->zp_gid);
	zp->zp_zap = BSWAP_64(zp->zp_zap);

	zp->zp_s2size = BSWAP_64(zp->zp_s2size);
	zp->zp_s2ptruncgen = BSWAP_32(zp->zp_s2ptruncgen);
	zp->zp_s2gen = BSWAP_32(zp->zp_s2gen);
	zp->zp_s2fid = BSWAP_64(zp->zp_s2fid);

	zp->zp_acl.z_acl_extern_obj = BSWAP_64(zp->zp_acl.z_acl_extern_obj);
	zp->zp_acl.z_acl_size = BSWAP_32(zp->zp_acl.z_acl_size);
	zp->zp_acl.z_acl_version = BSWAP_16(zp->zp_acl.z_acl_version);
	zp->zp_acl.z_acl_count = BSWAP_16(zp->zp_acl.z_acl_count);
	if (zp->zp_acl.z_acl_version == ZFS_ACL_VERSION) {
		zfs_acl_byteswap((void *)&zp->zp_acl.z_ace_data[0],
		    ZFS_ACE_SPACE);
	} else {
		zfs_oldace_byteswap((ace_t *)&zp->zp_acl.z_ace_data[0],
		    ACE_SLOT_CNT);
	}
}
Ejemplo n.º 9
0
static void
mzap_byteswap(mzap_phys_t *buf, size_t size)
{
	int i, maximum;
	buf->mz_block_type = BSWAP_64(buf->mz_block_type);
	buf->mz_salt = BSWAP_64(buf->mz_salt);
	maximum = (size / MZAP_ENT_LEN) - 1;
	for (i = 0; i < maximum; i++) {
		buf->mz_chunk[i].mze_value =
		    BSWAP_64(buf->mz_chunk[i].mze_value);
		buf->mz_chunk[i].mze_cd =
		    BSWAP_32(buf->mz_chunk[i].mze_cd);
	}
}
Ejemplo n.º 10
0
static int decode(const void *ptr)
{
#if defined(sun) && defined(__SVR4)
    if (sizeof(int) == 4) {
#if defined(_BIG_ENDIAN)
        return *(const int *)ptr;
#else
        return BSWAP_32(*(const int *)ptr);
#endif
#else
    if ((BYTE_ORDER == BIG_ENDIAN) && sizeof(int) == 4) {
        return *(const int *)ptr;
    } else if (BYTE_ORDER == LITTLE_ENDIAN && sizeof(int) == 4) {
        return (int)bswap_32(*(const unsigned int *)ptr);
#endif
    } else {
        const unsigned char *p = ptr;
        int result = *p & (1 << (CHAR_BIT - 1)) ? ~0 : 0;

        /* cppcheck-suppress shiftNegative */
        result = (result << 8) | *p++;
        result = (result << 8) | *p++;
        result = (result << 8) | *p++;
        result = (result << 8) | *p++;

        return result;
    }
}

static char *zname_from_stridx(char *str, size_t idx)
{
    size_t i;
    size_t size;
    char *ret;

    i = idx;
    while (str[i] != '\0') {
        i++;
    }

    size = i - idx;
    str += idx;
    ret = (char *)malloc(size + 1);
    ret = strncpy(ret, str, size);
    ret[size] = '\0';

    return ret;
}
Ejemplo n.º 11
0
void
fletcher_4_byteswap(const void *buf, uint64_t size, zio_cksum_t *zcp)
{
	const uint32_t *ip = buf;
	const uint32_t *ipend = ip + (size / sizeof (uint32_t));
	uint64_t a, b, c, d;

	for (a = b = c = d = 0; ip < ipend; ip++) {
		a += BSWAP_32(ip[0]);
		b += a;
		c += b;
		d += c;
	}

	ZIO_SET_CHECKSUM(zcp, a, b, c, d);
}
Ejemplo n.º 12
0
static void
fletcher_4_scalar_byteswap(const void *buf, uint64_t size, zio_cksum_t *zcp)
{
	const uint32_t *ip = buf;
	const uint32_t *ipend = ip + (size / sizeof (uint32_t));
	uint64_t a, b, c, d;

	a = zcp->zc_word[0];
	b = zcp->zc_word[1];
	c = zcp->zc_word[2];
	d = zcp->zc_word[3];

	for (; ip < ipend; ip++) {
		a += BSWAP_32(ip[0]);
		b += a;
		c += b;
		d += c;
	}

	ZIO_SET_CHECKSUM(zcp, a, b, c, d);
}
Ejemplo n.º 13
0
void
sa_byteswap(sa_handle_t *hdl, sa_buf_type_t buftype)
{
	sa_hdr_phys_t *sa_hdr_phys = SA_GET_HDR(hdl, buftype);
	dmu_buf_impl_t *db;
	sa_os_t *sa = hdl->sa_os->os_sa;
	int num_lengths = 1;
	int i;

	ASSERT(MUTEX_HELD(&sa->sa_lock));
	if (sa_hdr_phys->sa_magic == SA_MAGIC)
		return;

	db = SA_GET_DB(hdl, buftype);

	if (buftype == SA_SPILL) {
		arc_release(db->db_buf, NULL);
		arc_buf_thaw(db->db_buf);
	}

	sa_hdr_phys->sa_magic = BSWAP_32(sa_hdr_phys->sa_magic);
	sa_hdr_phys->sa_layout_info = BSWAP_16(sa_hdr_phys->sa_layout_info);

	/*
	 * Determine number of variable lenghts in header
	 * The standard 8 byte header has one for free and a
	 * 16 byte header would have 4 + 1;
	 */
	if (SA_HDR_SIZE(sa_hdr_phys) > 8)
		num_lengths += (SA_HDR_SIZE(sa_hdr_phys) - 8) >> 1;
	for (i = 0; i != num_lengths; i++)
		sa_hdr_phys->sa_lengths[i] =
		    BSWAP_16(sa_hdr_phys->sa_lengths[i]);

	sa_attr_iter(hdl->sa_os, sa_hdr_phys, DMU_OT_SA,
	    sa_byteswap_cb, NULL, hdl);

	if (buftype == SA_SPILL)
		arc_buf_freeze(((dmu_buf_impl_t *)hdl->sa_spill)->db_buf);
}
Ejemplo n.º 14
0
static void
fletcher_4_scalar_byteswap(fletcher_4_ctx_t *ctx, const void *buf,
    uint64_t size)
{
	const uint32_t *ip = buf;
	const uint32_t *ipend = ip + (size / sizeof (uint32_t));
	uint64_t a, b, c, d;

	a = ctx->scalar.zc_word[0];
	b = ctx->scalar.zc_word[1];
	c = ctx->scalar.zc_word[2];
	d = ctx->scalar.zc_word[3];

	for (; ip < ipend; ip++) {
		a += BSWAP_32(ip[0]);
		b += a;
		c += b;
		d += c;
	}

	ZIO_SET_CHECKSUM(&ctx->scalar, a, b, c, d);
}
Ejemplo n.º 15
0
static void
fletcher_4_superscalar4_byteswap(fletcher_4_ctx_t *ctx,
    const void *buf, uint64_t size)
{
	const uint32_t *ip = buf;
	const uint32_t *ipend = ip + (size / sizeof (uint32_t));
	uint64_t a, b, c, d;
	uint64_t a2, b2, c2, d2;
	uint64_t a3, b3, c3, d3;
	uint64_t a4, b4, c4, d4;

	a = ctx->superscalar[0].v[0];
	b = ctx->superscalar[1].v[0];
	c = ctx->superscalar[2].v[0];
	d = ctx->superscalar[3].v[0];
	a2 = ctx->superscalar[0].v[1];
	b2 = ctx->superscalar[1].v[1];
	c2 = ctx->superscalar[2].v[1];
	d2 = ctx->superscalar[3].v[1];
	a3 = ctx->superscalar[0].v[2];
	b3 = ctx->superscalar[1].v[2];
	c3 = ctx->superscalar[2].v[2];
	d3 = ctx->superscalar[3].v[2];
	a4 = ctx->superscalar[0].v[3];
	b4 = ctx->superscalar[1].v[3];
	c4 = ctx->superscalar[2].v[3];
	d4 = ctx->superscalar[3].v[3];

	for (; ip < ipend; ip += 4) {
		a += BSWAP_32(ip[0]);
		a2 += BSWAP_32(ip[1]);
		a3 += BSWAP_32(ip[2]);
		a4 += BSWAP_32(ip[3]);
		b += a;
		b2 += a2;
		b3 += a3;
		b4 += a4;
		c += b;
		c2 += b2;
		c3 += b3;
		c4 += b4;
		d += c;
		d2 += c2;
		d3 += c3;
		d4 += c4;
	}

	ctx->superscalar[0].v[0] = a;
	ctx->superscalar[1].v[0] = b;
	ctx->superscalar[2].v[0] = c;
	ctx->superscalar[3].v[0] = d;
	ctx->superscalar[0].v[1] = a2;
	ctx->superscalar[1].v[1] = b2;
	ctx->superscalar[2].v[1] = c2;
	ctx->superscalar[3].v[1] = d2;
	ctx->superscalar[0].v[2] = a3;
	ctx->superscalar[1].v[2] = b3;
	ctx->superscalar[2].v[2] = c3;
	ctx->superscalar[3].v[2] = d3;
	ctx->superscalar[0].v[3] = a4;
	ctx->superscalar[1].v[3] = b4;
	ctx->superscalar[2].v[3] = c4;
	ctx->superscalar[3].v[3] = d4;
}
Ejemplo n.º 16
0
/*
 * swap ace_t and ace_oject_t
 */
void
zfs_ace_byteswap(void *buf, size_t size, boolean_t zfs_layout)
{
	caddr_t end;
	caddr_t ptr;
	zfs_ace_t *zacep;
	ace_t *acep;
	uint16_t entry_type;
	size_t entry_size;
	int ace_type;

	end = (caddr_t)buf + size;
	ptr = buf;

	while (ptr < end) {
		if (zfs_layout) {
			/*
			 * Avoid overrun.  Embedded aces can have one
			 * of several sizes.  We don't know exactly
			 * how many our present, only the size of the
			 * buffer containing them.  That size may be
			 * larger than needed to hold the aces
			 * present.  As long as we do not do any
			 * swapping beyond the end of our block we are
			 * okay.  It it safe to swap any non-ace data
			 * within the block since it is just zeros.
			 */
			if (ptr + sizeof (zfs_ace_hdr_t) > end) {
				break;
			}
			zacep = (zfs_ace_t *)ptr;
			zacep->z_hdr.z_access_mask =
			    BSWAP_32(zacep->z_hdr.z_access_mask);
			zacep->z_hdr.z_flags = BSWAP_16(zacep->z_hdr.z_flags);
			ace_type = zacep->z_hdr.z_type =
			    BSWAP_16(zacep->z_hdr.z_type);
			entry_type = zacep->z_hdr.z_flags & ACE_TYPE_FLAGS;
		} else {
			/* Overrun avoidance */
			if (ptr + sizeof (ace_t) > end) {
				break;
			}
			acep = (ace_t *)ptr;
			acep->a_access_mask = BSWAP_32(acep->a_access_mask);
			acep->a_flags = BSWAP_16(acep->a_flags);
			ace_type = acep->a_type = BSWAP_16(acep->a_type);
			acep->a_who = BSWAP_32(acep->a_who);
			entry_type = acep->a_flags & ACE_TYPE_FLAGS;
		}
		switch (entry_type) {
		case ACE_OWNER:
		case ACE_EVERYONE:
		case (ACE_IDENTIFIER_GROUP | ACE_GROUP):
			entry_size = zfs_layout ?
			    sizeof (zfs_ace_hdr_t) : sizeof (ace_t);
			break;
		case ACE_IDENTIFIER_GROUP:
		default:
			/* Overrun avoidance */
			if (zfs_layout) {
				if (ptr + sizeof (zfs_ace_t) <= end) {
					zacep->z_fuid = BSWAP_64(zacep->z_fuid);
				} else {
					entry_size = sizeof (zfs_ace_t);
					break;
				}
			}
			switch (ace_type) {
			case ACE_ACCESS_ALLOWED_OBJECT_ACE_TYPE:
			case ACE_ACCESS_DENIED_OBJECT_ACE_TYPE:
			case ACE_SYSTEM_AUDIT_OBJECT_ACE_TYPE:
			case ACE_SYSTEM_ALARM_OBJECT_ACE_TYPE:
				entry_size = zfs_layout ?
				    sizeof (zfs_object_ace_t) :
				    sizeof (ace_object_t);
				break;
			default:
				entry_size = zfs_layout ? sizeof (zfs_ace_t) :
				    sizeof (ace_t);
				break;
			}
		}
		ptr = ptr + entry_size;
	}
}
Ejemplo n.º 17
0
int
uconv_u16tou32(const uint16_t *u16s, size_t *utf16len,
    uint32_t *u32s, size_t *utf32len, int flag)
{
	int inendian;
	int outendian;
	size_t u16l;
	size_t u32l;
	uint32_t hi;
	uint32_t lo;
	boolean_t do_not_ignore_null;

	/*
	 * Do preliminary validity checks on parameters and collect info on
	 * endians.
	 */
	if (u16s == NULL || utf16len == NULL)
		return (EILSEQ);

	if (u32s == NULL || utf32len == NULL)
		return (E2BIG);

	if (check_endian(flag, &inendian, &outendian) != 0)
		return (EBADF);

	/*
	 * Initialize input and output parameter buffer indices and
	 * temporary variables.
	 */
	u16l = u32l = 0;
	hi = 0;
	do_not_ignore_null = ((flag & UCONV_IGNORE_NULL) == 0);

	/*
	 * Check on the BOM at the beginning of the input buffer if required
	 * and if there is indeed one, process it.
	 */
	if ((flag & UCONV_IN_ACCEPT_BOM) &&
	    check_bom16(u16s, *utf16len, &inendian))
		u16l++;

	/*
	 * Reset inendian and outendian so that after this point, those can be
	 * used as condition values.
	 */
	inendian &= UCONV_IN_NAT_ENDIAN;
	outendian &= UCONV_OUT_NAT_ENDIAN;

	/*
	 * If there is something in the input buffer and if necessary and
	 * requested, save the BOM at the output buffer.
	 */
	if (*utf16len > 0 && *utf32len > 0 && (flag & UCONV_OUT_EMIT_BOM))
		u32s[u32l++] = (outendian) ? UCONV_BOM_NORMAL :
			UCONV_BOM_SWAPPED_32;

	/*
	 * Do conversion; if encounter a surrogate pair, assemble high and
	 * low pair values to form a UTF-32 character. If a half of a pair
	 * exists alone, then, either it is an illegal (EILSEQ) or
	 * invalid (EINVAL) value.
	 */
	for (; u16l < *utf16len; u16l++) {
		if (u16s[u16l] == 0 && do_not_ignore_null)
			break;

		lo = (uint32_t)((inendian) ? u16s[u16l] : BSWAP_16(u16s[u16l]));

		if (lo >= UCONV_U16_HI_MIN && lo <= UCONV_U16_HI_MAX) {
			if (hi)
				return (EILSEQ);
			hi = lo;
			continue;
		} else if (lo >= UCONV_U16_LO_MIN && lo <= UCONV_U16_LO_MAX) {
			if (! hi)
				return (EILSEQ);
			lo = (((hi - UCONV_U16_HI_MIN) * UCONV_U16_BIT_SHIFT +
				lo - UCONV_U16_LO_MIN) & UCONV_U16_BIT_MASK)
				+ UCONV_U16_START;
			hi = 0;
		} else if (hi) {
			return (EILSEQ);
		}

		if (u32l >= *utf32len)
			return (E2BIG);

		u32s[u32l++] = (outendian) ? lo : BSWAP_32(lo);
	}

	/*
	 * If high half didn't see low half, then, it's most likely the input
	 * parameter is incomplete.
	 */
	if (hi)
		return (EINVAL);

	/*
	 * Save the number of consumed and saved characters. They do not
	 * include terminating NULL character (U+0000) at the end of
	 * the input buffer (even when UCONV_IGNORE_NULL isn't specified and
	 * the input buffer length is big enough to include the terminating
	 * NULL character).
	 */
	*utf16len = u16l;
	*utf32len = u32l;

	return (0);
}
Ejemplo n.º 18
0
Archivo: zfs_vfsops.c Proyecto: nwf/zfs
static int
zfs_space_delta_cb(dmu_object_type_t bonustype, void *data,
    uint64_t *userp, uint64_t *groupp)
{
	/*
	 * Is it a valid type of object to track?
	 */
	if (bonustype != DMU_OT_ZNODE && bonustype != DMU_OT_SA)
		return (SET_ERROR(ENOENT));

	/*
	 * If we have a NULL data pointer
	 * then assume the id's aren't changing and
	 * return EEXIST to the dmu to let it know to
	 * use the same ids
	 */
	if (data == NULL)
		return (SET_ERROR(EEXIST));

	if (bonustype == DMU_OT_ZNODE) {
		znode_phys_t *znp = data;
		*userp = znp->zp_uid;
		*groupp = znp->zp_gid;
	} else {
		int hdrsize;
		sa_hdr_phys_t *sap = data;
		sa_hdr_phys_t sa = *sap;
		boolean_t swap = B_FALSE;

		ASSERT(bonustype == DMU_OT_SA);

		if (sa.sa_magic == 0) {
			/*
			 * This should only happen for newly created
			 * files that haven't had the znode data filled
			 * in yet.
			 */
			*userp = 0;
			*groupp = 0;
			return (0);
		}
		if (sa.sa_magic == BSWAP_32(SA_MAGIC)) {
			sa.sa_magic = SA_MAGIC;
			sa.sa_layout_info = BSWAP_16(sa.sa_layout_info);
			swap = B_TRUE;
		} else {
			VERIFY3U(sa.sa_magic, ==, SA_MAGIC);
		}

		hdrsize = sa_hdrsize(&sa);
		VERIFY3U(hdrsize, >=, sizeof (sa_hdr_phys_t));
		*userp = *((uint64_t *)((uintptr_t)data + hdrsize +
		    SA_UID_OFFSET));
		*groupp = *((uint64_t *)((uintptr_t)data + hdrsize +
		    SA_GID_OFFSET));
		if (swap) {
			*userp = BSWAP_64(*userp);
			*groupp = BSWAP_64(*groupp);
		}
	}
	return (0);
}
Ejemplo n.º 19
0
/*
 * swap ace_t and ace_oject_t
 */
void
zfs_ace_byteswap(void *buf, size_t size, boolean_t zfs_layout)
{
#ifdef TODO
	caddr_t end;
	caddr_t ptr;
	zfs_ace_t *zacep;
	ace_t *acep;
	uint16_t entry_type;
	size_t entry_size;
	int ace_type;

	end = (caddr_t)buf + size;
	ptr = buf;

	while (ptr < end) {
		if (zfs_layout) {
			zacep = (zfs_ace_t *)ptr;
			zacep->z_hdr.z_access_mask =
			    BSWAP_32(zacep->z_hdr.z_access_mask);
			zacep->z_hdr.z_flags = BSWAP_16(zacep->z_hdr.z_flags);
			ace_type = zacep->z_hdr.z_type =
			    BSWAP_16(zacep->z_hdr.z_type);
			entry_type = zacep->z_hdr.z_flags & ACE_TYPE_FLAGS;
		} else {
			acep = (ace_t *)ptr;
			acep->a_access_mask = BSWAP_32(acep->a_access_mask);
			acep->a_flags = BSWAP_16(acep->a_flags);
			ace_type = acep->a_type = BSWAP_16(acep->a_type);
			acep->a_who = BSWAP_32(acep->a_who);
			entry_type = acep->a_flags & ACE_TYPE_FLAGS;
		}
		switch (entry_type) {
		case ACE_OWNER:
		case ACE_EVERYONE:
		case (ACE_IDENTIFIER_GROUP | ACE_GROUP):
			entry_size = zfs_layout ?
			    sizeof (zfs_ace_hdr_t) : sizeof (ace_t);
			break;
		case ACE_IDENTIFIER_GROUP:
		default:
			if (zfs_layout) {
				zacep->z_fuid = BSWAP_64(zacep->z_fuid);
			}
			switch (ace_type) {
			case ACE_ACCESS_ALLOWED_OBJECT_ACE_TYPE:
			case ACE_ACCESS_DENIED_OBJECT_ACE_TYPE:
			case ACE_SYSTEM_AUDIT_OBJECT_ACE_TYPE:
			case ACE_SYSTEM_ALARM_OBJECT_ACE_TYPE:
				entry_size = zfs_layout ?
				    sizeof (zfs_object_ace_t) :
				    sizeof (ace_object_t);
				break;
			default:
				entry_size = zfs_layout ? sizeof (zfs_ace_t) :
				    sizeof (ace_t);
				break;
			}
		}
		ptr = ptr + entry_size;
	}
#else	/* TODO */
	panic("%s:%u: TODO", __func__, __LINE__);
#endif	/* TODO */
}
Ejemplo n.º 20
0
int
main(int argc, char *argv[])
{
    char *buf = malloc(INITIAL_BUFLEN);
    dmu_replay_record_t thedrr;
    dmu_replay_record_t *drr = &thedrr;
    struct drr_begin *drrb = &thedrr.drr_u.drr_begin;
    struct drr_end *drre = &thedrr.drr_u.drr_end;
    struct drr_object *drro = &thedrr.drr_u.drr_object;
    struct drr_freeobjects *drrfo = &thedrr.drr_u.drr_freeobjects;
    struct drr_write *drrw = &thedrr.drr_u.drr_write;
    struct drr_write_byref *drrwbr = &thedrr.drr_u.drr_write_byref;
    struct drr_free *drrf = &thedrr.drr_u.drr_free;
    struct drr_spill *drrs = &thedrr.drr_u.drr_spill;
    char c;
    boolean_t verbose = B_FALSE;
    boolean_t first = B_TRUE;
    int err;
    zio_cksum_t zc = { 0 };
    zio_cksum_t pcksum = { 0 };

    while ((c = getopt(argc, argv, ":vC")) != -1) {
        switch (c) {
        case 'C':
            do_cksum = B_FALSE;
            break;
        case 'v':
            verbose = B_TRUE;
            break;
        case ':':
            (void) fprintf(stderr,
                           "missing argument for '%c' option\n", optopt);
            usage();
            break;
        case '?':
            (void) fprintf(stderr, "invalid option '%c'\n",
                           optopt);
            usage();
        }
    }

    if (isatty(STDIN_FILENO)) {
        (void) fprintf(stderr,
                       "Error: Backup stream can not be read "
                       "from a terminal.\n"
                       "You must redirect standard input.\n");
        exit(1);
    }

    send_stream = stdin;
    pcksum = zc;
    while (ssread(drr, sizeof (dmu_replay_record_t), &zc)) {

        if (first) {
            if (drrb->drr_magic == BSWAP_64(DMU_BACKUP_MAGIC)) {
                do_byteswap = B_TRUE;
                if (do_cksum) {
                    ZIO_SET_CHECKSUM(&zc, 0, 0, 0, 0);
                    /*
                     * recalculate header checksum now
                     * that we know it needs to be
                     * byteswapped.
                     */
                    fletcher_4_incremental_byteswap(drr,
                                                    sizeof (dmu_replay_record_t), &zc);
                }
            } else if (drrb->drr_magic != DMU_BACKUP_MAGIC) {
                (void) fprintf(stderr, "Invalid stream "
                               "(bad magic number)\n");
                exit(1);
            }
            first = B_FALSE;
        }
        if (do_byteswap) {
            drr->drr_type = BSWAP_32(drr->drr_type);
            drr->drr_payloadlen =
                BSWAP_32(drr->drr_payloadlen);
        }

        /*
         * At this point, the leading fields of the replay record
         * (drr_type and drr_payloadlen) have been byte-swapped if
         * necessary, but the rest of the data structure (the
         * union of type-specific structures) is still in its
         * original state.
         */
        if (drr->drr_type >= DRR_NUMTYPES) {
            (void) printf("INVALID record found: type 0x%x\n",
                          drr->drr_type);
            (void) printf("Aborting.\n");
            exit(1);
        }

        drr_record_count[drr->drr_type]++;

        switch (drr->drr_type) {
        case DRR_BEGIN:
            if (do_byteswap) {
                drrb->drr_magic = BSWAP_64(drrb->drr_magic);
                drrb->drr_versioninfo =
                    BSWAP_64(drrb->drr_versioninfo);
                drrb->drr_creation_time =
                    BSWAP_64(drrb->drr_creation_time);
                drrb->drr_type = BSWAP_32(drrb->drr_type);
                drrb->drr_flags = BSWAP_32(drrb->drr_flags);
                drrb->drr_toguid = BSWAP_64(drrb->drr_toguid);
                drrb->drr_fromguid =
                    BSWAP_64(drrb->drr_fromguid);
            }

            (void) printf("BEGIN record\n");
            (void) printf("\thdrtype = %lld\n",
                          DMU_GET_STREAM_HDRTYPE(drrb->drr_versioninfo));
            (void) printf("\tfeatures = %llx\n",
                          DMU_GET_FEATUREFLAGS(drrb->drr_versioninfo));
            (void) printf("\tmagic = %llx\n",
                          (u_longlong_t)drrb->drr_magic);
            (void) printf("\tcreation_time = %llx\n",
                          (u_longlong_t)drrb->drr_creation_time);
            (void) printf("\ttype = %u\n", drrb->drr_type);
            (void) printf("\tflags = 0x%x\n", drrb->drr_flags);
            (void) printf("\ttoguid = %llx\n",
                          (u_longlong_t)drrb->drr_toguid);
            (void) printf("\tfromguid = %llx\n",
                          (u_longlong_t)drrb->drr_fromguid);
            (void) printf("\ttoname = %s\n", drrb->drr_toname);
            if (verbose)
                (void) printf("\n");

            if ((DMU_GET_STREAM_HDRTYPE(drrb->drr_versioninfo) ==
                    DMU_COMPOUNDSTREAM) && drr->drr_payloadlen != 0) {
                nvlist_t *nv;
                int sz = drr->drr_payloadlen;

                if (sz > 1<<20) {
                    free(buf);
                    buf = malloc(sz);
                }
                (void) ssread(buf, sz, &zc);
                if (ferror(send_stream))
                    perror("fread");
                err = nvlist_unpack(buf, sz, &nv, 0);
                if (err)
                    perror(strerror(err));
                nvlist_print(stdout, nv);
                nvlist_free(nv);
            }
            break;

        case DRR_END:
            if (do_byteswap) {
                drre->drr_checksum.zc_word[0] =
                    BSWAP_64(drre->drr_checksum.zc_word[0]);
                drre->drr_checksum.zc_word[1] =
                    BSWAP_64(drre->drr_checksum.zc_word[1]);
                drre->drr_checksum.zc_word[2] =
                    BSWAP_64(drre->drr_checksum.zc_word[2]);
                drre->drr_checksum.zc_word[3] =
                    BSWAP_64(drre->drr_checksum.zc_word[3]);
            }
            /*
             * We compare against the *previous* checksum
             * value, because the stored checksum is of
             * everything before the DRR_END record.
             */
            if (do_cksum && !ZIO_CHECKSUM_EQUAL(drre->drr_checksum,
                                                pcksum)) {
                (void) printf("Expected checksum differs from "
                              "checksum in stream.\n");
                (void) printf("Expected checksum = %"
                              FX64 "/%" FX64 "/%" FX64 "/%" FX64 "\n",
                              pcksum.zc_word[0],
                              pcksum.zc_word[1],
                              pcksum.zc_word[2],
                              pcksum.zc_word[3]);
            }
            (void) printf("END checksum = %" FX64 "/%" FX64 "/%" FX64 "/%" FX64 "\n",
                          drre->drr_checksum.zc_word[0],
                          drre->drr_checksum.zc_word[1],
                          drre->drr_checksum.zc_word[2],
                          drre->drr_checksum.zc_word[3]);

            ZIO_SET_CHECKSUM(&zc, 0, 0, 0, 0);
            break;

        case DRR_OBJECT:
            if (do_byteswap) {
                drro->drr_object = BSWAP_64(drro->drr_object);
                drro->drr_type = BSWAP_32(drro->drr_type);
                drro->drr_bonustype =
                    BSWAP_32(drro->drr_bonustype);
                drro->drr_blksz = BSWAP_32(drro->drr_blksz);
                drro->drr_bonuslen =
                    BSWAP_32(drro->drr_bonuslen);
                drro->drr_toguid = BSWAP_64(drro->drr_toguid);
            }
            if (verbose) {
                (void) printf("OBJECT object = %llu type = %u "
                              "bonustype = %u blksz = %u bonuslen = %u\n",
                              (u_longlong_t)drro->drr_object,
                              drro->drr_type,
                              drro->drr_bonustype,
                              drro->drr_blksz,
                              drro->drr_bonuslen);
            }
            if (drro->drr_bonuslen > 0) {
                (void) ssread(buf, P2ROUNDUP(drro->drr_bonuslen,
                                             8), &zc);
            }
            break;

        case DRR_FREEOBJECTS:
            if (do_byteswap) {
                drrfo->drr_firstobj =
                    BSWAP_64(drrfo->drr_firstobj);
                drrfo->drr_numobjs =
                    BSWAP_64(drrfo->drr_numobjs);
                drrfo->drr_toguid = BSWAP_64(drrfo->drr_toguid);
            }
            if (verbose) {
                (void) printf("FREEOBJECTS firstobj = %llu "
                              "numobjs = %llu\n",
                              (u_longlong_t)drrfo->drr_firstobj,
                              (u_longlong_t)drrfo->drr_numobjs);
            }
            break;

        case DRR_WRITE:
            if (do_byteswap) {
                drrw->drr_object = BSWAP_64(drrw->drr_object);
                drrw->drr_type = BSWAP_32(drrw->drr_type);
                drrw->drr_offset = BSWAP_64(drrw->drr_offset);
                drrw->drr_length = BSWAP_64(drrw->drr_length);
                drrw->drr_toguid = BSWAP_64(drrw->drr_toguid);
                drrw->drr_key.ddk_prop =
                    BSWAP_64(drrw->drr_key.ddk_prop);
            }
            if (verbose) {
                (void) printf("WRITE object = %llu type = %u "
                              "checksum type = %u\n"
                              "offset = %llu length = %llu "
                              "props = %llx\n",
                              (u_longlong_t)drrw->drr_object,
                              drrw->drr_type,
                              drrw->drr_checksumtype,
                              (u_longlong_t)drrw->drr_offset,
                              (u_longlong_t)drrw->drr_length,
                              (u_longlong_t)drrw->drr_key.ddk_prop);
            }
            (void) ssread(buf, drrw->drr_length, &zc);
            total_write_size += drrw->drr_length;
            break;

        case DRR_WRITE_BYREF:
            if (do_byteswap) {
                drrwbr->drr_object =
                    BSWAP_64(drrwbr->drr_object);
                drrwbr->drr_offset =
                    BSWAP_64(drrwbr->drr_offset);
                drrwbr->drr_length =
                    BSWAP_64(drrwbr->drr_length);
                drrwbr->drr_toguid =
                    BSWAP_64(drrwbr->drr_toguid);
                drrwbr->drr_refguid =
                    BSWAP_64(drrwbr->drr_refguid);
                drrwbr->drr_refobject =
                    BSWAP_64(drrwbr->drr_refobject);
                drrwbr->drr_refoffset =
                    BSWAP_64(drrwbr->drr_refoffset);
                drrwbr->drr_key.ddk_prop =
                    BSWAP_64(drrwbr->drr_key.ddk_prop);
            }
            if (verbose) {
                (void) printf("WRITE_BYREF object = %llu "
                              "checksum type = %u props = %llx\n"
                              "offset = %llu length = %llu\n"
                              "toguid = %llx refguid = %llx\n"
                              "refobject = %llu refoffset = %llu\n",
                              (u_longlong_t)drrwbr->drr_object,
                              drrwbr->drr_checksumtype,
                              (u_longlong_t)drrwbr->drr_key.ddk_prop,
                              (u_longlong_t)drrwbr->drr_offset,
                              (u_longlong_t)drrwbr->drr_length,
                              (u_longlong_t)drrwbr->drr_toguid,
                              (u_longlong_t)drrwbr->drr_refguid,
                              (u_longlong_t)drrwbr->drr_refobject,
                              (u_longlong_t)drrwbr->drr_refoffset);
            }
            break;

        case DRR_FREE:
            if (do_byteswap) {
                drrf->drr_object = BSWAP_64(drrf->drr_object);
                drrf->drr_offset = BSWAP_64(drrf->drr_offset);
                drrf->drr_length = BSWAP_64(drrf->drr_length);
            }
            if (verbose) {
                (void) printf("FREE object = %llu "
                              "offset = %llu length = %lld\n",
                              (u_longlong_t)drrf->drr_object,
                              (u_longlong_t)drrf->drr_offset,
                              (longlong_t)drrf->drr_length);
            }
            break;
        case DRR_SPILL:
            if (do_byteswap) {
                drrs->drr_object = BSWAP_64(drrs->drr_object);
                drrs->drr_length = BSWAP_64(drrs->drr_length);
            }
            if (verbose) {
                (void) printf("SPILL block for object = %" FU64
                              "length = %" FU64 "\n", drrs->drr_object,
                              drrs->drr_length);
            }
            (void) ssread(buf, drrs->drr_length, &zc);
            break;
        }
        pcksum = zc;
    }
    free(buf);

    /* Print final summary */

    (void) printf("SUMMARY:\n");
    (void) printf("\tTotal DRR_BEGIN records = %lld\n",
                  (u_longlong_t)drr_record_count[DRR_BEGIN]);
    (void) printf("\tTotal DRR_END records = %lld\n",
                  (u_longlong_t)drr_record_count[DRR_END]);
    (void) printf("\tTotal DRR_OBJECT records = %lld\n",
                  (u_longlong_t)drr_record_count[DRR_OBJECT]);
    (void) printf("\tTotal DRR_FREEOBJECTS records = %lld\n",
                  (u_longlong_t)drr_record_count[DRR_FREEOBJECTS]);
    (void) printf("\tTotal DRR_WRITE records = %lld\n",
                  (u_longlong_t)drr_record_count[DRR_WRITE]);
    (void) printf("\tTotal DRR_FREE records = %lld\n",
                  (u_longlong_t)drr_record_count[DRR_FREE]);
    (void) printf("\tTotal DRR_SPILL records = %lld\n",
                  (u_longlong_t)drr_record_count[DRR_SPILL]);
    (void) printf("\tTotal records = %lld\n",
                  (u_longlong_t)(drr_record_count[DRR_BEGIN] +
                                 drr_record_count[DRR_OBJECT] +
                                 drr_record_count[DRR_FREEOBJECTS] +
                                 drr_record_count[DRR_WRITE] +
                                 drr_record_count[DRR_FREE] +
                                 drr_record_count[DRR_SPILL] +
                                 drr_record_count[DRR_END]));
    (void) printf("\tTotal write size = %lld (0x%llx)\n",
                  (u_longlong_t)total_write_size, (u_longlong_t)total_write_size);
    (void) printf("\tTotal stream length = %lld (0x%llx)\n",
                  (u_longlong_t)total_stream_len, (u_longlong_t)total_stream_len);
    return (0);
}
Ejemplo n.º 21
0
DWORD CALLBACK ArpScanThread(CArpScanner * cls)
{
   /* Initialize WinPCAP */
   //TWinPCAP pcap;

   if (cls->pcap.LoadPCAP())
   {
      /* Get adapter parameters */
      IN_ADDR adapter_ip;
      unsigned char adapter_mac[6];

      /* Get IP and MAC */
      cls->pcap.GetAdapterIP(cls->sci_Adapter, &adapter_ip, NULL);
      cls->pcap.GetAdapterMAC(cls->sci_Adapter, adapter_mac);

      /* Clear all contexts */
      for (int i = 0; i < MAX_CONCURRENT_SCANS; i++)
      {
         cls->scan_ctx[i].addr.S_un.S_addr = 0; /* IP address we send packet for */
         cls->scan_ctx[i].replied = false;      /* was out request replied at least one time */
         cls->scan_ctx[i].timeout = 0;          /* when will this request time out */
         cls->scan_ctx[i].requested = false;    /* the request was sent and waiting for response */
      }

      /* Set starting ip address */
      IN_ADDR  current_ip = cls->sci_StartIP;

      /* start WinPCAP adapter capturing */
      if (cls->pcap.OpenAdapter(cls->sci_Adapter))
      {
         /* Scan started */
         cls->scanned_host_count = 0;
         __raise cls->OnScanStart();

         /* prepare */
         DWORD last_arp_sent = 0;

         /* loop while there are waiting scans and ending IP is not reached */
         do
         {
            /* check for received packets, parse them, verify context and raise OnScanHost events */
            CheckPCAPPackets(cls, &cls->pcap, &adapter_ip);

            /* check for context freeing and allocate next IP */
            for (int i = 0; i < MAX_CONCURRENT_SCANS; i++)
            {
               /* check for timeout */
               if (cls->scan_ctx[i].timeout < GetTickCount())
               {
                  /* requested but unreplied */
                  if (cls->scan_ctx[i].requested && !cls->scan_ctx[i].replied)
                  {
                     CComBSTR tmp_ip(inet_ntoa(cls->scan_ctx[i].addr));
                     cls->scanned_host_count++;

                     /* 1 = functional, 0 = demo */
#if 1
                     /* Actual - signal a timeout */
                     CComBSTR tmp_mac("");
                     __raise cls->OnScanHost(tmp_ip.Copy(), tmp_mac.Copy(), -1);
#else
                     /* Demo - random results */
                     if (rand() % 2)
                     {
                        unsigned char t_mac[6];
                        char          t_mac_txt[18];
                        for (int i = 0; i < 6; t_mac[i++] = rand() & 0xFF);
                        MAC2TXT(t_mac_txt, t_mac);
                        CComBSTR tmp_mac(t_mac_txt);
                        __raise cls->OnScanHost(tmp_ip.Copy(), tmp_mac.Copy(), rand() % 1000);
                     }
                     else
                     {
                        CComBSTR tmp_mac("");
                        __raise cls->OnScanHost(tmp_ip.Copy(), tmp_mac.Copy(), -1);
                     }
#endif
                  }
                  else if (cls->scan_ctx[i].requested && cls->scan_ctx[i].replied)
                  {
                     /* just count a host - events were raised in CheckPCAPPackets */
                     cls->scanned_host_count++;
                  }

                  /* in case of timeout mark the context as not requested */
                  cls->scan_ctx[i].requested = false;
               }

               /* is the context free so we can use it (and last request was sent enough time ago ? */
               if ((!cls->scan_ctx[i].requested) && 
                   (BSWAP_32(current_ip.S_un.S_addr) <= BSWAP_32(cls->sci_EndIP.S_un.S_addr)) && 
                   (GetTickCount() > (last_arp_sent + (MAX_ARP_SCAN_TIMEOUT / MAX_CONCURRENT_SCANS))))
               {
                  /* initialize a context with new address and timeout */
                  cls->scan_ctx[i].timeout = GetTickCount() + MAX_ARP_SCAN_TIMEOUT;
                  cls->scan_ctx[i].addr.S_un.S_addr = current_ip.S_un.S_addr;
                  cls->scan_ctx[i].requested = true;
                  cls->scan_ctx[i].replied = false;

                  /* craft an ARP Request packet and Send it to the network */
                  TIPv4ARP arp_pkt;
                  ARP_PrepareRequest(&arp_pkt, adapter_mac, adapter_ip, current_ip);
                  cls->pcap.SendPacket(NULL, NULL, 0x0806, (unsigned char *)&arp_pkt, sizeof(arp_pkt));
                  last_arp_sent = GetTickCount();

                  /* jump to next address */
                  current_ip.S_un.S_addr = BSWAP_32(BSWAP_32(current_ip.S_un.S_addr) + 1);
               }
            }

            /* Give up some CPU time */
            Sleep(1);
         } while (cls->ScansActive() && !cls->terminate_scan);

         /* Scan ended */
         __raise cls->OnStartStop();

         /* close adapter */
         cls->pcap.CloseAdapter();
      }
      else
      {
         /* error opening adapter */
         __raise cls->OnScanError(E_COULD_NOT_OPEN_ADAPTER);
      }
   }
   else
   {
      /* error loading WinPCAP */
      __raise cls->OnScanError(E_WINPCAP_NOT_FOUND);
   }

   /* Perform thread cleanup */
   CloseHandle(cls->scan_thread);
   cls->scan_thread = NULL;

   return 0;
}