예제 #1
0
static void writereg(uint8_t reg, uint8_t val) {
    ss(true);
    sendrecv(reg);
    sendrecv(val);
    ss(false);
    util_delay(100);
}
예제 #2
0
static uint8_t readreg(uint8_t reg) {
    ss(true);
    sendrecv(reg | (1 << 7));
    uint8_t val = sendrecv(0);
    ss(false);
    util_delay(100);
    return val;
}
예제 #3
0
/* ack block, expect next */
int
tftp_getnextblock(struct tftp_handle *h)
{
	struct {
		u_char header[HEADER_SIZE];
		struct tftphdr t;
	} wbuf;
	char           *wtail;
	int             res;
	struct tftphdr *t;

	bzero(&wbuf, sizeof(wbuf));

	wbuf.t.th_opcode = htons((u_short) ACK);
	wbuf.t.th_block = htons((u_short) h->currblock);
	wtail = (char *) &wbuf.t.th_data;

	t = &h->lastdata.t;

	h->iodesc->xid = h->currblock + 1;	/* expected block */

	res = sendrecv(h->iodesc, sendudp, &wbuf.t, wtail - (char *) &wbuf.t,
	    recvtftp, t, sizeof(*t) + RSPACE);

	if (res == -1)		/* 0 is OK! */
		return errno;

	h->currblock++;
	h->validsize = res;
	if (res < SEGSIZE)
		h->islastblock = 1;	/* EOF */
	return 0;
}
예제 #4
0
파일: fs.c 프로젝트: qinpan1003/linux_drv
/*
函数功能:MM的exit配套函数。用于销毁子进程的filp
输入参数:子进程pid	cpid
输出参数:无
*/
void fs_do_exit(int cpid)
{
	TCB*	p_tcb	= cpid + task_table;
	int	fd;
	for(fd = 0;fd < MAX_TASK_FILE;fd++)
	{
		if(p_tcb->filp[fd] == 0)
			continue;
		assert(p_tcb->filp[fd]->fd_inode->i_cnt > 0);
		
		if(--p_tcb->filp[fd]->fd_inode->i_cnt == 0)	// inode共享者计数减一。如果没有其他进程使用该文件,则释放inode
		{
			if(p_tcb->filp[fd]->fd_inode->i_mode == I_MODE_CHAR)	// 字符设备文件
				{
					MSG 	msg;
					msg.type				= TTY_MSG_UNION;
					msg.msg_union.tty_msg.para		= DEV_CLOSE;
					msg.msg_union.tty_msg.sub_device	= MINOR(p_tcb->filp[fd]->fd_inode->i_start_sect);
					disable_int();
					if(tty_has_msg_tmp == 0)
						assert(sendrecv(BOTH,dd_map[MAJAR(p_tcb->filp[fd]->fd_inode->i_start_sect)],&msg) == 0);
					enable_int();
				}
		}
		p_tcb->filp[fd]->fd_inode = 0;	// 释放file_desc
	//	p_tcb->filp[fd] = 0;		// 释放filp
	}
}
예제 #5
0
파일: fs.c 프로젝트: qinpan1003/linux_drv
/*
函数功能:关闭文件
输入参数:进程指针	p_tcb
	文件fd	fd
输出参数:成功返回0,失败返回-1
*/
int fs_close(int fd,TCB* p_tcb)
{
	if(p_tcb->filp[fd]->fd_inode->i_cnt < 1)
	{
		printk("error! the file has not being open. fd: %d\n",fd);
		return	-1;
	}
	if(p_tcb->filp[fd]->fd_inode->i_cnt == 1)			// inode共享者计数为1,表示没有其他进程使用该文件
	{
		if(p_tcb->filp[fd]->fd_inode->i_mode == I_MODE_CHAR)	// 字符设备文件
		{
			MSG 	msg;
			msg.type				= TTY_MSG_UNION;
			msg.msg_union.tty_msg.para		= DEV_CLOSE;
			msg.msg_union.tty_msg.sub_device	= MINOR(p_tcb->filp[fd]->fd_inode->i_start_sect);
			disable_int();
			if(tty_has_msg_tmp == 0)
				assert(sendrecv(BOTH,dd_map[MAJAR(p_tcb->filp[fd]->fd_inode->i_start_sect)],&msg) == 0);
			enable_int();
		}
		else						// 普通文件。关闭普通文件之前要先“同步文件缓冲”
		{
			sync_buff(p_tcb->filp[fd]->fd_inode,0);		// 0:不释放缓冲	1:同步之后释放缓冲
		}
	}
	p_tcb->filp[fd]->fd_inode->i_cnt--;				// inode共享者计数减一。如果没有其他进程使用该文件,则计数变成0,表示释放inode
	p_tcb->filp[fd]->fd_inode = 0;				// 释放file_desc
	p_tcb->filp[fd] = 0;					// 释放filp
	return	0;
}
예제 #6
0
    // read data from the sensor.
    errlHndl_t SensorBase::readSensorData(uint8_t *& o_data)
    {

        // get sensor reading command only requires one byte of extra data,
        // which will be the sensor number, the command will return between
        // 3 and 5 bytes of data.
        size_t len =  1;

        // need to allocate some me to hold the sensor number this will be
        // deleted by the IPMI transport layer
        o_data = new uint8_t[len];

        o_data[0] = getSensorNumber();

        IPMI::completion_code cc = IPMI::CC_UNKBAD;

        // o_data will hold the response when this returns
        errlHndl_t l_err = sendrecv(IPMI::get_sensor_reading(), cc, len,
                                  (uint8_t *&)o_data);

        // if we didn't get an error back from the BT interface, but see a
        // bad completion code from the BMC, process the CC to see if we
        // need to create a PEL
        if( (l_err == NULL ) && (cc != IPMI::CC_OK) )
        {
            l_err = processCompletionCode( cc );
        }

        return l_err;
    };
