/**
 * ib_ud_header_unpack - Unpack UD header struct from wire format
 * @header:UD header struct
 * @buf:Buffer to pack into
 *
 * ib_ud_header_pack() unpacks the UD header structure @header from wire
 * format in the buffer @buf.
 */
int ib_ud_header_unpack(void                *buf,
			struct ib_ud_header *header)
{
	ib_unpack(lrh_table, ARRAY_SIZE(lrh_table),
		  buf, &header->lrh);
	buf += IB_LRH_BYTES;

	if (header->lrh.link_version != 0) {
		printk(KERN_WARNING "Invalid LRH.link_version %d\n",
		       header->lrh.link_version);
		return -EINVAL;
	}

	switch (header->lrh.link_next_header) {
	case IB_LNH_IBA_LOCAL:
		header->grh_present = 0;
		break;

	case IB_LNH_IBA_GLOBAL:
		header->grh_present = 1;
		ib_unpack(grh_table, ARRAY_SIZE(grh_table),
			  buf, &header->grh);
		buf += IB_GRH_BYTES;

		if (header->grh.ip_version != 6) {
			printk(KERN_WARNING "Invalid GRH.ip_version %d\n",
			       header->grh.ip_version);
			return -EINVAL;
		}
		if (header->grh.next_header != 0x1b) {
			printk(KERN_WARNING "Invalid GRH.next_header 0x%02x\n",
			       header->grh.next_header);
			return -EINVAL;
		}
		break;

	default:
		printk(KERN_WARNING "Invalid LRH.link_next_header %d\n",
		       header->lrh.link_next_header);
		return -EINVAL;
	}

	ib_unpack(bth_table, ARRAY_SIZE(bth_table),
		  buf, &header->bth);
	buf += IB_BTH_BYTES;

	switch (header->bth.opcode) {
	case IB_OPCODE_UD_SEND_ONLY:
		header->immediate_present = 0;
		break;
	case IB_OPCODE_UD_SEND_ONLY_WITH_IMMEDIATE:
		header->immediate_present = 1;
		break;
	default:
		printk(KERN_WARNING "Invalid BTH.opcode 0x%02x\n",
		       header->bth.opcode);
		return -EINVAL;
	}

	if (header->bth.transport_header_version != 0) {
		printk(KERN_WARNING "Invalid BTH.transport_header_version %d\n",
		       header->bth.transport_header_version);
		return -EINVAL;
	}

	ib_unpack(deth_table, ARRAY_SIZE(deth_table),
		  buf, &header->deth);
	buf += IB_DETH_BYTES;

	if (header->immediate_present)
		memcpy(&header->immediate_data, buf, sizeof header->immediate_data);

	return 0;
}
Exemple #2
0
/**
 * ib_lrh_header_unpack - Unpack LRH structure from wire format
 * @lrh:unpacked LRH header struct
 * @buf:Buffer to pack into
 *
 * ib_lrh_header_unpack() unpacks the LRH header structure from
 * wire format (in buf) into @lrh.
 */
int ib_lrh_header_unpack(void *buf, struct ib_unpacked_lrh *lrh)
{
	ib_unpack(lrh_table, ARRAY_SIZE(lrh_table), buf, lrh);
	return 0;
}