]> git.ipfire.org Git - people/ms/rstp.git/blame - netif_utils.c
fixes for 4.3.3 GCC warnings/errors
[people/ms/rstp.git] / netif_utils.c
CommitLineData
ad02a0eb
SH
1/*****************************************************************************
2 Copyright (c) 2006 EMC Corporation.
3
4 This program is free software; you can redistribute it and/or modify it
5 under the terms of the GNU General Public License as published by the Free
6 Software Foundation; either version 2 of the License, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful, but WITHOUT
10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 more details.
13
14 You should have received a copy of the GNU General Public License along with
15 this program; if not, write to the Free Software Foundation, Inc., 59
16 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18 The full GNU General Public License is included in this distribution in the
19 file called LICENSE.
20
21 Authors: Srinivas Aji <Aji_Srinivas@emc.com>
22
23******************************************************************************/
24
25#include "netif_utils.h"
26
27#include <errno.h>
28#include <string.h>
29#include <stdlib.h>
30#include <unistd.h>
31#include <stdint.h>
32#include <sys/socket.h>
33#include <sys/ioctl.h>
34#include <fcntl.h>
76eb7423 35#include <limits.h>
ad02a0eb
SH
36
37#include <net/if.h>
38#include <linux/if_ether.h>
39#include <linux/ethtool.h>
40#include <linux/sockios.h>
41
42#include "log.h"
43
ad02a0eb
SH
44int netsock = -1;
45
46int netsock_init(void)
47{
11904a35
SH
48 LOG("");
49 netsock = socket(AF_INET, SOCK_DGRAM, 0);
50 if (netsock < 0) {
51 ERROR("Couldn't open inet socket for ioctls: %m\n");
52 return -1;
53 }
54 return 0;
ad02a0eb
SH
55}
56
57int get_hwaddr(char *ifname, unsigned char *hwaddr)
58{
11904a35
SH
59 struct ifreq ifr;
60 memset(&ifr, 0, sizeof(ifr));
61 strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
62 if (ioctl(netsock, SIOCGIFHWADDR, &ifr) < 0) {
63 ERROR("%s: get hw address failed: %m", ifname);
64 return -1;
65 }
66 memcpy(hwaddr, ifr.ifr_hwaddr.sa_data, ETH_ALEN);
67 return 0;
ad02a0eb
SH
68}
69
70int ethtool_get_speed_duplex(char *ifname, int *speed, int *duplex)
71{
11904a35
SH
72 struct ifreq ifr;
73 memset(&ifr, 0, sizeof(ifr));
74 strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
75 struct ethtool_cmd ecmd;
76
77 ecmd.cmd = ETHTOOL_GSET;
78 ifr.ifr_data = (caddr_t) & ecmd;
79 if (ioctl(netsock, SIOCETHTOOL, &ifr) < 0) {
80 ERROR("Cannot get link status for %s: %m\n", ifname);
81 return -1;
82 }
83 *speed = ecmd.speed; /* Ethtool speed is in Mbps */
84 *duplex = ecmd.duplex; /* We have same convention as ethtool.
85 0 = half, 1 = full */
86 return 0;
ad02a0eb
SH
87}
88
ad02a0eb
SH
89/********* Sysfs based utility functions *************/
90
91/* This sysfs stuff might break with interface renames */
92int is_bridge(char *if_name)
93{
11904a35
SH
94 char path[32 + IFNAMSIZ];
95 sprintf(path, "/sys/class/net/%s/bridge", if_name);
96 return (access(path, R_OK) == 0);
ad02a0eb
SH
97}
98
99/* This will work even less if the bridge port is renamed after being
100 joined to the bridge.
101*/
102int is_bridge_slave(char *br_name, char *if_name)
103{
11904a35
SH
104 char path[32 + 2 * IFNAMSIZ];
105 sprintf(path, "/sys/class/net/%s/brif/%s", br_name, if_name);
106 return (access(path, R_OK) == 0);
ad02a0eb
SH
107}
108
109int get_bridge_portno(char *if_name)
110{
11904a35
SH
111 char path[32 + IFNAMSIZ];
112 sprintf(path, "/sys/class/net/%s/brport/port_no", if_name);
113 char buf[128];
114 int fd;
115 long res = -1;
116 TSTM((fd = open(path, O_RDONLY)) >= 0, -1, "%m");
117 int l;
118 TSTM((l = read(fd, buf, sizeof(buf) - 1)) >= 0, -1, "%m");
119 if (l == 0) {
120 ERROR("Empty port index file");
121 goto out;
122 } else if (l == sizeof(buf) - 1) {
123 ERROR("port_index file too long");
124 goto out;
125 }
126 buf[l] = 0;
127 if (buf[l - 1] == '\n')
128 buf[l - 1] = 0;
129 char *end;
130 res = strtoul(buf, &end, 0);
131 if (*end != 0 || res > INT_MAX) {
132 ERROR("Invalid port index %s", buf);
133 res = -1;
134 }
135 out:
136 close(fd);
137 return res;
ad02a0eb 138}