예제 #7
0
/* ack block, expect next */
static int 
tftp_getnextblock(struct tftp_handle *h)
{
	struct {
		u_char header[HEADER_SIZE];
		struct tftphdr t;
	} __packed __aligned(4) wbuf;
	char           *wtail;
	int             res;
	struct tftphdr *t;

	/*
	 * Ack previous block
	 */
	wbuf.t.th_opcode = htons((u_short) ACK);
	wtail = (char *) &wbuf.t.th_block;
	wbuf.t.th_block = htons((u_short) h->currblock);
	wtail += 2;

	t = &h->lastdata.t;

	h->iodesc->xid = h->currblock + 1;	/* expected block */

	res = sendrecv(h->iodesc, sendudp, &wbuf.t, wtail - (char *) &wbuf.t,
		       recvtftp, t, sizeof(*t) + RSPACE);

	if (res == -1)		/* 0 is OK! */
		return (errno);

	h->currblock++;
	h->validsize = res;
	if (res < SEGSIZE)
		h->islastblock = 1;	/* EOF */
	return (0);
}
예제 #8
0
/* Fetch required bootp information */
void
bootp(int sock)
{
	struct iodesc *d;
	struct bootp *bp;
	struct {
		u_char header[HEADER_SIZE];
		struct bootp wbootp;
	} wbuf;
	struct {
		u_char header[HEADER_SIZE];
		struct bootp rbootp;
	} rbuf;

#ifdef BOOTP_DEBUG
	if (debug)
		printf("bootp: socket=%d\n", sock);
#endif
	if (!bot)
		bot = getsecs();

	if (!(d = socktodesc(sock))) {
		printf("bootp: bad socket. %d\n", sock);
		return;
	}
#ifdef BOOTP_DEBUG
	if (debug)
		printf("bootp: d=%x\n", (u_int)d);
#endif

	bp = &wbuf.wbootp;
	bzero(bp, sizeof(*bp));

	bp->bp_op = BOOTREQUEST;
	bp->bp_htype = HTYPE_ETHERNET;	/* 10Mb Ethernet (48 bits) */
	bp->bp_hlen = 6;
	bp->bp_xid = htonl(d->xid);
	MACPY(d->myea, bp->bp_chaddr);
	bzero(bp->bp_file, sizeof(bp->bp_file));
	bcopy(vm_rfc1048, bp->bp_vend, sizeof(vm_rfc1048));

	d->myip = myip;
	d->myport = htons(IPPORT_BOOTPC);
	d->destip.s_addr = INADDR_BROADCAST;
	d->destport = htons(IPPORT_BOOTPS);

	(void)sendrecv(d,
	    bootpsend, bp, sizeof(*bp),
	    bootprecv, &rbuf.rbootp, sizeof(rbuf.rbootp));

	/* Bump xid so next request will be unique. */
	++d->xid;
}
예제 #9
0
int main(int argc, char * argv[]) {
  int x;

  MPI_Init(&argc, &argv);
  MPI_Comm_size(comm, &nprocs);
  MPI_Comm_rank(comm, &rank);
  left = (rank-1) % nprocs;
  right = (rank+1) % nprocs;
  x = sendrecv();
  MPI_Finalize();
  return 0;
}
예제 #10
0
    //
    //  Synchronously send a set sensor reading command to the BMC,
    //  the response is returned with the io_data pointer
    //
    errlHndl_t SensorBase::sendSetSensorReading(
                            setSensorReadingRequest *& io_data,
                            IPMI::completion_code& o_completion_code )
    {

        size_t l_len = sizeof( setSensorReadingRequest );

        o_completion_code = IPMI::CC_UNKBAD;

        // i_data will hold the response when this returns
        errlHndl_t l_err = sendrecv(IPMI::set_sensor_reading(),
                            o_completion_code, l_len, (uint8_t *&)io_data);

        return l_err;
    }
예제 #11
0
/* send request, expect first block (or error) */
int
tftp_makereq(struct tftp_handle *h)
{
	struct {
		u_char header[HEADER_SIZE];
		struct tftphdr  t;
		u_char space[FNAME_SIZE + 6];
	} wbuf;
	char           *wtail;
	int             l;
	ssize_t         res;
	struct tftphdr *t;

	bzero(&wbuf, sizeof(wbuf));

	wbuf.t.th_opcode = htons((u_short) RRQ);
	wtail = wbuf.t.th_stuff;
	l = strlen(h->path);
	bcopy(h->path, wtail, l + 1);
	wtail += l + 1;
	bcopy("octet", wtail, 6);
	wtail += 6;

	t = &h->lastdata.t;

	/* h->iodesc->myport = htons(--tftpport); */
	h->iodesc->myport = htons(tftpport + (getsecs() & 0x3ff));
	h->iodesc->destport = htons(IPPORT_TFTP);
	h->iodesc->xid = 1;	/* expected block */

	res = sendrecv(h->iodesc, sendudp, &wbuf.t, wtail - (char *) &wbuf.t,
	    recvtftp, t, sizeof(*t) + RSPACE);

	if (res == -1)
		return errno;

	h->currblock = 1;
	h->validsize = res;
	h->islastblock = 0;
	if (res < SEGSIZE)
		h->islastblock = 1;	/* very short file */
	return 0;
}
예제 #12
0
파일: fs.c 프로젝트: qinpan1003/linux_drv
/*
函数功能:读文件
输入参数:进程指针	p_tcb
	文件fd	fd
	读缓冲	buf
	读大小	count	字节
输出参数:对于普通文件,输出实际读取字节数。
	对于字符设备:0 请求成功,-1 请求失败(有其他进程正在请求输入)
*/
int fs_read(int fd,void * buf,int offset,int count,TCB* p_tcb)
{
	File_Desc*	p_fd;
	Inode*		p_inode;
	buf	= va2pa(p_tcb->pdb,buf);
	p_fd	= p_tcb->filp[fd];
	p_inode	= p_fd->fd_inode;
	//----------------------------------------------------------
	// 字符设备文件
	if(p_inode->i_mode == I_MODE_CHAR)
	{
		MSG 	msg;
		msg.type				= TTY_MSG_UNION;
		msg.msg_union.tty_msg.para		= DEV_READ;
		msg.msg_union.tty_msg.sub_device	= MINOR(p_inode->i_start_sect);
		msg.msg_union.tty_msg.req_caller	= TASK_FS_PID;
		msg.msg_union.tty_msg.req_PID		= p_tcb - task_table;
		msg.msg_union.tty_msg.req_buf		= buf;
		msg.msg_union.tty_msg.req_count	= count;
		disable_int();
		if(tty_has_msg_tmp == 0)
		{
			if(sendrecv(SEND,dd_map[MAJAR(p_inode->i_start_sect)],&msg) == 0)
			{
				no_answer	= 1;	// 通知主循环将用户进程挂起
				enable_int();
				return	0;	// 0 消息发送成功
			}			// 请求是否成功在这里还不能判断,需要在主循环中收到tty发来的消息才知道
		}
		enable_int();
		return	-1;			// -1 发送消息失败(可能构成死锁)
	}
	//----------------------------------------------------------
	// 以下是普通文件
	int	cnt = file_buff_read(	buf,
					p_fd->fd_inode,
					offset + p_fd->fd_pos,
					count);
	assert(cnt != -1);
	p_fd->fd_pos	+= offset + cnt;
	return	cnt;
}
예제 #13
0
    /*
     * @brief       Asynchronus message send
     *
     * @param[in]   i_cmd,  the command we're sending
     * @param[in]   i_len,  the length of the data
     * @param[in]   i_data, the data we're sending
     * @param[in]   i_type, the type of message we're sending
     *
     */
    errlHndl_t send(const IPMI::command_t& i_cmd,
                    size_t i_len, uint8_t* i_data,
                    IPMI::message_type i_type)
    {
        IPMI::completion_code l_cc = IPMI::CC_UNKBAD;

        // We are calling a synchronous send in an asynchronous function
        // This is needed to enable asynchronous message sending before
        // runtime. A message should be synchronous during runtime, but
        // by ignoring the cc returned and clearing the data, we're making
        // a synchronous function "asynchronous".
        errlHndl_t l_err = sendrecv(i_cmd,l_cc,i_len,i_data);

        if(i_data != NULL)
        {
            delete i_data;
        }

        return l_err;
    }
