Annotation of embedaddon/iftop/addrs_ioctl.c, revision 1.1.1.1
1.1 misho 1: /*
2: * addrs_ioctl.c:
3: *
4: * Provides the get_addrs_ioctl() function for use on systems that
5: * support a simple socket ioctl for acquiring low-level ethernet
6: * information about interfaces.
7: *
8: */
9:
10: #include <stdio.h>
11: #include <stdlib.h>
12: #include <unistd.h>
13: #include <string.h>
14:
15: #include <sys/types.h>
16: #include <sys/ioctl.h>
17: #include <sys/socket.h>
18: #include <net/if.h>
19: #include <netinet/in.h>
20:
21: #if defined __FreeBSD__ || defined __OpenBSD__ || defined __APPLE__
22: #include <sys/param.h>
23: #include <sys/sysctl.h>
24: #include <net/if_dl.h>
25: #endif
26:
27: #include "iftop.h"
28:
29: /*
30: * This function identifies the IP address and ethernet address for the requested
31: * interface
32: *
33: * This function returns -1 on catastrophic failure, or a bitwise OR of the
34: * following values:
35: *
36: * 1 - Was able to get the ethernet address
37: * 2 - Was able to get the IP address
38: *
39: * This function should return 3 if all information was found
40: */
41:
42: int
43: get_addrs_ioctl(char *interface, char if_hw_addr[], struct in_addr *if_ip_addr)
44: {
45: int s;
46: struct ifreq ifr = {};
47: int got_hw_addr = 0;
48: int got_ip_addr = 0;
49:
50: /* -- */
51:
52: s = socket(PF_INET, SOCK_DGRAM, 0); /* any sort of IP socket will do */
53:
54: if (s == -1) {
55: perror("socket");
56: return -1;
57: }
58:
59: fprintf(stderr,"interface: %s\n", interface);
60:
61: memset(if_hw_addr, 0, 6);
62: strncpy(ifr.ifr_name, interface, IFNAMSIZ);
63:
64: #ifdef SIOCGIFHWADDR
65: if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) {
66: fprintf(stderr, "Error getting hardware address for interface: %s\n", interface);
67: perror("ioctl(SIOCGIFHWADDR)");
68: }
69: else {
70: memcpy(if_hw_addr, ifr.ifr_hwaddr.sa_data, 6);
71: got_hw_addr = 1;
72: }
73: #else
74: #if defined __FreeBSD__ || defined __OpenBSD__ || defined __APPLE__
75: {
76: int sysctlparam[6] = {CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST, 0};
77: size_t needed = 0;
78: char *buf = NULL;
79: struct if_msghdr *msghdr = NULL;
80: sysctlparam[5] = if_nametoindex(interface);
81: if (sysctlparam[5] == 0) {
82: fprintf(stderr, "Error getting hardware address for interface: %s\n", interface);
83: goto ENDHWADDR;
84: }
85: if (sysctl(sysctlparam, 6, NULL, &needed, NULL, 0) < 0) {
86: fprintf(stderr, "Error getting hardware address for interface: %s\n", interface);
87: goto ENDHWADDR;
88: }
89: if ((buf = malloc(needed)) == NULL) {
90: fprintf(stderr, "Error getting hardware address for interface: %s\n", interface);
91: goto ENDHWADDR;
92: }
93: if (sysctl(sysctlparam, 6, buf, &needed, NULL, 0) < 0) {
94: fprintf(stderr, "Error getting hardware address for interface: %s\n", interface);
95: free(buf);
96: goto ENDHWADDR;
97: }
98: msghdr = (struct if_msghdr *) buf;
99: memcpy(if_hw_addr, LLADDR((struct sockaddr_dl *)(buf + sizeof(struct if_msghdr) - sizeof(struct if_data) + sizeof(struct if_data))), 6);
100: free(buf);
101: got_hw_addr = 1;
102:
103: ENDHWADDR:
104: 1; /* compiler whines if there is a label at the end of a block...*/
105: }
106: #else
107: fprintf(stderr, "Cannot obtain hardware address on this platform\n");
108: #endif
109: #endif
110:
111: /* Get the IP address of the interface */
112: #ifdef SIOCGIFADDR
113: (*(struct sockaddr_in *) &ifr.ifr_addr).sin_family = AF_INET;
114: if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
115: fprintf(stderr, "Unable to get IP address for interface: %s\n", interface);
116: perror("ioctl(SIOCGIFADDR)");
117: }
118: else {
119: memcpy(if_ip_addr, &((*(struct sockaddr_in *) &ifr.ifr_addr).sin_addr), sizeof(struct in_addr));
120: got_ip_addr = 2;
121: }
122: #else
123: fprintf(stderr, "Cannot obtain IP address on this platform\n");
124: #endif
125:
126: close(s);
127:
128: return got_hw_addr + got_ip_addr;
129: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>