int iscsi_pdu_add_data(struct iscsi_context *iscsi, struct iscsi_pdu *pdu, unsigned char *dptr, int dsize) { if (pdu == NULL) { iscsi_set_error(iscsi, "trying to add data to NULL pdu"); return -1; } if (dsize == 0) { iscsi_set_error(iscsi, "Trying to append zero size data to " "pdu"); return -1; } if (iscsi_add_data(iscsi, &pdu->outdata, dptr, dsize, 1) != 0) { iscsi_set_error(iscsi, "failed to add data to pdu buffer"); return -1; } /* update data segment length */ *(uint32_t *)&pdu->outdata.data[4] = htonl(pdu->outdata.size - ISCSI_HEADER_SIZE); return 0; }
int iscsi_process_scsi_data_in(struct iscsi_context *iscsi, struct iscsi_pdu *pdu, const unsigned char *hdr, int size, int *is_finished) { int statsn, flags, status; struct iscsi_scsi_cbdata *scsi_cbdata = pdu->scsi_cbdata; struct scsi_task *task = scsi_cbdata->task; int dsl; statsn = ntohl(*(uint32_t *)&hdr[24]); if (statsn > (int)iscsi->statsn) { iscsi->statsn = statsn; } flags = hdr[1]; if ((flags&ISCSI_PDU_DATA_ACK_REQUESTED) != 0) { printf("scsi response asked for ACK 0x%02x\n", flags); pdu->callback(iscsi, ISCSI_STATUS_ERROR, task, pdu->private_data); return -1; } /* for now, we ignore all overflow/underflow flags. We just print/log them so we can tweak * libiscsi to not generate under/over flows */ if ((flags&ISCSI_PDU_DATA_RESIDUAL_OVERFLOW) != 0) { printf("scsi response contains residual overflow 0x%02x\n", flags); } if ((flags&ISCSI_PDU_DATA_RESIDUAL_UNDERFLOW) != 0) { printf("scsi response contains residual underflow 0x%02x\n", flags); } dsl = ntohl(*(uint32_t *)&hdr[4])&0x00ffffff; if (dsl > size - ISCSI_HEADER_SIZE) { printf ("dsl is :%d, while buffser size if %d\n", dsl, size - ISCSI_HEADER_SIZE); } if (iscsi_add_data(&pdu->indata, discard_const(hdr + ISCSI_HEADER_SIZE), dsl, 0) != 0) { printf("failed to add data to pdu in buffer\n"); return -3; } if ((flags&ISCSI_PDU_DATA_FINAL) == 0) { printf("scsi data-in without Final bit: 0x%02x\n", flags); *is_finished = 0; } if ((flags&ISCSI_PDU_DATA_CONTAINS_STATUS) == 0) { printf("scsi data-in without Status bit: 0x%02x\n", flags); *is_finished = 0; } if (*is_finished == 0) { return 0; } /* this was the final data-in packet in the sequence and it has the s-bit set, so invoke the * callback. */ status = hdr[3]; task->datain.data = pdu->indata.data; task->datain.size = pdu->indata.size; pdu->callback(iscsi, status, task, pdu->private_data); return 0; }