예제 #14
0
파일: fs.c 프로젝트: qinpan1003/linux_drv
/*
函数功能:写文件
输入参数:进程指针	p_tcb
	文件fd	fd
	写缓冲	buf
	写大小	count	字节
输出参数:成功返回实际写入字节数,失败返回-1
*/
int fs_write(int fd,void * buf,int offset,int count,TCB* p_tcb)
{
	File_Desc*	p_fd;
	Inode*		p_inode;
	buf	= va2pa(p_tcb->pdb,buf);
	p_fd	= p_tcb->filp[fd];
	p_inode	= p_fd->fd_inode;
	//----------------------------------------------------------
	// 字符设备文件
	if(p_inode->i_mode == I_MODE_CHAR)
	{
		MSG 	msg;
		msg.type				= TTY_MSG_UNION;
		msg.msg_union.tty_msg.para		= DEV_WRITE;
		msg.msg_union.tty_msg.sub_device	= MINOR(p_inode->i_start_sect);
		msg.msg_union.tty_msg.req_buf		= buf;
		msg.msg_union.tty_msg.req_count	= count;
		disable_int();
		if(tty_has_msg_tmp == 0)
		{
			if(sendrecv(BOTH,dd_map[MAJAR(p_inode->i_start_sect)],&msg) == -1)
				msg.msg_union.tty_msg.req_count = -1;
			enable_int();
			return	msg.msg_union.tty_msg.req_count;
		}
		enable_int();
		return	-1;
	}
	//----------------------------------------------------------
	// 以下是普通文件
	int	cnt = file_buff_write(	buf,
					p_fd->fd_inode,
					offset + p_fd->fd_pos,
					count);
	assert(cnt != -1);
	p_fd->fd_pos	+= offset + cnt;
	return	cnt;
}
예제 #15
0
/*
 * Make a rpc call; return length of answer
 * Note: Caller must leave room for headers.
 */
