Logo Search packages:      
Sourcecode: laptop-net version File versions  Download package

probe.c

/* -*-C-*-

$Id: probe.c,v 1.3 2005/03/01 21:22:47 cph Exp $

Copyright 2003 Massachusetts Institute of Technology

This file is part of autonet.

Autonet is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.

Autonet is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License
along with autonet; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

*/

#include "config.h"

#include <string.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <linux/sockios.h>
#include <net/if.h>

#ifdef HAVE_ETHTOOL
#  include <linux/types.h>
   typedef __u8 u8;
   typedef __u16 u16;
   typedef __u32 u32;
   typedef __u64 u64;
#  include <linux/ethtool.h>
#endif

#ifndef SIOCGMIIPHY
#  define SIOCGMIIPHY 0x8947  /* Get the PHY in use. */
#  define SIOCGMIIREG 0x8948  /* Read a PHY register. */
#endif

/* Pre-2.4 kernels used these numbers instead.  */
#define OLD_SIOCGMIIPHY SIOCDEVPRIVATE
#define OLD_SIOCGMIIREG (SIOCDEVPRIVATE + 1)

static unsigned int probe_link_mii_1 (int, const char *, int, int, int *);

unsigned int
probe_link_ethtool (int fd, const char * if_name, int * conn_p_r)
{
#ifdef HAVE_ETHTOOL
  struct ethtool_value ev;
  struct ifreq ifr;

  (ev . cmd) = ETHTOOL_GLINK;
  strncpy ((ifr . ifr_name), if_name, IFNAMSIZ);
  (ifr . ifr_data) = ((caddr_t) (&ev));
  if ((ioctl (fd, SIOCETHTOOL, (&ifr))) < 0)
    return (errno);
  (*conn_p_r) = (ev . data);
  return (0);
#else
  return (EOPNOTSUPP);
#endif
}

unsigned int
probe_link_mii (int fd, const char * if_name, int * conn_p_r)
{
  return (probe_link_mii_1 (fd, if_name,
                      SIOCGMIIPHY, SIOCGMIIREG,
                      conn_p_r));
}

unsigned int
probe_link_old_mii (int fd, const char * if_name, int * conn_p_r)
{
  return (probe_link_mii_1 (fd, if_name,
                      OLD_SIOCGMIIPHY, OLD_SIOCGMIIREG,
                      conn_p_r));
}

static unsigned int
probe_link_mii_1 (int fd, const char * if_name,
              int siocgmiiphy, int siocgmiireg,
              int * conn_p_r)
{
  struct ifreq ifr;
  u16 * data = ((u16 *) (& (ifr . ifr_data)));

  strncpy ((ifr . ifr_name), if_name, IFNAMSIZ);
  (data[1]) = 1;        /* BMSR */
  if ((ioctl (fd, siocgmiiphy, (&ifr))) < 0)
    return (errno);
  (data[1]) = 1;        /* BMSR */
  if ((ioctl (fd, siocgmiireg, (&ifr))) < 0)
    return (errno);
  if ((data[3]) == 0xFFFF)
    /* Interface no longer available.  */
    return (ENODEV);
  /* Check for:
     0x0002 clear = no jabber
     0x0004 set = link up
     0x0010 clear = no remote fault */
  (*conn_p_r) = (((data[3]) & 0x0016) == 0x0004);
  return (0);
}

Generated by  Doxygen 1.6.0   Back to index