Exemple #1
0
/*********************************************************************
 * Function:        void ICMPPut(NODE_INFO *remote,
 *                               ICMP_CODE code,
 *                               BYTE *data,
 *                               BYTE len,
 *                               WORD id,
 *                               WORD seq)
 *
 * PreCondition:    ICMPIsTxReady() == TRUE
 *
 * Input:           remote      - Remote node info
 *                  code        - ICMP_ECHO_REPLY or ICMP_ECHO_REQUEST
 *                  data        - Data bytes
 *                  len         - Number of bytes to send
 *                  id          - ICMP identifier
 *                  seq         - ICMP sequence number
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Note:            A ICMP packet is created and put on MAC.
 *
 ********************************************************************/
void ICMPPut(NODE_INFO *remote,
             ICMP_CODE code,
             BYTE *data,
             BYTE len,
             WORD id,
             WORD seq)
{
    ICMP_PACKET packet;

    packet.Code             = 0;
    packet.Type             = code;
    packet.Checksum         = 0;
    packet.Identifier       = id;
    packet.SequenceNumber   = seq;

    memcpy((void*)packet.Data, (void*)data, len);

    SwapICMPPacket(&packet);

    packet.Checksum         = CalcIPChecksum((BYTE*)&packet,
                                    (WORD)(ICMP_HEADER_SIZE + len));

    IPPutHeader(remote,
                IP_PROT_ICMP,
                (WORD)(ICMP_HEADER_SIZE + len));

    IPPutArray((BYTE*)&packet, (WORD)(ICMP_HEADER_SIZE + len));

    MACFlush();
}
Exemple #2
0
/**
 * A ICMP packet is created and put on MAC.
 *
 * @preCondition ICMPIsTxReady() == TRUE
 *
 * @param remote    Remote node info
 * @param code      ICMP_ECHO_REPLY or ICMP_ECHO_REQUEST
 * @param data      Data bytes
 * @param len       Number of bytes to send
 * @param id        ICMP identifier
 * @param seq       ICMP sequence number
 */
void ICMPPut(NODE_INFO *remote,
             ICMP_CODE code,
             BYTE *data,
             BYTE len,
             WORD id,
             WORD seq)
{
    ICMP_PACKET    packet;
    WORD ICMPLen;
    BUFFER MyTxBuffer;
    MyTxBuffer = MACGetTxBuffer(TRUE);

    // Abort if there is no where in the Ethernet controller to 
    // store this packet.
    if(MyTxBuffer == INVALID_BUFFER)
        return;

    IPSetTxBuffer(MyTxBuffer, 0);


    ICMPLen = ICMP_HEADER_SIZE + (WORD)len;

    packet.Code             = 0;
    packet.Type             = code;
    packet.Checksum         = 0;
    packet.Identifier       = id;
    packet.SequenceNumber   = seq;

    memcpy((void*)packet.Data, (void*)data, len);

    SwapICMPPacket(&packet);

#if defined(NON_MCHP_MAC)   //This is NOT a Microchip MAC
    packet.Checksum         = CalcIPChecksum((BYTE*)&packet,
                                    ICMPLen);
#endif

    IPPutHeader(remote,
                IP_PROT_ICMP,
                (WORD)(ICMP_HEADER_SIZE + len));

    IPPutArray((BYTE*)&packet, ICMPLen);

#if !defined(NON_MCHP_MAC)  //This is a Microchip MAC
    // Calculate and write the ICMP checksum using the Microchip MAC's DMA
    packet.Checksum = MACCalcTxChecksum(sizeof(IP_HEADER), ICMPLen);
    IPSetTxBuffer(MyTxBuffer, 2);
    MACPutArray((BYTE*)&packet.Checksum, 2);
#endif


    MACFlush();
}
Exemple #3
0
/*********************************************************************
 * Function:        BOOL UDPFlush(void)
 *
 * PreCondition:    UDPPut() is already called and desired UDP socket
 *                  is set as an active socket by calling
 *                  UDPIsPutReady().
 *
 * Input:           None
 *
 * Output:          All and any data associated with active UDP socket
 *                  buffer is marked as ready for transmission.
 *
 * Side Effects:    None
 *
 * Overview:        None
 *
 * Note:            This function transmit all data from
 *                  an active UDP socket.
 ********************************************************************/