ssize_t
rpc_call(struct iodesc *d, n_long prog, n_long vers, n_long proc,
	void *sdata, size_t slen, void **rdata, void **pkt)
{
	ssize_t cc, rsize;
	struct auth_info *auth;
	struct rpc_call *call;
	struct rpc_reply *reply;
	char *send_head, *send_tail;
	void *ptr;
	n_long x;
	int port;	/* host order */

#ifdef RPC_DEBUG
	if (debug)
		printf("rpc_call: prog=0x%x vers=%d proc=%d\n",
		    prog, vers, proc);
#endif

	port = rpc_getport(d, prog, vers);
	if (port == -1)
		return (-1);

	d->destport = htons(port);

	/*
	 * Prepend authorization stuff and headers.
	 * Note, must prepend things in reverse order.
	 */
	send_head = sdata;
	send_tail = (char *)sdata + slen;

	/* Auth verifier is always auth_null */
	send_head -= sizeof(*auth);
	auth = (struct auth_info *)send_head;
	auth->authtype = htonl(RPCAUTH_NULL);
	auth->authlen = 0;

	/* Auth credentials: always auth unix (as root) */
	send_head -= sizeof(struct auth_unix);
	bzero(send_head, sizeof(struct auth_unix));
	send_head -= sizeof(*auth);
	auth = (struct auth_info *)send_head;
	auth->authtype = htonl(RPCAUTH_UNIX);
	auth->authlen = htonl(sizeof(struct auth_unix));

	/* RPC call structure. */
	send_head -= sizeof(*call);
	call = (struct rpc_call *)send_head;
	rpc_xid++;
	call->rp_xid       = htonl(rpc_xid);
	call->rp_direction = htonl(RPC_CALL);
	call->rp_rpcvers   = htonl(RPC_VER2);
	call->rp_prog = htonl(prog);
	call->rp_vers = htonl(vers);
	call->rp_proc = htonl(proc);

	ptr = NULL;
	cc = sendrecv(d,
	    sendudp, send_head, send_tail - send_head,
	    recvrpc, &ptr, (void **)&reply);

#ifdef RPC_DEBUG
	if (debug)
		printf("callrpc: cc=%zd\n", cc);
#endif
	if (cc == -1)
		return (-1);

	if (cc <= sizeof(*reply)) {
		errno = EBADRPC;
		free(ptr);
		return (-1);
	}

	/*
	 * Check the RPC reply status.
	 * The xid, dir, astatus were already checked.
	 */
	auth = &reply->rp_u.rpu_rok.rok_auth;
	x = ntohl(auth->authlen);
	if (x != 0) {
#ifdef RPC_DEBUG
		if (debug)
			printf("callrpc: reply auth != NULL\n");
#endif
		errno = EBADRPC;
		free(ptr);
		return (-1);
	}
	x = ntohl(reply->rp_u.rpu_rok.rok_status);
	if (x != 0) {
		printf("callrpc: error = %ld\n", (long)x);
		errno = EBADRPC;
		free(ptr);
		return (-1);
	}

	rsize = cc - sizeof(*reply);
	*rdata = (void *)((uintptr_t)reply + sizeof(*reply));
	*pkt = ptr;
	return (rsize);
}
예제 #16
0
파일: bootp.c 프로젝트: AgamAgarwal/minix
/* Fetch required bootp information */
void
bootp(int sock)
{
	struct iodesc *d;
	struct bootp *bp;
	struct {
		u_char header[UDP_TOTAL_HEADER_SIZE];
		struct bootp wbootp;
	} wbuf;
	struct {
		u_char header[UDP_TOTAL_HEADER_SIZE];
		struct bootp rbootp;
	} rbuf;
	unsigned int index;

#ifdef BOOTP_DEBUG
 	if (debug)
		printf("bootp: socket=%d\n", sock);
#endif
	if (!bot)
		bot = getsecs();

	if (!(d = socktodesc(sock))) {
		printf("bootp: bad socket. %d\n", sock);
		return;
	}
#ifdef BOOTP_DEBUG
 	if (debug)
		printf("bootp: d=%lx\n", (long)d);
#endif

	bp = &wbuf.wbootp;
	(void)memset(bp, 0, sizeof(*bp));

	bp->bp_op = BOOTREQUEST;
	bp->bp_htype = 1;		/* 10Mb Ethernet (48 bits) */
	bp->bp_hlen = 6;
	bp->bp_xid = htonl(d->xid);
	MACPY(d->myea, bp->bp_chaddr);
	(void)strncpy((char *)bp->bp_file, bootfile, sizeof(bp->bp_file));
	(void)memcpy(bp->bp_vend, vm_rfc1048, sizeof(vm_rfc1048));
	index = 4;
#ifdef SUPPORT_DHCP
	bp->bp_vend[index++] = TAG_DHCP_MSGTYPE;
	bp->bp_vend[index++] = 1;
	bp->bp_vend[index++] = DHCPDISCOVER;
#endif
	bootp_addvend(&bp->bp_vend[index]);

	d->myip.s_addr = INADDR_ANY;
	d->myport = htons(IPPORT_BOOTPC);
	d->destip.s_addr = INADDR_BROADCAST;
	d->destport = htons(IPPORT_BOOTPS);

#ifdef SUPPORT_DHCP
	expected_dhcpmsgtype = DHCPOFFER;
	dhcp_ok = 0;
#endif

	if (sendrecv(d,
		    bootpsend, bp, sizeof(*bp),
		    bootprecv, &rbuf.rbootp, sizeof(rbuf.rbootp))
	   == -1) {
		printf("bootp: no reply\n");
		return;
	}

#ifdef SUPPORT_DHCP
	if (dhcp_ok) {
		u_int32_t leasetime;
		index = 6;
		bp->bp_vend[index++] = DHCPREQUEST;
		bp->bp_vend[index++] = TAG_REQ_ADDR;
		bp->bp_vend[index++] = 4;
		(void)memcpy(&bp->bp_vend[9], &rbuf.rbootp.bp_yiaddr, 4);
		index += 4;
		bp->bp_vend[index++] = TAG_SERVERID;
		bp->bp_vend[index++] = 4;
		(void)memcpy(&bp->bp_vend[index], &dhcp_serverip.s_addr, 4);
		index += 4;
		bp->bp_vend[index++] = TAG_LEASETIME;
		bp->bp_vend[index++] = 4;
		leasetime = htonl(300);
		(void)memcpy(&bp->bp_vend[index], &leasetime, 4);
		index += 4;
		bootp_addvend(&bp->bp_vend[index]);

		expected_dhcpmsgtype = DHCPACK;

		if (sendrecv(d,
			    bootpsend, bp, sizeof(*bp),
			    bootprecv, &rbuf.rbootp, sizeof(rbuf.rbootp))
		   == -1) {
			printf("DHCPREQUEST failed\n");
			return;
		}
	}
#endif

	myip = d->myip = rbuf.rbootp.bp_yiaddr;
	servip = rbuf.rbootp.bp_siaddr;
	if (rootip.s_addr == INADDR_ANY)
		rootip = servip;
	(void)memcpy(bootfile, rbuf.rbootp.bp_file, sizeof(bootfile));
	bootfile[sizeof(bootfile) - 1] = '\0';

	if (IN_CLASSA(myip.s_addr))
		nmask = IN_CLASSA_NET;
	else if (IN_CLASSB(myip.s_addr))
		nmask = IN_CLASSB_NET;
	else
		nmask = IN_CLASSC_NET;
#ifdef BOOTP_DEBUG
	if (debug)
		printf("'native netmask' is %s\n", intoa(nmask));
#endif

	/* Get subnet (or natural net) mask */
	netmask = nmask;
	if (smask)
		netmask = smask;
#ifdef BOOTP_DEBUG
	if (debug)
		printf("mask: %s\n", intoa(netmask));
#endif

	/* We need a gateway if root is on a different net */
	if (!SAMENET(myip, rootip, netmask)) {
#ifdef BOOTP_DEBUG
		if (debug)
			printf("need gateway for root ip\n");
#endif
	}

	/* Toss gateway if on a different net */
	if (!SAMENET(myip, gateip, netmask)) {
#ifdef BOOTP_DEBUG
		if (debug)
			printf("gateway ip (%s) bad\n", inet_ntoa(gateip));
#endif
		gateip.s_addr = 0;
	}

#ifdef BOOTP_DEBUG
	if (debug) {
		printf("client addr: %s\n", inet_ntoa(myip));
		if (smask)
			printf("subnet mask: %s\n", intoa(smask));
		if (gateip.s_addr != 0)
			printf("net gateway: %s\n", inet_ntoa(gateip));
		printf("server addr: %s\n", inet_ntoa(rootip));
		if (rootpath[0] != '\0')
			printf("server path: %s\n", rootpath);
		if (bootfile[0] != '\0')
			printf("file name: %s\n", bootfile);
	}
#endif

	/* Bump xid so next request will be unique. */
	++d->xid;
}
예제 #17
0
파일: arp.c 프로젝트: illumos/illumos-gate
/* Broadcast an ARP packet, asking who has addr on interface d */
uchar_t *
arpwhohas(struct iodesc *d, struct in_addr addr)
{
	int i;
	struct ether_arp *ah;
	struct arp_list *al;
	void *pkt;
	struct {
		struct ether_header eh;
		struct {
			struct ether_arp arp;
			uchar_t pad[18];		/* 60 - sizeof (...) */
		} data;
	} wbuf;

	/* Try for cached answer first */
	for (i = 0, al = arp_list; i < arp_num; ++i, ++al)
		if (addr.s_addr == al->addr.s_addr)
			return (al->ea);

	/* Don't overflow cache */
	if (arp_num > ARP_NUM - 1) {
		arp_num = 1;	/* recycle */
		printf("arpwhohas: overflowed arp_list!\n");
	}

#ifdef ARP_DEBUG
	if (debug)
		printf("arpwhohas: send request for %s\n", inet_ntoa(addr));
#endif

	bzero((char *)&wbuf.data, sizeof (wbuf.data));
	ah = &wbuf.data.arp;
	ah->arp_hrd = htons(ARPHRD_ETHER);
	ah->arp_pro = htons(ETHERTYPE_IP);
	ah->arp_hln = sizeof (ah->arp_sha); /* hardware address length */
	ah->arp_pln = sizeof (ah->arp_spa); /* protocol address length */
	ah->arp_op = htons(ARPOP_REQUEST);
	MACPY(d->myea, ah->arp_sha);
	bcopy(&d->myip, ah->arp_spa, sizeof (ah->arp_spa));
	/* Leave zeros in arp_tha */
	bcopy(&addr, ah->arp_tpa, sizeof (ah->arp_tpa));

	/* Store ip address in cache (incomplete entry). */
	al->addr = addr;

	pkt = NULL;
	ah = NULL;
	i = sendrecv(d,
	    arpsend, &wbuf.data, sizeof (wbuf.data),
	    arprecv, &pkt, (void **)&ah, NULL);
	if (i == -1)
		panic("arp: no response for %s", inet_ntoa(addr));

	/* Store ethernet address in cache */
#ifdef ARP_DEBUG
	if (debug) {
		struct ether_header *eh;

		eh = (struct ether_header *)((uintptr_t)pkt + ETHER_ALIGN);
		printf("arp: response from %s\n",
		    ether_sprintf(eh->ether_shost));
		printf("arp: cacheing %s --> %s\n",
		    inet_ntoa(addr), ether_sprintf(ah->arp_sha));
	}
#endif
	MACPY(ah->arp_sha, al->ea);
	++arp_num;
	free(pkt);
	return (al->ea);
}
예제 #18
0
파일: rpc.c 프로젝트: appleorange1/bitrig
/*
 * Make a rpc call; return length of answer
 * Note: Caller must leave room for headers.
 */
