[RFC] small app for aiding non-MII card link detection on idle networks



Hi Dan,

Here is a small program to send a LOOPBACK packet on an interface.
I tested on my systems (FC2/FC3) and it works.
Launch it with an ethernet interface argument for sending a loopback
packet on that interface.
If the link is up, then you will have growing RX_bytes on the interface.
We should run this only if there is no network activity, ie RX_bytes on
the interface is not growing.
At one point we may want this in HAL, and HAL will export to everybody the
link status of the non-MII card.

The program bellow can be improved, but it is a working start.
Comments ?

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <ctype.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <linux/if.h>

char outpack[30];

int main(int argc, char *argv[])
{
        struct sockaddr whereto;
        char *ifname = "eth0" ;
        int s;

        if (argc == 2) ifname = argv[1] ;
                else
                        {
                        puts ("Usage : loop NETWORK_INTERFACE \n\
where NETWORK_INTERFACE is a valid ethernet device \n\
default NETWORK_INTERFACE is eth0, all other arguments are ignored");
                        }

        if ((s = socket(AF_INET, SOCK_PACKET, SOCK_PACKET)) < 0) {
                if (errno == EPERM)
                        fprintf(stderr, "must run me as root\n");
                else
                        perror("error socket");
        }
        /* Don't revert if debugging allows a normal user to get the raw socket. */
        setuid(getuid());

        struct ifreq if_hwaddr;
        unsigned char *hwaddr = if_hwaddr.ifr_hwaddr.sa_data;

                strcpy(if_hwaddr.ifr_name, ifname);
                if (ioctl(s, SIOCGIFHWADDR, &if_hwaddr) < 0) {
                        fprintf(stderr, "SIOCGIFHWADDR on %s failed: %s\n", ifname,
                                        strerror(errno));
                        return 1;
                }

/* set destination and source MAC address as our own */

                memcpy(outpack, if_hwaddr.ifr_hwaddr.sa_data, 6);
                memcpy(outpack+6, if_hwaddr.ifr_hwaddr.sa_data, 6);

/* set ETHER-TYPE to 0x9000 meaning LOOPBACK packet */
                outpack[12]=0x90;
                outpack[13]=0x00;

/* set loop.function to Replay  */
                outpack[16]=0x01;

        whereto.sa_family = 0;
        strcpy(whereto.sa_data, ifname);

/* send the whole packet which is 20 bytes long */

        if (sendto(s, outpack, 20 , 0, &whereto, sizeof(whereto)) < 0)
                perror("sendto");
}






[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]