void UDPFlush(void)
{
    UDP_HEADER      h;
    UDP_SOCKET_INFO *p;

    /*
     * When using SLIP (USART), packet transmission takes some time
     * and hence before sending another packet, we must make sure
     * that, last packet is transmitted.
     * When using ethernet controller, transmission occurs very fast
     * and by the time next packet is transmitted, previous is
     * transmitted and we do not need to check for last packet.
     */
    //while( !IPIsTxReady() );

    p = &UDPSocketInfo[activeUDPSocket];

    h.SourcePort        = swaps(p->localPort);
    h.DestinationPort   = swaps(p->remotePort);
    h.Length            = (WORD)((WORD)p->TxCount + (WORD)sizeof(UDP_HEADER));
    // Do not swap h.Length yet.  It is needed in IPPutHeader.
    h.Checksum          = 0x00;

    IPSetTxBuffer(p->TxBuffer, 0);

    /*
     * Load IP header.
     */
    IPPutHeader( &p->remoteNode,
                 IP_PROT_UDP,
                 h.Length );


    // Now swap h.Length.
    h.Length            = swaps(h.Length);

    /*
     * Now load UDP header.
     */
    IPPutArray((BYTE*)&h, sizeof(h));

    /*
     * Update checksum.
     * TO BE IMPLEMENTED
     */

    MACFlush();

    p->TxBuffer         = INVALID_BUFFER;
    p->TxCount          = 0;

}
Exemple #4
0
/**
 * This function transmit all data from the active UDP socket.
 *
 * @preCondition    UDPPut() is already called and desired UDP socket
 *                  is set as an active socket by calling
 *                  UDPIsPutReady().
 *
 * @return          All and any data associated with active UDP socket
 *                  buffer is marked as ready for transmission.
 *
 */
void UDPFlush(void)
{
    UDP_HEADER      h;
    UDP_SOCKET_INFO *p;

    // Wait for TX hardware to become available (finish transmitting 
    // any previous packet)
    while( !IPIsTxReady(TRUE) ) FAST_USER_PROCESS();

    p = &UDPSocketInfo[activeUDPSocket];

    h.SourcePort.Val        = swaps(p->localPort);
    h.DestinationPort.Val   = swaps(p->remotePort);
    h.Length.Val            = (WORD)((WORD)p->TxCount + (WORD)sizeof(UDP_HEADER));
    // Do not swap h.Length yet.  It is needed in IPPutHeader.
    h.Checksum.Val      = 0x00;

    //Makes the given TX Buffer active, and set's the pointer to the first byte after the IP
    //header. This is the first byte of the UDP header. The UDP header follows the IP header.
    IPSetTxBuffer(p->TxBuffer, 0);

    //Load IP header.
    IPPutHeader( &p->remoteNode,
                 IP_PROT_UDP,
                 h.Length.Val );


    //Now swap h.Length.Val
    h.Length.Val        = swaps(h.Length.Val);

    //Now load UDP header.
    IPPutArray((BYTE*)&h, sizeof(h));

    //Update checksum. !!!!!!!!!!!!!!! TO BE IMPLEMENTED !!!!!!!!!!!!!!!!!!!

    //Send data contained in TX Buffer via MAC
    MACFlush();

    // The buffer was reserved with AutoFree, so we can immediately 
    // discard it.  The MAC layer will free it after transmission.
    p->TxBuffer         = INVALID_BUFFER;
    p->TxCount          = 0;

}
/*********************************************************************
 * Function:        BOOL UDPFlush(void)
 *
 * PreCondition:    UDPPut() is already called and desired UDP socket
 *                  is set as an active socket by calling
 *                  UDPIsPutReady().
 *
 * Input:           None
 *
 * Output:          All and any data associated with active UDP socket
 *                  buffer is marked as ready for transmission.
 *
 * Side Effects:    None
 *
 * Overview:        None
 *
 * Note:            This function transmit all data from
 *                  an active UDP socket.
 ********************************************************************/
void UDPFlush(void)
{
    UDP_HEADER      h;
    UDP_SOCKET_INFO *p;

    // Wait for TX hardware to become available (finish transmitting
    // any previous packet)
    while( !IPIsTxReady(TRUE) );

    p = &UDPSocketInfo[activeUDPSocket];

    debug_udp("\r\nUDP FLUSH - Sok:%U TxC:%LU SP:%LU DP:%LU ",
         activeUDPSocket,
         p->TxCount,
         p->localPort,
         p->remotePort
      );
    debug_udp("MAC-%X:%X:%X:%X:%X:%X",
         p->remoteNode.MACAddr.v[0],
         p->remoteNode.MACAddr.v[1],
         p->remoteNode.MACAddr.v[2],
         p->remoteNode.MACAddr.v[3],
         p->remoteNode.MACAddr.v[4],
         p->remoteNode.MACAddr.v[5]
      );


    h.SourcePort        = swaps(p->localPort);
    h.DestinationPort   = swaps(p->remotePort);
    h.Length            = (WORD)((WORD)p->TxCount + (WORD)sizeof(UDP_HEADER));
    // Do not swap h.Length yet.  It is needed in IPPutHeader.
    h.Checksum          = 0x0000;

    IPSetTxBuffer(p->TxBuffer, 0);

    /*
     * Load IP header.
     */

    IPPutHeader( &p->remoteNode,
                 IP_PROT_UDP,
                 h.Length );


    // Now swap h.Length.
    h.Length            = swaps(h.Length);

    // Now load UDP header.
    IPPutArray((BYTE*)&h, sizeof(h));

     // Update checksum.
     // TO BE IMPLEMENTED

    MACFlush();

    // The buffer was reserved with AutoFree, so we can immediately
   // discard it.  The MAC layer will free it after transmission.
    p->TxBuffer         = INVALID_BUFFER;
    p->TxCount          = 0;

}
Exemple #6
0
/**
 * This function transmit all data from the active UDP socket.
 *
 * @preCondition    UDPPut() is already called and desired UDP socket
 *                  is set as an active socket by calling
 *                  UDPIsPutReady().
 *
 * @return          All and any data associated with active UDP socket
 *                  buffer is marked as ready for transmission.
 *
 */