ssize_t
rpc_call(struct iodesc *d, n_long prog, n_long vers, n_long proc, void *sdata,
    size_t slen, void *rdata, size_t rlen)
{
	ssize_t cc;
	struct auth_info *auth;
	struct rpc_call *call;
	struct rpc_reply *reply;
	char *send_head, *send_tail;
	char *recv_head, *recv_tail;
	n_long x;
	int port;	/* host order */

#ifdef RPC_DEBUG
	if (debug)
		printf("rpc_call: prog=0x%x vers=%d proc=%d\n",
		    prog, vers, proc);
#endif

	port = rpc_getport(d, prog, vers);
	if (port == -1)
		return (-1);

	d->destport = htons(port);

	/*
	 * Prepend authorization stuff and headers.
	 * Note, must prepend things in reverse order.
	 */
	send_head = sdata;
	send_tail = (char *)sdata + slen;

	/* Auth verifier is always auth_null */
	send_head -= sizeof(*auth);
	auth = (struct auth_info *)send_head;
	auth->authtype = htonl(RPCAUTH_NULL);
	auth->authlen = 0;

#if 1
	/* Auth credentials: always auth unix (as root) */
	send_head -= sizeof(struct auth_unix);
	bzero(send_head, sizeof(struct auth_unix));
	send_head -= sizeof(*auth);
	auth = (struct auth_info *)send_head;
	auth->authtype = htonl(RPCAUTH_UNIX);
	auth->authlen = htonl(sizeof(struct auth_unix));
#else
	/* Auth credentials: always auth_null (XXX OK?) */
	send_head -= sizeof(*auth);
	auth = send_head;
	auth->authtype = htonl(RPCAUTH_NULL);
	auth->authlen = 0;
#endif

	/* RPC call structure. */
	send_head -= sizeof(*call);
	call = (struct rpc_call *)send_head;
	rpc_xid++;
	call->rp_xid       = htonl(rpc_xid);
	call->rp_direction = htonl(RPC_CALL);
	call->rp_rpcvers   = htonl(RPC_VER2);
	call->rp_prog = htonl(prog);
	call->rp_vers = htonl(vers);
	call->rp_proc = htonl(proc);

	/* Make room for the rpc_reply header. */
	recv_head = rdata;
	recv_tail = (char *)rdata + rlen;
	recv_head -= sizeof(*reply);

	cc = sendrecv(d,
	    sendudp, send_head, send_tail - send_head,
	    recvrpc, recv_head, recv_tail - recv_head);

#ifdef RPC_DEBUG
	if (debug)
		printf("callrpc: cc=%d rlen=%d\n", cc, rlen);
#endif
	if (cc < -1)
		return (-1);

	if ((size_t)cc <= sizeof(*reply)) {
		errno = EBADRPC;
		return (-1);
	}

	recv_tail = recv_head + cc;

	/*
	 * Check the RPC reply status.
	 * The xid, dir, astatus were already checked.
	 */
	reply = (struct rpc_reply *)recv_head;
	auth = &reply->rp_u.rpu_rok.rok_auth;
	x = ntohl(auth->authlen);
	if (x != 0) {
#ifdef RPC_DEBUG
		if (debug)
			printf("callrpc: reply auth != NULL\n");
#endif
		errno = EBADRPC;
		return(-1);
	}
	x = ntohl(reply->rp_u.rpu_rok.rok_status);
	if (x != 0) {
		printf("callrpc: error = %d\n", x);
		errno = EBADRPC;
		return(-1);
	}
	recv_head += sizeof(*reply);

	return (ssize_t)(recv_tail - recv_head);
}
예제 #19
0
/* Fetch required bootp infomation */
void
bootp(int sock)
{
	void *pkt;
	struct iodesc *d;
	struct bootp *bp;
	struct {
		uchar_t header[HEADER_SIZE];
		struct bootp wbootp;
	} wbuf;
	struct bootp *rbootp;

#ifdef BOOTP_DEBUG
	if (debug)
		printf("bootp: socket=%d\n", sock);
#endif
	if (!bot)
		bot = getsecs();

	if (!(d = socktodesc(sock))) {
		printf("bootp: bad socket. %d\n", sock);
		return;
	}
#ifdef BOOTP_DEBUG
	if (debug)
		printf("bootp: d=%lx\n", (long)d);
#endif

	bp = &wbuf.wbootp;
	bzero(bp, sizeof (*bp));

	bp->bp_op = BOOTREQUEST;
	bp->bp_htype = 1;		/* 10Mb Ethernet (48 bits) */
	bp->bp_hlen = 6;
	bp->bp_xid = htonl(d->xid);
	MACPY(d->myea, bp->bp_chaddr);
	strncpy(bp->bp_file, bootfile, sizeof (bp->bp_file));
	bcopy(vm_rfc1048, bp->bp_vend, sizeof (vm_rfc1048));
#ifdef SUPPORT_DHCP
	bp->bp_vend[4] = TAG_DHCP_MSGTYPE;
	bp->bp_vend[5] = 1;
	bp->bp_vend[6] = DHCPDISCOVER;
	bootp_fill_request(&bp->bp_vend[7]);
#else
	bp->bp_vend[4] = TAG_END;
#endif

	d->myip.s_addr = INADDR_ANY;
	d->myport = htons(IPPORT_BOOTPC);
	d->destip.s_addr = INADDR_BROADCAST;
	d->destport = htons(IPPORT_BOOTPS);

#ifdef SUPPORT_DHCP
	expected_dhcpmsgtype = DHCPOFFER;
	dhcp_ok = 0;
#endif

	if (sendrecv(d, bootpsend, bp, sizeof (*bp),
	    bootprecv, &pkt, (void **)&rbootp, NULL) == -1) {
		printf("bootp: no reply\n");
		return;
	}

#ifdef SUPPORT_DHCP
	if (dhcp_ok) {
		uint32_t leasetime;
		bp->bp_vend[6] = DHCPREQUEST;
		bp->bp_vend[7] = TAG_REQ_ADDR;
		bp->bp_vend[8] = 4;
		bcopy(&rbootp->bp_yiaddr, &bp->bp_vend[9], 4);
		bp->bp_vend[13] = TAG_SERVERID;
		bp->bp_vend[14] = 4;
		bcopy(&dhcp_serverip.s_addr, &bp->bp_vend[15], 4);
		bp->bp_vend[19] = TAG_LEASETIME;
		bp->bp_vend[20] = 4;
		leasetime = htonl(300);
		bcopy(&leasetime, &bp->bp_vend[21], 4);
		bootp_fill_request(&bp->bp_vend[25]);

		expected_dhcpmsgtype = DHCPACK;

		free(pkt);
		if (sendrecv(d, bootpsend, bp, sizeof (*bp),
		    bootprecv, &pkt, (void **)&rbootp, NULL) == -1) {
			printf("DHCPREQUEST failed\n");
			return;
		}
	}
#endif

	myip = d->myip = rbootp->bp_yiaddr;
	servip = rbootp->bp_siaddr;
	if (rootip.s_addr == INADDR_ANY)
		rootip = servip;
	bcopy(rbootp->bp_file, bootfile, sizeof (bootfile));
	bootfile[sizeof (bootfile) - 1] = '\0';

	if (!netmask) {
		if (IN_CLASSA(ntohl(myip.s_addr)))
			netmask = htonl(IN_CLASSA_NET);
		else if (IN_CLASSB(ntohl(myip.s_addr)))
			netmask = htonl(IN_CLASSB_NET);
		else
			netmask = htonl(IN_CLASSC_NET);
#ifdef BOOTP_DEBUG
		if (debug)
			printf("'native netmask' is %s\n", intoa(netmask));
#endif
	}

#ifdef BOOTP_DEBUG
	if (debug)
		printf("mask: %s\n", intoa(netmask));
#endif

	/* We need a gateway if root is on a different net */
	if (!SAMENET(myip, rootip, netmask)) {
#ifdef BOOTP_DEBUG
		if (debug)
			printf("need gateway for root ip\n");
#endif
	}

	/* Toss gateway if on a different net */
	if (!SAMENET(myip, gateip, netmask)) {
#ifdef BOOTP_DEBUG
		if (debug)
			printf("gateway ip (%s) bad\n", inet_ntoa(gateip));
#endif
		gateip.s_addr = 0;
	}

	/* Bump xid so next request will be unique. */
	++d->xid;
	free(pkt);
}
예제 #20
0
파일: rarp.c 프로젝트: zrj-rimwis/blub
/*
 * Ethernet (Reverse) Address Resolution Protocol (see RFC 903, and 826).
 */
