⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usr_targ_x86.c

📁 一个iSCSI协议实现源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*  *  $Id: usr_targ_x86.c,v 1.3 2001/04/21 04:07:01 mbrown Exp $ * *  Implements iSCSI user space target  *  *  Changes : * *  $Log: usr_targ_x86.c,v $ *  Revision 1.3  2001/04/21 04:07:01  mbrown *  more bug fixing, mount readonly works, use the new DISK file, it *  contains a valid ext2 partition * *  Revision 1.2  2001/04/19 15:16:50  mbrown *  devices now show up, fdisk still causes a kernel panic, *  checkin per jhawkins' request * *  Revision 1.1  2001/04/06 04:06:06  mbrown *  Usermode target.  Modified version of UNH Interoperability Lab's version * * *//* Credits: * * Most of the ideas expressed, and some verbatim code was borrowed from * Chris Loveland and other members of the UNH Ineroperability Lab's * userspace target iSCSI implementation found here: * ftp://ftp.iol.unh.edu/pub/iscsi/iscsi-3_init.tgz */#include <sys/types.h>#include <linux/types.h>#include <sys/socket.h>#include <sys/stat.h>#include <netinet/in.h>#include <fcntl.h>#include <unistd.h>#include <stdio.h>#include <stdlib.h>#include <errno.h>#include <scsi/scsi.h>/* junk to let me include iscsi.h */typedef unsigned char u8;typedef unsigned int u32;typedef unsigned short u16;typedef int s32;typedef short s16;typedef unsigned long long int u64;typedef long long int s64;struct socket {};#include "iscsi.h"typedef unsigned char byte;#define BUF_LEN 2000int init_server();int rx_login(int sock, iscsi_header_t *);int rx_scsi_cmd(int sock, iscsi_header_t *);int rx_scsi_data(int sock, iscsi_header_t *);static void DUMP_DATA (void *start, int len){        int i;        unsigned char *tmp = start;        for (i=0; i<len; i++) {                if ((i % 4) == 0) {                        printf ("\n\t0x");                }                printf ("%02x", tmp[i]);        }        printf ("\n");}static __inline__ u64 be_to_cpu64 (u64 u){        byte *a = (byte *) &u;        byte tmp;        int i;        if (sizeof(u64) != 8) {                fprintf(stderr, "u64 IS NOT 8 BYTES!!!!!\n");        }        for (i=0; i<sizeof(u64) / 2; i++) {                tmp = a[i];                a[i] = a[sizeof(u64) - i - 1];                a[sizeof(u64) - i - 1] = tmp;        }                                return u;}static __inline__ iscsi_header_t be_to_cpu_iscsi (iscsi_header_t hdr){        printf ("RX Header:\n");        iscsi_print_header (&hdr);        switch (hdr.op) {                /*case ISCSI_OP_NOP_OUT:                hdr.nop_out.len = ntohl(hdr.nop_out.len);                hdr.nop_out.lun = be_to_cpu64(hdr.nop_out.lun);                hdr.nop_out.itt = ntohl(hdr.nop_out.itt);                hdr.nop_out.ttt = ntohl(hdr.nop_out.ttt);                hdr.nop_out.cmd_rn = ntohl(hdr.nop_out.cmd_rn);                hdr.nop_out.exp_stat_rn = ntohl(hdr.nop_out.exp_stat_rn);                hdr.nop_out.exp_data_rn = ntohl(hdr.nop_out.exp_data_rn);                return hdr;*/            case ISCSI_OP_SCSI_CMD:                hdr.scsi_cmd.len = ntohl(hdr.scsi_cmd.len);                hdr.scsi_cmd.lun = be_to_cpu64(hdr.scsi_cmd.lun);                hdr.scsi_cmd.itt = ntohl(hdr.scsi_cmd.itt);                hdr.scsi_cmd.exp_data_len = ntohl(hdr.scsi_cmd.exp_data_len);                hdr.scsi_cmd.cmd_rn = ntohl(hdr.scsi_cmd.cmd_rn);                hdr.scsi_cmd.exp_stat_rn = ntohl(hdr.scsi_cmd.exp_stat_rn);                return hdr;            case ISCSI_OP_LOGIN_CMD:                hdr.login_cmd.len = ntohl (hdr.login_cmd.len);                hdr.login_cmd.cid = ntohs (hdr.login_cmd.cid);                hdr.login_cmd.isid = ntohs (hdr.login_cmd.isid);                hdr.login_cmd.tsid = ntohs (hdr.login_cmd.tsid);                hdr.login_cmd.itt = ntohl (hdr.login_cmd.itt);                hdr.login_cmd.init_cmd_rn = ntohl (hdr.login_cmd.init_cmd_rn);                return hdr;            case ISCSI_OP_WRITE_DATA:                hdr.scsi_write.len = ntohl (hdr.scsi_write.len);                hdr.scsi_write.lun = be_to_cpu64 (hdr.scsi_write.lun);                hdr.scsi_write.itt = ntohl (hdr.scsi_write.itt);                hdr.scsi_write.ttt = ntohl (hdr.scsi_write.ttt);                hdr.scsi_write.exp_stat_rn = ntohl (hdr.scsi_write.exp_stat_rn);                hdr.scsi_write.buf_offset = ntohl (hdr.scsi_write.buf_offset);                return hdr;            case ISCSI_OP_TASK_CMD:            case ISCSI_OP_TEXT_CMD:            case ISCSI_OP_LOGOUT_CMD:            case ISCSI_OP_SACK_REQ:            default:                    printf ("iscsi - ntoh - Unimplemented Byte Conversion\n");        }        return hdr;}static __inline__ iscsi_header_t cpu_to_be_iscsi (iscsi_header_t hdr){        switch (hdr.op) {            case ISCSI_OP_SCSI_RSP:                hdr.scsi_rsp.len = htonl(hdr.scsi_rsp.len);                hdr.scsi_rsp.itt = htonl(hdr.scsi_rsp.itt);                hdr.scsi_rsp.resid_cnt = htonl(hdr.scsi_rsp.resid_cnt);                hdr.scsi_rsp.stat_rn = htonl(hdr.scsi_rsp.stat_rn);                hdr.scsi_rsp.exp_cmd_rn = htonl(hdr.scsi_rsp.exp_cmd_rn);                hdr.scsi_rsp.max_cmd_rn = htonl(hdr.scsi_rsp.max_cmd_rn);                hdr.scsi_rsp.sense_len = htons(hdr.scsi_rsp.sense_len);                hdr.scsi_rsp.bidi_resid_cnt = htonl(hdr.scsi_rsp.bidi_resid_cnt);                break;            case ISCSI_OP_LOGIN_RSP:                hdr.login_rsp.len = htonl (hdr.login_rsp.len);                hdr.login_rsp.isid = htons (hdr.login_rsp.isid);                hdr.login_rsp.tsid = htons (hdr.login_rsp.tsid);                hdr.login_rsp.itt = htonl (hdr.login_rsp.itt);                hdr.login_rsp.init_stat_rn = htonl (hdr.login_rsp.init_stat_rn);                hdr.login_rsp.exp_cmd_rn = htonl (hdr.login_rsp.exp_cmd_rn);                hdr.login_rsp.max_cmd_rn = htonl (hdr.login_rsp.max_cmd_rn);                break;            case ISCSI_OP_READ_DATA:                hdr.scsi_read.len = htonl (hdr.scsi_read.len);                hdr.scsi_read.itt = htonl (hdr.scsi_read.itt);                hdr.scsi_read.ttt = htonl (hdr.scsi_read.ttt);                hdr.scsi_read.data_rn_stat_rn = htonl (hdr.scsi_read.data_rn_stat_rn);                hdr.scsi_read.exp_cmd_rn = htonl (hdr.scsi_read.exp_cmd_rn);                hdr.scsi_read.max_cmd_rn = htonl (hdr.scsi_read.max_cmd_rn);                hdr.scsi_read.buf_offset = htonl (hdr.scsi_read.buf_offset);                hdr.scsi_read.resid_cnt = htonl (hdr.scsi_read.resid_cnt);                break;            case ISCSI_OP_R2T:                hdr.r2t.len = htonl (hdr.r2t.len);                hdr.r2t.itt = htonl (hdr.r2t.itt);                hdr.r2t.ttt = htonl (hdr.r2t.ttt);                hdr.r2t.exp_cmd_rn = htonl (hdr.r2t.exp_cmd_rn);                hdr.r2t.max_cmd_rn = htonl (hdr.r2t.max_cmd_rn);                hdr.r2t.desired_data_len = htonl (hdr.r2t.desired_data_len);                hdr.r2t.buf_offset = htonl (hdr.r2t.buf_offset);                break;            case ISCSI_OP_NOP_IN:            case ISCSI_OP_TASK_RSP:            case ISCSI_OP_TEXT_RSP:            case ISCSI_OP_LOGOUT_RSP:            case ISCSI_OP_ASYNC_EVENT:            case ISCSI_OP_REJECT:            default:                printf ("iscsi - hton - Unimplemented Byte Conversion\n");        }        printf ("TX Header:\n");        iscsi_print_header (&hdr);        return hdr;}void iscsi_print_header (void *hdr) {        register int i;        byte *buf=hdr;        for (i=0; i<ISCSI_HDR_SIZE; i++) {                if (i % 4 == 0) {                        printf ("\n\t0x");                }                printf ("%02x", buf[i]);        }        printf ("\n");}struct cmd_table{        u32 block_no;        u32 num_blocks;        u32 data_dir;        u32 task_id;        u32 received;        byte opcode;        struct cmd_table * next;};#define DO_FILE_IO   1#define WRITE_TYPE   2#define READ_TYPE    1#define NONE_TYPE    0struct cmd_table * cmnds = NULL;u32 cur_statrn = 1;u32 exp_cmdrn = 0;u32 global_fd;int main(int argc, char * argv[]){        int sock;        int bytes_read, bytes_to_read;        iscsi_header_t hdr;         #if DO_FILE_IO        if (argc == 2){                global_fd = open(argv[1], O_RDWR);        }        else{                printf("need to specify a file to use as disk\n");                return 0;        }#endif        sock = init_server();        while (1) {                bytes_to_read = ISCSI_HDR_SIZE;                printf ("Reading new iscsi hdr......\n");                while (bytes_to_read){                        if ((bytes_read = read (sock,                                                 ((byte *) &hdr) + (ISCSI_HDR_SIZE - bytes_to_read),                                                 bytes_to_read)) == -1) {                                perror ("read() failed");                                exit(1);                        }                        if (bytes_read == 0) {                                printf ("Client disconnected\n");                                exit(0);                        }                        bytes_to_read -= bytes_read;                        if (bytes_to_read) {                                printf ("warning - short read\n");                        }                }                /* convert byte ordering */                hdr = be_to_cpu_iscsi (hdr);                switch (hdr.op){                    case ISCSI_OP_LOGIN_CMD:                        printf ("Processing iscsi login command\n");                        rx_login(sock, &hdr);                        break;                    case ISCSI_OP_SCSI_CMD:                        printf ("Processing iscsi scsi command\n");                        rx_scsi_cmd(sock, &hdr);                        break;                    case ISCSI_OP_WRITE_DATA:                        printf ("Processing iscsi write data\n");                        rx_scsi_data(sock, &hdr);                        break;                    default:                        printf ("BOGUS MESSAGE:\n");                        iscsi_print_header (&hdr);                        exit(1);                }        }}int rx_login(int sock, iscsi_header_t *hdr){        int bytes_to_write = ISCSI_HDR_SIZE, bytes_written;        iscsi_header_t rsp;        memset (&rsp, 0, ISCSI_HDR_SIZE);                rsp.op = ISCSI_OP_LOGIN_RSP;        rsp.login_rsp.F_reserved1 |= ISCSI_F_BIT; /* turn on F-bit */        rsp.login_rsp.len = 0;        rsp.login_rsp.version_active = 1; /* conform to UNH's kernel target */        rsp.login_rsp.isid = hdr->login_cmd.isid;        rsp.login_rsp.tsid = 0x1;        rsp.login_rsp.init_stat_rn = cur_statrn;        exp_cmdrn = rsp.login_rsp.exp_cmd_rn = rsp.login_rsp.max_cmd_rn                   = hdr->login_cmd.init_cmd_rn + 1;                 rsp.login_rsp.status = ISCSI_LOGIN_ACCEPT;                rsp = cpu_to_be_iscsi (rsp);                        printf ("writing iscsi login response\n");        while (bytes_to_write) {                if ((bytes_written = write (sock,                                             ((byte *) &rsp) + (ISCSI_HDR_SIZE - bytes_to_write),                                            bytes_to_write)) == -1) {                        perror ("write failed\n");                        exit(1);                }                if (bytes_written == 0) {                        perror ("Client disconnected\n");                        exit(1);                }                bytes_to_write -= bytes_written;                if (bytes_to_write) {                        printf ("warning - short write\n");                }        }        return 0;}int rx_scsi_data(int sock, iscsi_header_t *hdr){      iscsi_header_t rsp;      char *buffer;      int len, bytes_to_read, bytes_read,           bytes_to_write = ISCSI_HDR_SIZE, bytes_written;      struct cmd_table * cur_cmnd;      struct cmd_table * trail_cmnd;      len = bytes_to_read = hdr->scsi_write.len;      buffer = malloc(bytes_to_read);      cur_cmnd = cmnds;      while (cur_cmnd && cur_cmnd->task_id != hdr->scsi_write.ttt){              cur_cmnd = cur_cmnd->next;      }      if (cur_cmnd == NULL){              printf("couldnt find matching cmnd\n");              free(buffer);              exit(1);      }      while (bytes_to_read){              if ((bytes_read = read (sock,                                       buffer + (len - bytes_to_read),                                       bytes_to_read)) == -1) {                      perror ("read() failed\n");                      exit(1);              }              if (bytes_read == 0) {                      printf ("Client disconnected\n");                      exit(0);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -