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

📄 user.c

📁 mcf5307实验源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    /*
     *  install maximum segment size which will be sent out in the first
     *  ACK-SYN packet
     */
    prt->tcpout.x.options[0]=2;
	prt->tcpout.x.options[1]=4;

	/* install maximum segment size */
	seg=intswap(mseg);
	memcpy ((void *)&prt->tcpout.x.options[2], (const void *)&seg, 2);


//	sprintf(buffer,"Send Syn:%u,%u",++syntimes,++syntimes_add);
//	 __TextOut(10,120,12,buffer);

	Send_SYN_FIN(prt, 4);

	prt->state=SSYNS;                         /* syn sent */

	/* Increment the number active connections attempted. */
	SNMP_tcpActiveOpens_Inc;

	prt->out.nxt++;                       /* ack should be for next byte */
	return(pnum);                         /* do not wait for connect */
}   /* doconnect */

/*************************************************************************/
/*                                                                       */
/* FUNCTION                                                              */
/*                                                                       */
/*      Send_SYN_FIN(int16, uint16, uint16)                              */
/*                                                                       */
/* DESCRIPTION                                                           */
/*                                                                       */
/*   This routine is responsible for sending a packet containing either  */
/*   a SYN or FIN bit.                                                   */
/*                                                                       */
/* CALLED BY                                                             */
/*      netxopen                                                         */
/*                                                                       */
/* CALLS                                                                 */
/*                                                                       */
/*      intswap                                                          */
/*      tcp_sendack                                                      */
/*                                                                       */
/*************************************************************************/
int16 Send_SYN_FIN(PORT *prt, int16 options)
{
    uint16          *temp_tcp;
    TCPKT           *tcp_ptr;
    uint16          p_size;
    BUFFER          *buf_ptr;
    int16           tcp_hlen;

    buf_ptr = allocate_buffer(prt);
    if(buf_ptr == NU_NULL)
        return -1;

    /* Initialize each field in the buffer. */
    /* Point the data pointer at an offset into the buffer large
       enough to leave room for the header information. */
    buf_ptr->data_ptr = buf_ptr->packet + (sizeof(DLAYER) +
                                           sizeof(IPLAYER) +
                                           sizeof(TCPLAYER) + options);

    /* There are 4 bytes of option data in the SYN packet. */
    buf_ptr->data_len = 0;
    buf_ptr->option_len = options;

    /* Store the sequence number of this packet. */
    buf_ptr->seqnum = prt->out.nxt;

    /* Initialize the number of times this packet has been retransmitted. */
    buf_ptr->retransmits = MAX_RETRANSMITS;

    /* Update the number of packets in this port. */
    prt->out.num_packets++;

    /* Get a pointer to the header information to be copied into the packet. */
    temp_tcp = (uint16 *) &prt->tcpout;
    temp_tcp++;

    /* Compute the sizeof the TCP header in words */
    tcp_hlen = ((sizeof(TCPLAYER) + options - 1) / 4) + 1;

    /* Update the header information. */
    tcp_update_headers(prt, options, longswap(buf_ptr->seqnum), tcp_hlen);

    /* Compute the length of the packet. */
    p_size = sizeof(DLAYER) + sizeof(IPLAYER) + sizeof(TCPLAYER) + options;

    /* Move the header information into the packet. */
    memcpy ((void *)buf_ptr->packet, (const void *)temp_tcp, p_size);

    tcp_ptr = (TCPKT *)(buf_ptr->packet - 2);

    /* Compute and fill in the checksum. */
    tcp_ptr->t.check = tcpcheck((uint16 *)&prt->tcps,
                            (uint16 *) &tcp_ptr->t,
                            (uint16)(options + sizeof(TCPLAYER)));

    /* Set a retransmit event for this packet. */
    Stimerset (CONCLASS, TCPRETRANS, prt->pindex, prt->rto,
               buf_ptr->seqnum);

    /* Increment the number of IP packets transmitted. */
    SNMP_ipOutRequests_Inc;

    /* Increment the number of TCP segments transmitted. */
    SNMP_tcpOutSegs_Inc;

    /* Send the packet. */
    return (NET_Send(buf_ptr, p_size, TCP_DATA_PKT));
}  /* Send_SYN_FIN */