int
rarp_getipaddress(int sock)
{
	struct iodesc *d;
	struct ether_arp *ap;
	struct {
		u_char header[ETHER_SIZE];
		struct {
			struct ether_arp arp;
			u_char pad[18];		/* 60 - sizeof(arp) */
		} data;
	} wbuf;
	struct {
		u_char header[ETHER_SIZE];
		struct {
			struct ether_arp arp;
			u_char pad[24];		/* extra space */
		} data;
	} rbuf;

#ifdef RARP_DEBUG
	if (debug)
		printf("rarp: socket=%d\n", sock);
#endif
	if (!(d = socktodesc(sock))) {
		printf("rarp: bad socket. %d\n", sock);
		return (-1);
	}
#ifdef RARP_DEBUG
	if (debug)
		printf("rarp: d=%x\n", (u_int)d);
#endif

	bzero((char*)&wbuf.data, sizeof(wbuf.data));
	ap = &wbuf.data.arp;
	ap->arp_hrd = htons(ARPHRD_ETHER);
	ap->arp_pro = htons(ETHERTYPE_IP);
	ap->arp_hln = sizeof(ap->arp_sha); /* hardware address length */
	ap->arp_pln = sizeof(ap->arp_spa); /* protocol address length */
	ap->arp_op = htons(ARPOP_REVREQUEST);
	bcopy(d->myea, ap->arp_sha, 6);
	bcopy(d->myea, ap->arp_tha, 6);

	if (sendrecv(d,
	    rarpsend, &wbuf.data, sizeof(wbuf.data),
	    rarprecv, &rbuf.data, sizeof(rbuf.data)) < 0)
	{
		printf("No response for RARP request\n");
		return (-1);
	}

	ap = &rbuf.data.arp;
	bcopy(ap->arp_tpa, (char *)&myip, sizeof(myip));
#if 0
	/* XXX - Can NOT assume this is our root server! */
	bcopy(ap->arp_spa, (char *)&rootip, sizeof(rootip));
#endif

	/* Compute our "natural" netmask. */
	if (IN_CLASSA(myip.s_addr))
		netmask = IN_CLASSA_NET;
	else if (IN_CLASSB(myip.s_addr))
		netmask = IN_CLASSB_NET;
	else
		netmask = IN_CLASSC_NET;

	d->myip = myip;
	return (0);
}
예제 #21
0
/* Fetch required bootp infomation */
void
bootp(int sock, int flag)
{
	struct iodesc *d;
	struct bootp *bp;
	struct {
		u_char header[HEADER_SIZE];
		struct bootp wbootp;
	} wbuf;
	struct {
		u_char header[HEADER_SIZE];
		struct bootp rbootp;
	} rbuf;

#ifdef BOOTP_DEBUG
 	if (debug)
		printf("bootp: socket=%d\n", sock);
#endif
	if (!bot)
		bot = getsecs();
	
	if (!(d = socktodesc(sock))) {
		printf("bootp: bad socket. %d\n", sock);
		return;
	}
#ifdef BOOTP_DEBUG
 	if (debug)
		printf("bootp: d=%lx\n", (long)d);
#endif

	bp = &wbuf.wbootp;
	bzero(bp, sizeof(*bp));

	bp->bp_op = BOOTREQUEST;
	bp->bp_htype = 1;		/* 10Mb Ethernet (48 bits) */
	bp->bp_hlen = 6;
	bp->bp_xid = htonl(d->xid);
	MACPY(d->myea, bp->bp_chaddr);
	strncpy(bp->bp_file, bootfile, sizeof(bp->bp_file));
	bcopy(vm_rfc1048, bp->bp_vend, sizeof(vm_rfc1048));
#ifdef SUPPORT_DHCP
	bp->bp_vend[4] = TAG_DHCP_MSGTYPE;
	bp->bp_vend[5] = 1;
	bp->bp_vend[6] = DHCPDISCOVER;

	/*
	 * If we are booting from PXE, we want to send the string
	 * 'PXEClient' to the DHCP server so you have the option of
	 * only responding to PXE aware dhcp requests.
	 */
	if (flag & BOOTP_PXE) {
		bp->bp_vend[7] = TAG_CLASSID;
		bp->bp_vend[8] = 9;
		bcopy("PXEClient", &bp->bp_vend[9], 9);
		bp->bp_vend[18] = TAG_PARAM_REQ;
		bp->bp_vend[19] = 7;
		bp->bp_vend[20] = TAG_ROOTPATH;
		bp->bp_vend[21] = TAG_HOSTNAME;
		bp->bp_vend[22] = TAG_SWAPSERVER;
		bp->bp_vend[23] = TAG_GATEWAY;
		bp->bp_vend[24] = TAG_SUBNET_MASK;
		bp->bp_vend[25] = TAG_INTF_MTU;
		bp->bp_vend[26] = TAG_SERVERID;
		bp->bp_vend[27] = TAG_END;
	} else
		bp->bp_vend[7] = TAG_END;
#else
	bp->bp_vend[4] = TAG_END;
#endif

	d->myip.s_addr = INADDR_ANY;
	d->myport = htons(IPPORT_BOOTPC);
	d->destip.s_addr = INADDR_BROADCAST;
	d->destport = htons(IPPORT_BOOTPS);

#ifdef SUPPORT_DHCP
	expected_dhcpmsgtype = DHCPOFFER;
	dhcp_ok = 0;
#endif

	if(sendrecv(d,
		    bootpsend, bp, sizeof(*bp),
		    bootprecv, &rbuf.rbootp, sizeof(rbuf.rbootp))
	   == -1) {
	    printf("bootp: no reply\n");
	    return;
	}

#ifdef SUPPORT_DHCP
	if(dhcp_ok) {
		u_int32_t leasetime;
		bp->bp_vend[6] = DHCPREQUEST;
		bp->bp_vend[7] = TAG_REQ_ADDR;
		bp->bp_vend[8] = 4;
		bcopy(&rbuf.rbootp.bp_yiaddr, &bp->bp_vend[9], 4);
		bp->bp_vend[13] = TAG_SERVERID;
		bp->bp_vend[14] = 4;
		bcopy(&dhcp_serverip.s_addr, &bp->bp_vend[15], 4);
		bp->bp_vend[19] = TAG_LEASETIME;
		bp->bp_vend[20] = 4;
		leasetime = htonl(300);
		bcopy(&leasetime, &bp->bp_vend[21], 4);
		if (flag & BOOTP_PXE) {
			bp->bp_vend[25] = TAG_CLASSID;
			bp->bp_vend[26] = 9;
			bcopy("PXEClient", &bp->bp_vend[27], 9);
			bp->bp_vend[36] = TAG_END;
		} else
			bp->bp_vend[25] = TAG_END;

		expected_dhcpmsgtype = DHCPACK;

		if(sendrecv(d,
			    bootpsend, bp, sizeof(*bp),
			    bootprecv, &rbuf.rbootp, sizeof(rbuf.rbootp))
		   == -1) {
			printf("DHCPREQUEST failed\n");
			return;
		}
	}
#endif

	myip = d->myip = rbuf.rbootp.bp_yiaddr;
	servip = rbuf.rbootp.bp_siaddr;
	if(rootip.s_addr == INADDR_ANY) rootip = servip;
	bcopy(rbuf.rbootp.bp_file, bootfile, sizeof(bootfile));
	bootfile[sizeof(bootfile) - 1] = '\0';

	if (!netmask) {
		if (IN_CLASSA(ntohl(myip.s_addr)))
			netmask = htonl(IN_CLASSA_NET);
		else if (IN_CLASSB(ntohl(myip.s_addr)))
			netmask = htonl(IN_CLASSB_NET);
		else
			netmask = htonl(IN_CLASSC_NET);
#ifdef BOOTP_DEBUG
		if (debug)
			printf("'native netmask' is %s\n", intoa(netmask));
#endif
	}

#ifdef BOOTP_DEBUG
	if (debug)
		printf("mask: %s\n", intoa(netmask));
#endif

	/* We need a gateway if root is on a different net */
	if (!SAMENET(myip, rootip, netmask)) {
#ifdef BOOTP_DEBUG
		if (debug)
			printf("need gateway for root ip\n");
#endif
	}

	/* Toss gateway if on a different net */
	if (!SAMENET(myip, gateip, netmask)) {
#ifdef BOOTP_DEBUG
		if (debug)
			printf("gateway ip (%s) bad\n", inet_ntoa(gateip));
#endif
		gateip.s_addr = 0;
	}

	/* Bump xid so next request will be unique. */
	++d->xid;
}
예제 #22
0
파일: fs.c 프로젝트: qinpan1003/linux_drv
/*
函数功能:打开文件
输入参数:文件名	pathname
	打开方式	flags
	进程指针	p_tcb
输出参数:成功返回进程filp中的fd下标,失败返回-1
*/
int fs_open(char * pathname,int flags,TCB* p_tcb)
{
	pathname		= va2pa(p_tcb->pdb,pathname);
	DEV_Inode*	p_devinode;
	int		inode_nr;
	File_Desc*	p_fd;
	Inode*		p_inode;
	Dir_Entry*	p_de;
	int		i,j;
	
	// 读目录文件,寻找pathname,获得其inode_nr
	int	file_offset	= 0;
	for(i = 0,inode_nr = 0;i < ROOT_SECTS;i++,file_offset += SECTOR_SIZE)
	{
		file_buff_read(fsbuf,p_inode_de,file_offset,SECTOR_SIZE);
		for(j = 0,p_de = (Dir_Entry*)fsbuf;j < DIR_ENT_PER_SECT;j++,p_de++)
		{
			if(strcmp(p_de->name,pathname) == 0)
			{
				inode_nr = p_de->inode_nr;
				break;
			}
		}
		if(inode_nr != 0)
			break;
	}
	// 目录中寻找结束
	if(inode_nr == 0)				// 没找到dev_inode
	{
		if(flags == O_CREATE)
		{
			// 这里应该判断待创建打开的是否是普通文件
			inode_nr = create_file(pathname);
			if(inode_nr == 0)
			{
				printk("create_file error! %s\n",pathname);
				return	-1;	// 创建文件失败
			}
		}
		else
		{
			printk("no file : %s\n",pathname);
			return	-1;		// 没有找到,也没有创建文件
		}
	}
	//printk("file : %s   inode_nr : %d\n",pathname,inode_nr);
	// 找到了dev_inode编号inode_nr
	// 查看内存里的inode_table中是否存在该inode
	int	i_dev = ROOT_DEV;
	Inode*	p_inode_empty = 0;
	Inode*	p_inode_empty1 = 0;
	for(p_inode = inode_table;p_inode < inode_table + MAX_ALL_INODE;p_inode++)
	{
		if(p_inode->i_cnt == 0)
		{
			if(p_inode_empty == 0)
				p_inode_empty = p_inode;	// 第一个空位
			
			if(p_inode_empty1 == 0 && p_inode->i_dev == 0 && p_inode->i_num == 0)
				p_inode_empty1 = p_inode;	// 第一个从未被使用过的空位
		}
		if(p_inode->i_dev != i_dev)		continue;
		if(p_inode->i_num != inode_nr)	continue;
		break;
	}
	int	new_inode	= 0;
	if(p_inode >= inode_table + MAX_ALL_INODE)		// 不在inode_table里,需要手动添加
	{	// 在inode_table中寻找一个空位
		if(p_inode_empty1 != 0)
		{
			p_inode		= p_inode_empty1;
		}
		else
		{
			if(p_inode_empty == 0)
			{
				printk("inode_table full : %s----",pathname);
				return	-1;	// inode_table无空位
			}
			p_inode		= p_inode_empty;
		}
		
		new_inode		= 1;	// 用于判断该inode是否是新添加的
	}
	// 此时p_inode的i_dev i_num正确,但是i_cnt可能是0。即:现在找到的inode可能是正在被其他进程共享的,也可能是被其他进程废弃的
	// 在file_table中寻找一个空位
	for(p_fd = file_table;p_fd < file_table + MAX_ALL_FILE;p_fd++)
	{
		if(p_fd->fd_inode == 0)
			break;
	}
	//printk(" p_fd : %d   \n",p_fd - file_table);
	if(p_fd >= file_table + MAX_ALL_FILE)
	{
		printk("file_table full : %s----",pathname);
		return	-1;	// file_table无空位
	}
	// 在进程filp数组中寻找一个空位
	for(i = 0;i < MAX_TASK_FILE;i++)
	{
		if(p_tcb->filp[i] == 0)
			break;
	}
	if(i >= MAX_TASK_FILE)
	{
		printk("filp full : %s----",pathname);
		return	-1;	// filp无空位
	}
	// 填充空位信息
	p_tcb->filp[i]		= p_fd;
	
	p_fd->fd_mode		= RD_WR;
	p_fd->fd_pos		= 0;
	p_fd->fd_inode		= p_inode;
	p_inode->i_cnt++;
	if(new_inode == 1)		// 新添加的inode,需要赋值
	{
		//printk("new inode : %d\n",inode_nr);
		// 获取dev_inode指针
		hd_read(ROOT_DEV,fsbuf,SECTOR_SIZE * (INODE_1ST_SECTS + inode_nr  / INODE_PER_SECT),1);
		p_devinode = (DEV_Inode*)fsbuf;
		p_devinode += inode_nr % INODE_PER_SECT;
		// 赋值
		p_inode->i_mode		= p_devinode->i_mode;
		p_inode->i_size		= p_devinode->i_size;
		p_inode->i_start_sect	= p_devinode->i_start_sect;
		p_inode->i_nr_sects		= p_devinode->i_nr_sects;
		p_inode->i_dev		= ROOT_DEV;
		p_inode->i_num		= inode_nr;
	}
	// 返回filp中的下标
	//printk("file open : %s  ----",pathname);
	if(p_inode->i_mode == I_MODE_CHAR)			// 字符设备文件
	{
		MSG 	msg;
		msg.type				= TTY_MSG_UNION;
		msg.msg_union.tty_msg.para		= DEV_OPEN;
		msg.msg_union.tty_msg.sub_device	= MINOR(p_inode->i_start_sect);	// 字符设备的i_start_sect即设备号
		//printk("sub_device : %d       ",msg.msg_union.tty_msg.sub_device);
		disable_int();
		if(tty_has_msg_tmp == 0)
		{
			assert(sendrecv(BOTH,dd_map[MAJAR(p_inode->i_start_sect)],&msg) == 0);
		}
		enable_int();
		
	}
	//printk(" i : %d----",i);
	return	i;
}