示例#1
0
int sr_integ_low_level_output(struct sr_instance* sr /* borrowed */,
                             uint8_t* buf /* borrowed */ ,
                             unsigned int len,
                             const char* iface /* borrowed */)
{
#ifdef _CPUMODE_
    return sr_cpu_output(sr, buf /*lent*/, len, iface);
#else
    return sr_vns_send_packet(sr, buf /*lent*/, len, iface);
#endif /* _CPUMODE_ */
} /* -- sr_vns_integ_output -- */
int sr_cpu_input( struct sr_instance* sr ) {
    byte buf[ETH_MAX_LEN];
    ssize_t len;
    router_t* router;
    interface_t* intf;
    fd_set rdset, errset;
    int ret, max_fd;
    unsigned i;
    struct timeval timeout;

    /* loop until something interesting happens */
    do {
        /* clear the sets */
        FD_ZERO( &rdset );
        FD_ZERO( &errset );

        /* set the bits on interfaces' fd's that we care about */
        max_fd = -1;
        router = sr->interface_subsystem;
        for( i=0; i<router->num_interfaces; i++ ) {
            if( router->interface[i].enabled ) {
                FD_SET( router->interface[i].hw_fd, &rdset );
                FD_SET( router->interface[i].hw_fd, &errset );

                if( router->interface[i].hw_fd > max_fd )
                    max_fd = router->interface[i].hw_fd;

#ifdef _DEBUG_
                if( router->interface[i].hw_fd > FD_SETSIZE )
                    die( "Error: fd too big for select (%d > %d)",
                         router->interface[i].hw_fd, FD_SETSIZE );
#endif
            }
        }

        /* wait for something to happen */
        timeout.tv_sec  = 1;
        timeout.tv_usec = 0;
        ret = select( max_fd + 1, &rdset, NULL, &errset, &timeout );

        /* check each intf to see if something interesting happened on it */
        for( i=0; i<router->num_interfaces; i++ ) {
            intf = &router->interface[i];
            if( intf->enabled ) {
                /* check for available bytes in the input buffer */
                if( FD_ISSET( intf->hw_fd, &rdset ) ) {
                    len = real_read_once( intf->hw_fd, buf, ETH_MAX_LEN );
                    if( len == 0 )
                        debug_println( "Warning: HW socket closed to %s",
                                       intf->name );
                    else if( len < 0 )
                        debug_println( "Warning: error when reading on HW socket to %s",
                                       intf->name );
                    else {
#if 0
                        /* check packet for decap first */
                        if( len >= 34 ) {
                            if( buf[23] == 0x04 || buf[23] == 0xF4 ) {
                                debug_println( "*** DECAPSULATING PACKET ***" );

                                /* write a new Ethernet header */
                                byte* new_buf = buf + 20;
                                memset( new_buf, 0xFF, ETH_ADDR_LEN );
                                memcpy( new_buf+6, &router->interface[DECAP_NEXT_INTF].mac, ETH_ADDR_LEN );
                                *((uint16_t*)(new_buf+12)) = IPV4_ETHERTYPE;

                                /* send it back out nf2c{DECAP_NEXT_INTF} */
                                sr_cpu_output( new_buf, len-20, &router->interface[DECAP_NEXT_INTF] );
                                count+=len;
                                fprintf(stderr,"%llu\n",count-20);
                                continue;
                            }
                        }
#endif
                        /* send the packet to our processing pipeline */
                        sr_integ_input( sr, buf, len, intf );

                        /* log the received packet */
                        sr_log_packet( sr, buf, len );

                        return 1;
                    }
                }

                /* check for an error on the socket */
                if( FD_ISSET( intf->hw_fd, &errset ) ) {
                    debug_println( "Warning: error on HW socket to %s",
                                   intf->name );
                }
            }
        }
    }
    while( 1 );
}