/*************************************************************************/
/*                                                                       */
/* FUNCTION                                                              */
/*                                                                       */
/*      netclose                                                         */
/*                                                                       */
/* DESCRIPTION                                                           */
/*                                                                       */
/*   Start the closing process on port pnum.                             */
/*                                                                       */
/* CALLED BY                                                             */
/*      NU_EventsDispatcher                                              */
/*      NU_Close_Socket                                                  */
/*                                                                       */
/* CALLS                                                                 */
/*      tcp_sendack                                                      */
/*                                                                       */
/* INPUTS                                                                */
/*      pnum            Number of the port to close.                     */
/*                                                                       */
/* OUTPUTS                                                               */
/*                                                                       */
/*      Success or failure.                                              */
/*                                                                       */
/* HISTORY                                                               */
/*         NAME            DATE                    REMARKS               */
/*                                                                       */
/*     G. Johnson        06/13/95      Modified SCWAIT case of the switch*/
/*                                     statment to fix a bug.            */
/*                                                                       */
/*************************************************************************/
int16 netclose (int16 pnum)
{
    PORT *prt;
    int16         return_status = -1;

	if ((pnum < 0) || (pnum > NPORTS))		   /* is a valid port? */
		return (-1);

    if ((prt = portlist[pnum]) != NU_NULL)
	{		 /* something there */
        switch (prt->state)
		{
            case SLISTEN:             /* we don't care anymore */
			case SSYNS:

                 /* Increment the number of connection failures. */
                 SNMP_tcpAttemptFails_Inc;

                 prt->state = SCLOSED;
				 break;

			case SEST:					  /* must initiate close */
                 /* Send FIN only if all data has been transmitted. */
                 if (prt->out.nextPacket == NU_NULL)
                 {
                    if(prt->portFlags & ACK_TIMER_SET)
                    {
                        /*  Delete the ACK timeout timer.  */
                        Stimerunset(CONCLASS, TCPACK, prt->pindex, (int32)1);

                        /* Clear the ACK timer flag in the port. */
                        prt->portFlags &= (~ACK_TIMER_SET);
                    }

                    prt->tcpout.t.flags = TACK | TFIN;
                    Send_SYN_FIN(prt, 0);
                    prt->state = SFW1;           /* wait for ACK of FIN */
                    return_status = NU_SUCCESS;
                 }
                 else
                 {
                    if (prt->xmitFlag == NU_SET)
                    {
                         Stimerunset (CONCLASS, CONTX, prt->pindex, (int32)1);

                         prt->tcpout.t.flags = TPUSH | TACK | TFIN;

                         tcp_xmit(prt, prt->out.nextPacket);

                         prt->out.nextPacket = (BUFFER *)prt->out.nextPacket->next;

                         prt->xmitFlag = NU_CLEAR;
                    }

                    prt->state = SFW1;           /* wait for ACK of FIN */

                    prt->closeFlag = NU_SET;
                    return_status = -1;

                 }
                 break;                   /* do nothing for now ?*/


			case SCWAIT:			  /* other side already closed */
                 /* Send the FIN. */
                 prt->tcpout.t.flags = TFIN | TACK;
                 Send_SYN_FIN(prt, 0);

                 /* Update the connection state. */
                 prt->state = SLAST;

                 /* Deallocate any date that is in the in window. */
                 if (prt->in.contain)
                 {
                    dll_cleanup(&prt->in.packet_list);
                 }

                 if(prt->out.contain)
                 {
                    dll_cleanup(&prt->out.packet_list);
                    prt->out.nextPacket = NU_NULL;
                 }

                 return_status = -1;
                 break;

			case STWAIT:			  /* time out yet? */
				 if ((portlist[pnum]->out.lasttime + WAITTIME) < n_clicks ())
				 {
                     prt->state = SCLOSED;
				 }

                 return_status = NU_SUCCESS;

				 break;

            case SLAST:
                 /* If the state is SLAST, then a FIN has already been sent.  We
                    are waiting for an ACK.  If one is not received the
                    retransmit timeout will eventually close this connection.
                 */
                 return_status = -1;

                 break;

            case SCLOSING:
            case SCLOSED:
                 return_status = NU_SUCCESS;
                 break;

			default:
				 break;
		}
	}
	else
	{
		return (1);
	}
    return (return_status);
}  /* end netclose */

/*************************************************************************/
/*                                                                       */
/* FUNCTION                                                              */
/*                                                                       */
/*      netinit(void)                                                    */
/*                                                                       */
/* DESCRIPTION                                                           */
/*                                                                       */
/*   Handles all the initialization to bring up the network connection.  */
/*   Assumes that the configuration file has already been read up.       */

⌨️ 快捷键说明

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