Beispiel #1
0
void ANNOUNCE_DeInit(const TCPIP_STACK_MODULE_CTRL* const stackData)
{
    SGL_LIST_NODE*  node;

    announceEventPending = false;

    if (announceDHCPHandler != NULL)
    {
        DHCPDeRegisterHandler(announceDHCPHandler);
        announceDHCPHandler = NULL;
    }

#if defined (TCPIP_STACK_USE_IPV6)
    if (announceIPV6Handler != NULL)
    {
        TCPIP_IPV6_DeRegisterHandler(announceIPV6Handler);
        announceIPV6Handler = NULL;
    }
#endif

    // Free all announce events
    while ((node = SingleListRemoveHead(&announceEvents)) != NULL)
    {
        TCPIP_HEAP_Free (announceMemH, node);
    }

    announceMemH = 0;
}
Beispiel #2
0
static void _ARPCleanupClients(void)
{
    SGL_LIST_NODE* aNode;

    while( (aNode = SingleListRemoveHead(&arpRegisteredUsers)) != 0 )
    {
        TCPIP_HEAP_Free(arpMemH, aNode);
    }
}
Beispiel #3
0
// Deletes an entry to make room in the hash table.
// This shouldn't normally occur if ARPTask()
// does its job of periodically performing the cache clean-up.
// However, since the threshold can be dynamically adjusted,
// the situation could still occur
OA_HASH_ENTRY* OAHashDeleteEntry(OA_HASH_DCPT* pOH)
{
    ARP_CACHE_DCPT  *pArpDcpt;
    ARP_HASH_ENTRY  *pE;
    SGL_LIST_NODE   *pN;
    SINGLE_LIST     *pRemList = 0;

    pArpDcpt = (ARP_CACHE_DCPT*)pOH;

    if( (pN = pArpDcpt->incompleteList.head) != 0)
    {
        pE = (ARP_HASH_ENTRY*) ((uint8_t*)pN - offsetof(ARP_HASH_ENTRY, next));
        if( (arpTimeSeconds - pE->tInsert) >= ARP_CACHE_PENDING_ENTRY_TMO)
        {   // we remove this one
            pRemList = &pArpDcpt->incompleteList;
        }
    }

    if(pRemList == 0)
    {   // no luck with the incomplete list; use the complete one
        pRemList = &pArpDcpt->completeList;
    }

    pN = SingleListRemoveHead(pRemList);

    if(pN)
    {
        pE = (ARP_HASH_ENTRY*) ((uint8_t*)pN - offsetof(ARP_HASH_ENTRY, next));
        return &pE->hEntry;
    }

    // it's possible to be unable to make room in the cache
    // for example, too many permanent entries added...

    return 0;
}
Beispiel #4
0
// called after service needed reported
// maintain the queues
void ARPTask(void)
{
    int netIx, purgeIx;
    ARP_HASH_ENTRY  *pE;
    ARP_CACHE_DCPT  *pArpDcpt;
    SGL_LIST_NODE   *pN;
    NET_CONFIG *pIf;
    int         nArpIfs;

    nArpIfs = TCPIP_STACK_NetworksNo();

    for(netIx = 0, pArpDcpt = arpCache; netIx < nArpIfs; netIx++, pArpDcpt++)
    {
        pIf = (NET_CONFIG*)TCPIP_STACK_IxToNet(netIx);

        // process the incomplete queue
        // see if there's something to remove
        while( (pN = pArpDcpt->incompleteList.head) != 0)
        {
            pE = (ARP_HASH_ENTRY*) ((uint8_t*)pN - offsetof(ARP_HASH_ENTRY, next));
            if( (arpTimeSeconds - pE->tInsert) >= ARP_CACHE_PENDING_ENTRY_TMO)
            {   // expired, remove it
                OAHashRemoveEntry(pArpDcpt->cacheDcpt, &pE->hEntry);
                SingleListRemoveHead(&pArpDcpt->incompleteList);
            }
            else
            {   // this list is ordered, we can safely break out
                break;
            }
        }

        // see if we have to query again
        for(pN = pArpDcpt->incompleteList.head; pN != 0; pN = pN->next)
        {
            pE = (ARP_HASH_ENTRY*) ((uint8_t*)pN - offsetof(ARP_HASH_ENTRY, next));
            if( (arpTimeSeconds - pE->tInsert) >= pE->nRetries * ARP_CACHE_PENDING_RETRY_TMO)
            {   // expired, retry it
                ARP_SendIfPkt(pIf, ARP_OPERATION_REQ, (uint32_t)pIf->MyIPAddr.Val, pE->ipAddress, &arpBcastAdd);
                pE->nRetries++;
            }
        }

        // see the completed entries queue
        while( (pN = pArpDcpt->completeList.head) != 0)
        {
            pE = (ARP_HASH_ENTRY*) ((uint8_t*)pN - offsetof(ARP_HASH_ENTRY, next));
            if( (arpTimeSeconds - pE->tInsert) >= ARP_CACHE_SOLVED_ENTRY_TMO)
            {   // expired, remove it
                OAHashRemoveEntry(pArpDcpt->cacheDcpt, &pE->hEntry);
                SingleListRemoveHead(&pArpDcpt->completeList);
            }
            else
            {   // this list is ordered, we can safely break out
                break;
            }
        }

        // finally purge, if needed
        if(pArpDcpt->cacheDcpt->fullSlots >= pArpDcpt->purgeThres)
        {
            for(purgeIx = 0; purgeIx < pArpDcpt->purgeQuanta; purgeIx++)
            {
                pN = SingleListRemoveHead(&pArpDcpt->completeList);
                if(pN)
                {
                    pE = (ARP_HASH_ENTRY*) ((uint8_t*)pN - offsetof(ARP_HASH_ENTRY, next));
                    OAHashRemoveEntry(pArpDcpt->cacheDcpt, &pE->hEntry);
                }
                else
                {   // no more entries
                    break;
                }
            }
        }


    }


    arpTickPending = 0;
}
Beispiel #5
0
void ANNOUNCE_Send(void)
{
    UDP_SOCKET  announceSocket;
    int         netIx;
    uint16_t    dataLen;
    uint16_t    minimumDataLen;
    uint16_t    txLen;
    bool truncated;
    NET_CONFIG * pNetIf;
    ANNOUNCE_LIST_NODE *  node = (ANNOUNCE_LIST_NODE *)announceEvents.head;
    ANNOUNCE_FIELD_PAYLOAD payloadType;
    uint16_t terminatorLen = strlen ((const char *)announceFieldTerminator);

#if defined (TCPIP_STACK_USE_IPV6)
    IPV6_ADDR_STRUCT * addressPointer;
#endif

    while (node != NULL)
    {    
        pNetIf = (NET_CONFIG *)node->handle;

        netIx = TCPIP_STACK_NetIx (pNetIf);

        truncated = false;

        dataLen = ((terminatorLen + 1) * 4) + sizeof (IPV4_ADDR) + sizeof (MAC_ADDR);

        dataLen += strlen(TCPIP_HOSTS_CONFIGURATION[netIx].interface);
        dataLen += strlen((char *)pNetIf->NetBIOSName);
    
        minimumDataLen = dataLen + 1 + terminatorLen;
    
        if(!MACIsLinked(_TCPIPStackNetToMac(pNetIf)))  // Check for link before blindly opening and transmitting (similar to DHCP case)
        {
            return;
        }
    
        announceSocket = UDPOpenClient(IP_ADDRESS_TYPE_IPV4, ANNOUNCE_PORT, 0);
    
        if (announceSocket == INVALID_UDP_SOCKET)
        {
            return;
        }
    
        UDPSocketSetNet (announceSocket, pNetIf);
    
    #if defined (TCPIP_STACK_USE_IPV6)
        addressPointer = (IPV6_ADDR_STRUCT *)ipv6Config[netIx].listIpv6UnicastAddresses.head;
    
        while(addressPointer != NULL)
        {
            dataLen += sizeof (IPV6_ADDR) + 1 + terminatorLen;
            addressPointer = addressPointer->next;
        }
    
        addressPointer = (IPV6_ADDR_STRUCT *)ipv6Config[netIx].listIpv6MulticastAddresses.head;
    
        while(addressPointer != NULL)
        {
            dataLen += sizeof (IPV6_ADDR) + 1 + terminatorLen;
            addressPointer = addressPointer->next;
        }
    #endif
    
        if (dataLen > ANNOUNCE_MAX_PAYLOAD)
        {
            dataLen = ANNOUNCE_MAX_PAYLOAD;
        }
    
        if ((txLen = UDPIsTxPutReady(announceSocket, dataLen)) < dataLen)
        {
            truncated = true;
            if ((txLen = UDPIsTxPutReady(announceSocket, minimumDataLen)) < minimumDataLen)
            {
                UDPClose (announceSocket);
                return;
            }
        }
    
        // Put Mac Address
        payloadType = ANNOUNCE_FIELD_MAC_ADDR;
        UDPPut (announceSocket, payloadType);
        UDPPutArray(announceSocket, (const uint8_t *)&pNetIf->MyMACAddr, sizeof (MAC_ADDR));
        UDPPutArray (announceSocket, announceFieldTerminator, terminatorLen);

        if (truncated)
        {
            payloadType = ANNOUNCE_FIELD_TRUNCATED;
            UDPPut (announceSocket, payloadType);
            UDPPutArray (announceSocket, announceFieldTerminator, terminatorLen);
        }

        // Put Mac Type
        payloadType = ANNOUNCE_FIELD_MAC_TYPE;
        UDPPut (announceSocket, payloadType);
        UDPPutArray(announceSocket, (const uint8_t *)TCPIP_HOSTS_CONFIGURATION[netIx].interface, strlen ((const char *)TCPIP_HOSTS_CONFIGURATION[netIx].interface));
        UDPPutArray (announceSocket, announceFieldTerminator, terminatorLen);

        // Put Host Name
        payloadType = ANNOUNCE_FIELD_HOST_NAME;
        UDPPut (announceSocket, payloadType);
        UDPPutArray(announceSocket, (const uint8_t *)&pNetIf->NetBIOSName, strlen((char*)pNetIf->NetBIOSName));
        UDPPutArray (announceSocket, announceFieldTerminator, terminatorLen);

        // Put IPv4 Address
        payloadType = ANNOUNCE_FIELD_IPV4_ADDRESS;
        UDPPut (announceSocket, payloadType);
        UDPPutArray(announceSocket, (const uint8_t *)&pNetIf->MyIPAddr, sizeof (IP_ADDR));
        UDPPutArray (announceSocket, announceFieldTerminator, terminatorLen);
    
#if defined (TCPIP_STACK_USE_IPV6)
    
        // Put IPv6 unicast addresses
        minimumDataLen = sizeof (IPV6_ADDR) + 1 + terminatorLen;
    
        addressPointer = (IPV6_ADDR_STRUCT *)ipv6Config[netIx].listIpv6UnicastAddresses.head;
    
        payloadType = ANNOUNCE_FIELD_IPV6_UNICAST;

        while(addressPointer != NULL && (UDPIsTxPutReady(announceSocket, minimumDataLen) >= minimumDataLen))
        {
            UDPPut (announceSocket, payloadType);
            UDPPutArray(announceSocket, (const uint8_t *)&addressPointer->address, sizeof (IPV6_ADDR));
            UDPPutArray (announceSocket, announceFieldTerminator, terminatorLen);
            addressPointer = addressPointer->next;
        }
    
        // Put IPv6 multicast listeners    
        addressPointer = (IPV6_ADDR_STRUCT *)ipv6Config[netIx].listIpv6MulticastAddresses.head;
    
        payloadType = ANNOUNCE_FIELD_IPV6_MULTICAST;

        while(addressPointer != NULL && (UDPIsTxPutReady(announceSocket, minimumDataLen) >= minimumDataLen))
        {
            UDPPut (announceSocket, payloadType);
            UDPPutArray(announceSocket, (const uint8_t *)&addressPointer->address, sizeof (IPV6_ADDR));
            UDPPutArray (announceSocket, announceFieldTerminator, terminatorLen);
            addressPointer = addressPointer->next;
        }
#endif
    
        UDPFlush (announceSocket);
    
        UDPClose (announceSocket);

        SingleListRemoveHead(&announceEvents);

        TCPIP_HEAP_Free (announceMemH, node);

        node = (ANNOUNCE_LIST_NODE *)announceEvents.head;

        if (node == NULL)
        {
            announceEventPending = false;
        }
    }
}