コード例 #1
0
/**
*   Handles incoming membership reports, and
*   appends them to the routing table.
*/
void acceptGroupReport(uint32_t src, uint32_t group, uint8_t type) {
    struct IfDesc  *sourceVif;

    // Sanitycheck the group adress...
    if(!IN_MULTICAST( ntohl(group) )) {
        my_log(LOG_WARNING, 0, "The group address %s is not a valid Multicast group.",
            inetFmt(group, s1));
        return;
    }

    // Find the interface on which the report was recieved.
    sourceVif = getIfByAddress( src );
    if(sourceVif == NULL) {
        my_log(LOG_WARNING, 0, "No interfaces found for source %s",
            inetFmt(src,s1));
        return;
    }

    if(sourceVif->InAdr.s_addr == src) {
        my_log(LOG_NOTICE, 0, "The IGMP message was from myself. Ignoring.");
        return;
    }

    // We have a IF so check that it's an downstream IF.
    if(sourceVif->state == IF_STATE_DOWNSTREAM) {

        my_log(LOG_DEBUG, 0, "Should insert group %s (from: %s) to route table. Vif Ix : %d",
        inetFmt(group,s1), inetFmt(src,s2), sourceVif->index);

	// If we don't have a whitelist we insertRoute and done
	if(sourceVif->allowedgroups == NULL)
	{
#ifdef RALINK_ESW_SUPPORT
	    insert_multicast_ip(ntohl(group), ntohl(src));
#endif
	    insertRoute(group, sourceVif->index);
	    return;
	}
	// Check if this Request is legit on this interface
	struct SubnetList *sn;
	for(sn = sourceVif->allowedgroups; sn != NULL; sn = sn->next)
	    if((group & sn->subnet_mask) == sn->subnet_addr)
	    {
#ifdef RALINK_ESW_SUPPORT
		insert_multicast_ip(ntohl(group), ntohl(src));
#endif
        	// The membership report was OK... Insert it into the route table..
        	insertRoute(group, sourceVif->index);
		return;
	    }
	my_log(LOG_INFO, 0, "The group address %s may not be requested from this interface. Ignoring.", inetFmt(group, s1));
    } else {
        // Log the state of the interface the report was recieved on.
        my_log(LOG_INFO, 0, "Mebership report was recieved on %s. Ignoring.",
            sourceVif->state==IF_STATE_UPSTREAM?"the upstream interface":"a disabled interface");
    }

}
コード例 #2
0
ファイル: rttable.c プロジェクト: PterX/rt-n56u
/**
*   Activates a passive group. If the group is already
*   activated, it's reinstalled in the kernel. If
*   the route is activated, no originAddr is needed.
*/
int activateRoute(uint32_t group, uint32_t originAddr) {
    struct RouteTable*  croute;
    int result = 0;

    // Find the requested route.
    croute = findRoute(group);
    if(croute == NULL) {
        my_log(LOG_DEBUG, 0,
		"No table entry for %s [From: %s]. Inserting route.",
		inetFmt(group, s1),inetFmt(originAddr, s2));

        // Insert route, but no interfaces have yet requested it downstream.
        insertRoute(group, -1);

        // Retrieve the route from table...
        croute = findRoute(group);
    }

    if(croute != NULL) {
        // If the origin address is set, update the route data.
        if(originAddr > 0) {
            // find this origin, or an unused slot
            int i;
            for (i = 0; i < MAX_ORIGINS; i++) {
                // unused slots are at the bottom, so we can't miss this origin
                if (croute->originAddrs[i] == originAddr || croute->originAddrs[i] == 0) {
                    break;
                }
            }
            
            if (i == MAX_ORIGINS) {
                i = MAX_ORIGINS - 1;
                
                my_log(LOG_WARNING, 0, "Too many origins for route %s; replacing %s with %s",
                    inetFmt(croute->group, s1),
                    inetFmt(croute->originAddrs[i], s2),
                    inetFmt(originAddr, s3));
            }
            
            // set origin
            croute->originAddrs[i] = originAddr;
            
            // move it to the top
            while (i > 0) {
                uint32_t t = croute->originAddrs[i - 1];
                croute->originAddrs[i - 1] = croute->originAddrs[i];
                croute->originAddrs[i] = t;
                i--;
            }
        }

        // Only update kernel table if there are listeners !
        if(croute->vifBits > 0) {
            result = internUpdateKernelRoute(croute, 1);
        }
    }
    logRouteTable("Activate Route");

    return result;
}
コード例 #3
0
ファイル: request.c プロジェクト: diagprov/igmpproxy
/**
*   Handles incoming membership reports, and
*   appends them to the routing table.
*/
void acceptGroupReport(uint32_t src, uint32_t group, uint8_t type) {
    struct IfDesc  *sourceVif;

    // Sanitycheck the group adress...
    if(!IN_MULTICAST( ntohl(group) )) {
        my_log(LOG_WARNING, 0, "The group address %s is not a valid Multicast group.",
            inetFmt(group, s1));
        return;
    }

    // Find the interface on which the report was recieved.
    sourceVif = getIfByAddress( src );
    if(sourceVif == NULL) {
        my_log(LOG_WARNING, 0, "No interfaces found for source %s",
            inetFmt(src,s1));
        return;
    }

    if(sourceVif->InAdr.s_addr == src) {
        my_log(LOG_NOTICE, 0, "The IGMP message was from myself. Ignoring.");
        return;
    }

    // We have a IF so check that it's an downstream IF.
    if(sourceVif->state == IF_STATE_DOWNSTREAM) {

        my_log(LOG_DEBUG, 0, "Should insert group %s (from: %s) to route table. Vif Ix : %d",
            inetFmt(group,s1), inetFmt(src,s2), sourceVif->index);

        // The membership report was OK... Insert it into the route table..
        insertRoute(group, sourceVif->index);


    } else {
        // Log the state of the interface the report was recieved on.
        my_log(LOG_INFO, 0, "Membership report was recieved on %s. Ignoring.",
            sourceVif->state==IF_STATE_UPSTREAM?"the upstream interface":"a disabled interface");
    }

}
コード例 #4
0
ファイル: request.c プロジェクト: diagprov/igmpproxy
/**
*   Accept a V3 Membership Report
*/
void acceptV3GroupReport(uint32_t src, uint8_t type, struct igmpv3_groupreport* igmpv3rep) {
    struct IfDesc  *sourceVif;

    // Sanitycheck the group adress...
    if(!IN_MULTICAST( ntohl(group) )) {
        my_log(LOG_WARNING, 0, "The group address %s is not a valid Multicast group.",
            inetFmt(group, s1));
        return;
    }

    // Find the interface on which the report was recieved.
    sourceVif = getIfByAddress( src );
    if(sourceVif == NULL) {
        my_log(LOG_WARNING, 0, "No interfaces found for source %s",
            inetFmt(src,s1));
        return;
    }

    if(sourceVif->InAdr.s_addr == src) {
        my_log(LOG_NOTICE, 0, "The IGMP message was from myself. Ignoring.");
        return;
    }

    // We have a IF so check that it's an downstream IF.
    if(sourceVif->state != IF_STATE_DOWNSTREAM) {
        // Log the state of the interface the report was recieved on.
        my_log(LOG_INFO, 0, "Membership report was recieved on %s. Ignoring.",
            sourceVif->state==IF_STATE_UPSTREAM?"the upstream interface":"a disabled interface");

    } else {
        my_log(LOG_DEBUG, 0, "IGMPv3 Membership Report")

        // TODO: Can we batch-report here?

        uint16_t num_entries = ntohl(igmpv3rep->num_entries);
        uint16_t eix = 0;

        while ( eix < num_entries )
        {
            struct igmpv3_groupreport_entry* e = (struct igmpv3_groupreport_entry* igmpv3rep->grec) + eix;


            uint16_t num_sources = ntohl(e->nsrcs);
            uint16_t six = 0;
            while ( six < num_sources )
            {
                uint32_t* srcgroup = (uint32_t* e->sources) + six;
                group = ntohl(*srcgroup);
                switch ( e->type == 0x0 )
                {
                case IGMPV3_GRE_MODE_INCLUDE:
                case IGMPV3_GRE_CHMODE_INCLUDE:
                case IGMPV3_GRE_ALLOW_NEW_SOURCES:
                    my_log(LOG_DEBUG, 0, "IGMPv3 Subscribe to %s.",
                        inetFmt(group, s1));
                    insertRoute(group, sourceVif->index);
                    break;
                case IGMPV3_GRE_MODE_EXCLUDE:
                case IGMPV3_GRE_CHMODE_EXCLUDE:
                case IGMPV3_GRE_BLOCK_OLD_SOURCES:
                    my_log(LOG_DEBUG, 0, "IGMPv3 Unsubscribe from %s.",
                        inetFmt(group, s1));
                    deleteRoute(group, sourceVif->index);
                    break;
                default:
                    my_log(LOG_INFO, 0, "Membership V3 group report received with unknown type %d.", e->type);
                }
            };

            eix++;
        };

        return;
    }
}