void UDPFlush(void)
{
    UDP_HEADER      h;
    UDP_SOCKET_INFO *p;
    WORD csLength;
	DWORD_VAL csChecksum;
    // Wait for TX hardware to become available (finish transmitting 
    // any previous packet)
    while( !IPIsTxReady(TRUE) ) FAST_USER_PROCESS();

    p = &UDPSocketInfo[activeUDPSocket];

    h.SourcePort.Val        = swaps(p->localPort);
    h.DestinationPort.Val   = swaps(p->remotePort);
    h.Length.Val            = (WORD)((WORD)p->TxCount + (WORD)sizeof(UDP_HEADER));
    // Do not swap h.Length yet.  It is needed in IPPutHeader.
    h.Checksum.Val      = 0x00;

    //Makes the given TX Buffer active, and set's the pointer to the first byte after the IP
    //header. This is the first byte of the UDP header. The UDP header follows the IP header.
    IPSetTxBuffer(p->TxBuffer, 0);

    //Load IP header.
    IPPutHeader( &p->remoteNode,
                 IP_PROT_UDP,
                 h.Length.Val );

    // save length before swap for checksum calculation
    csLength			= p->TxCount;

    //Now swap h.Length.Val
    h.Length.Val        = swaps(h.Length.Val);

    //Now load UDP header.
    IPPutArray((BYTE*)&h, sizeof(h));

    //Update checksum. !!!!!!!!!!!!!!! TO BE IMPLEMENTED !!!!!!!!!!!!!!!!!!!
	// Update checksum.
    
	// start the checksum with value for UDP protocol & length from pseudo header (and in the actual packet)
	csChecksum.Val = (WORD)IP_PROT_UDP + (WORD)csLength + sizeof(UDP_HEADER);
	// add in my address and the remoteNode address
	csChecksum.Val += ((WORD)MY_IP_BYTE1 << 8) + MY_IP_BYTE2;
	csChecksum.Val += ((WORD)MY_IP_BYTE3 << 8) + MY_IP_BYTE4;
	csChecksum.Val += ((WORD)p->remoteNode.IPAddr.v[0] << 8) +  ((WORD)p->remoteNode.IPAddr.v[1] ) +
					  ((WORD)p->remoteNode.IPAddr.v[2] << 8) +  ((WORD)p->remoteNode.IPAddr.v[3] );
			

    // set mac pointer to the ip_addr of the source, so all of pseudo header but length is included.
    // length of pseudo header is already included in previous instruction.
    //MACSetRxBuffer( sizeof(IP_HEADER)+sizeof(UDP_HEADER) );
	

	csChecksum.Val += (WORD)p->localPort;
	csChecksum.Val += (WORD)p->remotePort;
	csChecksum.Val += (WORD)csLength + sizeof(UDP_HEADER);

	//IPSetRxBuffer(BASE_TX_ADDR + sizeof(ETHER_HEADER) + sizeof(IP_HEADER) - ( sizeof(IP_ADDR) * 2 ) );
	
    // handled in UdpPut routines
	csChecksum.Val += udpChecksum;

	// add any carry over to the last word
	while((DWORD)csChecksum.word.MSW) {
		csChecksum.Val = (DWORD)csChecksum.word.LSW + (DWORD)csChecksum.word.MSW;
	}	
	// add any carry over from adding the carry over
	//csChecksum.Val = (DWORD)csChecksum.word.LSW + (DWORD)csChecksum.word.MSW;
	
	// invert
	csChecksum.Val = ~csChecksum.Val;
	
	// set write pointer to location of checksum in packet
	//MACSetWritePtr( sizeof(ETHER_HEADER) + sizeof(IP_HEADER) + sizeof(UDP_HEADER) - 2 );
	IPSetTxBuffer(p->TxBuffer,   sizeof(UDP_HEADER) - 2);
	// write the swapped checksum to the packet
	
	
	//MACPut(	csChecksum.v[1] );
	//MACPut(	csChecksum.v[0] );
	MACPut(0);
	MACPut(0);
    //Send data contained in TX Buffer via MAC
    MACFlush();

    // The buffer was reserved with AutoFree, so we can immediately 
    // discard it.  The MAC layer will free it after transmission.
    p->TxBuffer         = INVALID_BUFFER;
    p->TxCount          = 0;

}