diff options
author | Jeremy Katz <katzj@redhat.com> | 2002-11-18 17:19:33 +0000 |
---|---|---|
committer | Jeremy Katz <katzj@redhat.com> | 2002-11-18 17:19:33 +0000 |
commit | fda834d4b0831ef0400f03d8e3bf95880b364037 (patch) | |
tree | 2773786b6d6484897ad6eb8c94c4e1e5cfc7150e | |
parent | a705ddcdf2ff8cdb5481adb31577b7867fd9e490 (diff) | |
download | anaconda-fda834d4b0831ef0400f03d8e3bf95880b364037.tar.gz anaconda-fda834d4b0831ef0400f03d8e3bf95880b364037.tar.xz anaconda-fda834d4b0831ef0400f03d8e3bf95880b364037.zip |
add getLinkStatus to determine whether an interface has an active link
-rw-r--r-- | isys/Makefile | 2 | ||||
-rw-r--r-- | isys/isys.c | 14 | ||||
-rw-r--r-- | isys/isys.h | 3 | ||||
-rw-r--r-- | isys/isys.py | 3 | ||||
-rw-r--r-- | isys/linkdetect.c | 103 | ||||
-rw-r--r-- | isys/mii.h | 84 |
6 files changed, 208 insertions, 1 deletions
diff --git a/isys/Makefile b/isys/Makefile index e630f4e22..c06b9df7b 100644 --- a/isys/Makefile +++ b/isys/Makefile @@ -4,7 +4,7 @@ CFLAGS = -ffunction-sections -I$(PYTHONINCLUDE) -I.. -Wall -Os -g -DHAVE_NFS -D OBJECTS = nfsmount.o nfsmount_clnt.o nfsmount_xdr.o imount.o \ smp.o moduleinfo.o devnodes.o cpio.o probe.o uncpio.o \ - lang.o isofs.o pdc.o dns.o + lang.o isofs.o pdc.o dns.o linkdetect.o SOBJECTS = $(patsubst %.o,%.lo,$(OBJECTS)) SOURCES = $(patsubst %.o,%.c,$(OBJECTS)) isys.c STATICOBJS = otherinsmod.o diff --git a/isys/isys.c b/isys/isys.c index a4c0bbf9b..4b3d1a91b 100644 --- a/isys/isys.c +++ b/isys/isys.c @@ -102,6 +102,7 @@ static PyObject * getFramebufferInfo(PyObject * s, PyObject * args); static PyObject * printObject(PyObject * s, PyObject * args); static PyObject * doGetPageSize(PyObject * s, PyObject * args); static PyObject * py_bind_textdomain_codeset(PyObject * o, PyObject * args); +static PyObject * getLinkStatus(PyObject * s, PyObject * args); static PyMethodDef isysModuleMethods[] = { { "ejectcdrom", (PyCFunction) doEjectCdrom, METH_VARARGS, NULL }, @@ -158,6 +159,7 @@ static PyMethodDef isysModuleMethods[] = { { "getpagesize", (PyCFunction) doGetPageSize, METH_VARARGS, NULL}, { "printObject", (PyCFunction) printObject, METH_VARARGS, NULL}, { "bind_textdomain_codeset", (PyCFunction) py_bind_textdomain_codeset, METH_VARARGS, NULL}, + { "getLinkStatus", (PyCFunction) getLinkStatus, METH_VARARGS, NULL }, { NULL } } ; @@ -1611,6 +1613,18 @@ static PyObject * doGetPageSize(PyObject * s, PyObject * args) { return Py_BuildValue("i", getpagesize()); } +static PyObject * getLinkStatus(PyObject * s, PyObject * args) { + char *dev; + int ret; + + if (!PyArg_ParseTuple(args, "s", &dev)) + return NULL; + + ret = get_link_status(dev); + /* returns 1 for link, 0 for no link, -1 for unknown */ + return Py_BuildValue("i", ret); +} + static PyObject * printObject (PyObject * o, PyObject * args) { PyObject * obj; char buf[256]; diff --git a/isys/isys.h b/isys/isys.h index 4483b80f3..38fb0358e 100644 --- a/isys/isys.h +++ b/isys/isys.h @@ -56,4 +56,7 @@ int rmmod(char * modName); /* returns 0 for true, !0 for false */ int fileIsIso(const char * file); +/* returns 1 for link, 0 for no link, -1 for unknown */ +int get_link_status(char *ifname); + #endif diff --git a/isys/isys.py b/isys/isys.py index 0262bcf99..0c4f3502d 100644 --- a/isys/isys.py +++ b/isys/isys.py @@ -501,6 +501,9 @@ def ideCdRwList(): def getpagesize(): return _isys.getpagesize() +def getLinkStatus(dev): + return _isys.getLinkStatus(dev) + printObject = _isys.printObject bind_textdomain_codeset = _isys.bind_textdomain_codeset diff --git a/isys/linkdetect.c b/isys/linkdetect.c new file mode 100644 index 000000000..466cfd60d --- /dev/null +++ b/isys/linkdetect.c @@ -0,0 +1,103 @@ +/* + * linkdetect.c - simple link detection + * + * heavily based on mii-tool.c from net-tools, just cut down to what we need + * for anaconda + * + * Copyright 2002 Red Hat, Inc. + * Copyright 2000 David A. Hinds -- dhinds@pcmcia.sourceforge.org + * + * Jeremy Katz <katzj@redhat.com> + * + * This software may be freely redistributed under the terms of the GNU + * general public license. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <errno.h> + +#include <sys/socket.h> +#include <sys/types.h> + +#include <net/if.h> + +#include "mii.h" + +static struct ifreq ifr; + +static int mdio_read(int skfd, int location) +{ + struct mii_data *mii = (struct mii_data *)&ifr.ifr_data; + mii->reg_num = location; + if (ioctl(skfd, SIOCGMIIREG, &ifr) < 0) { + fprintf(stderr, "SIOCGMIIREG on %s failed: %s\n", ifr.ifr_name, + strerror(errno)); + return -1; + } + return mii->val_out; +} + +/* we don't need writing right now */ +#if 0 +static void mdio_write(int skfd, int location, int value) +{ + struct mii_data *mii = (struct mii_data *)&ifr.ifr_data; + mii->reg_num = location; + mii->val_in = value; + if (ioctl(skfd, SIOCSMIIREG, &ifr) < 0) { + fprintf(stderr, "SIOCSMIIREG on %s failed: %s\n", ifr.ifr_name, + strerror(errno)); + } +} +#endif + + + +int get_link_status(char *ifname) { + struct mii_data *mii = (struct mii_data *)&ifr.ifr_data; + int sock, i, mii_val[32]; + + if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + fprintf(stderr, "Error creating socket: %s\n", strerror(errno)); + return -1; + } + + /* Get the vitals from the interface. */ + strncpy(ifr.ifr_name, ifname, IFNAMSIZ); + if (ioctl(sock, SIOCGMIIPHY, &ifr) < 0) { + if (errno != ENODEV) + fprintf(stderr, "SIOCGMIIPHY on '%s' failed: %s\n", + ifname, strerror(errno)); + return -1; + } + + /* Some bits in the BMSR are latched, but we can't rely on being + the only reader, so only the current values are meaningful */ + mdio_read(sock, MII_BMSR); + for (i = 0; i < 8; i++) + mii_val[i] = mdio_read(sock, i); + + if (mii_val[MII_BMCR] == 0xffff) { + fprintf(stderr, " No MII transceiver present!.\n"); + return -1; + } + + if (mii_val[MII_BMSR] & MII_BMSR_LINK_VALID) + return 1; + else + return 0; +} + +#ifdef STANDALONE +/* hooray for stupid test programs! */ +int main(int argc, char **argv) { + printf("link status of eth0 is %d\n", get_link_status("eth0")); +} +#endif diff --git a/isys/mii.h b/isys/mii.h new file mode 100644 index 000000000..2ec6425b5 --- /dev/null +++ b/isys/mii.h @@ -0,0 +1,84 @@ +/* + * mii.h 1.4 2000/04/25 22:06:15 + * + * Media Independent Interface support: register layout and ioctl's + * + * Copyright (C) 2000 David A. Hinds -- dhinds@pcmcia.sourceforge.org + */ + +#ifndef _LINUX_MII_H +#define _LINUX_MII_H + +/* network interface ioctl's for MII commands */ +#ifndef SIOCGMIIPHY +#define SIOCGMIIPHY 0x8947 /* Read from current PHY */ +#define SIOCGMIIREG 0x8948 /* Read any PHY register */ +#define SIOCSMIIREG 0x8949 /* Write any PHY register */ +#endif + +#include <linux/types.h> + +/* This data structure is used for all the MII ioctl's */ +struct mii_data { + __u16 phy_id; + __u16 reg_num; + __u16 val_in; + __u16 val_out; +}; + +/* Basic Mode Control Register */ +#define MII_BMCR 0x00 +#define MII_BMCR_RESET 0x8000 +#define MII_BMCR_LOOPBACK 0x4000 +#define MII_BMCR_100MBIT 0x2000 +#define MII_BMCR_AN_ENA 0x1000 +#define MII_BMCR_ISOLATE 0x0400 +#define MII_BMCR_RESTART 0x0200 +#define MII_BMCR_DUPLEX 0x0100 +#define MII_BMCR_COLTEST 0x0080 + +/* Basic Mode Status Register */ +#define MII_BMSR 0x01 +#define MII_BMSR_CAP_MASK 0xf800 +#define MII_BMSR_100BASET4 0x8000 +#define MII_BMSR_100BASETX_FD 0x4000 +#define MII_BMSR_100BASETX_HD 0x2000 +#define MII_BMSR_10BASET_FD 0x1000 +#define MII_BMSR_10BASET_HD 0x0800 +#define MII_BMSR_NO_PREAMBLE 0x0040 +#define MII_BMSR_AN_COMPLETE 0x0020 +#define MII_BMSR_REMOTE_FAULT 0x0010 +#define MII_BMSR_AN_ABLE 0x0008 +#define MII_BMSR_LINK_VALID 0x0004 +#define MII_BMSR_JABBER 0x0002 +#define MII_BMSR_EXT_CAP 0x0001 + +#define MII_PHY_ID1 0x02 +#define MII_PHY_ID2 0x03 + +/* Auto-Negotiation Advertisement Register */ +#define MII_ANAR 0x04 +/* Auto-Negotiation Link Partner Ability Register */ +#define MII_ANLPAR 0x05 +#define MII_AN_NEXT_PAGE 0x8000 +#define MII_AN_ACK 0x4000 +#define MII_AN_REMOTE_FAULT 0x2000 +#define MII_AN_ABILITY_MASK 0x07e0 +#define MII_AN_FLOW_CONTROL 0x0400 +#define MII_AN_100BASET4 0x0200 +#define MII_AN_100BASETX_FD 0x0100 +#define MII_AN_100BASETX_HD 0x0080 +#define MII_AN_10BASET_FD 0x0040 +#define MII_AN_10BASET_HD 0x0020 +#define MII_AN_PROT_MASK 0x001f +#define MII_AN_PROT_802_3 0x0001 + +/* Auto-Negotiation Expansion Register */ +#define MII_ANER 0x06 +#define MII_ANER_MULT_FAULT 0x0010 +#define MII_ANER_LP_NP_ABLE 0x0008 +#define MII_ANER_NP_ABLE 0x0004 +#define MII_ANER_PAGE_RX 0x0002 +#define MII_ANER_LP_AN_ABLE 0x0001 + +#endif /* _LINUX_MII_H */ |