Lely core libraries  2.3.4
ifreq.h
Go to the documentation of this file.
1 
22 #ifndef LELY_IO2_INTERN_LINUX_IOCTL_H_
23 #define LELY_IO2_INTERN_LINUX_IOCTL_H_
24 
25 #include "io.h"
26 
27 #ifdef __linux__
28 
29 #include <assert.h>
30 #include <string.h>
31 
32 #include <net/if.h>
33 #include <sys/socket.h>
34 #include <unistd.h>
35 
36 #include <sys/ioctl.h>
37 
38 #ifndef LELY_IO_IFREQ_DOMAIN
39 #define LELY_IO_IFREQ_DOMAIN AF_UNIX
40 #endif
41 
42 #ifndef LELY_IO_IFREQ_TYPE
43 #define LELY_IO_IFREQ_TYPE SOCK_DGRAM
44 #endif
45 
46 #ifndef LELY_IO_IFREQ_PROTOCOL
47 #define LELY_IO_IFREQ_PROTOCOL 0
48 #endif
49 
50 struct ifr_handle {
51  int fd;
52  struct ifreq ifr;
53 };
54 
55 static int ifr_open(struct ifr_handle *ifh, const char *name);
56 static int ifr_close(struct ifr_handle *ifh);
57 
58 static int ifr_get_flags(const char *name);
59 static int ifr_set_flags(const char *name, int *flags, int mask);
60 
61 static inline int
62 ifr_open(struct ifr_handle *ifh, const char *name)
63 {
64  assert(ifh);
65  assert(name);
66 
67  ifh->fd = socket(LELY_IO_IFREQ_DOMAIN,
68  LELY_IO_IFREQ_TYPE | SOCK_CLOEXEC,
69  LELY_IO_IFREQ_PROTOCOL);
70  if (ifh->fd == -1)
71  return -1;
72 
73  memset(&ifh->ifr, 0, sizeof(ifh->ifr));
74  if (!memccpy(ifh->ifr.ifr_name, name, '\0', IFNAMSIZ))
75  ifh->ifr.ifr_name[IFNAMSIZ - 1] = '\0';
76 
77  return 0;
78 }
79 
80 static inline int
81 ifr_close(struct ifr_handle *ifh)
82 {
83  assert(ifh);
84 
85  int fd = ifh->fd;
86  ifh->fd = -1;
87  return close(fd);
88 }
89 
90 static inline int
91 ifr_get_flags(const char *name)
92 {
93  struct ifr_handle ifh;
94  if (ifr_open(&ifh, name) == -1)
95  return -1;
96 
97  int result = ioctl(ifh.fd, SIOCGIFFLAGS, &ifh.ifr) == -1
98  ? -1
99  : ifh.ifr.ifr_flags;
100  ifr_close(&ifh);
101  return result;
102 }
103 
104 static inline int
105 ifr_set_flags(const char *name, int *flags, int mask)
106 {
107  assert(flags);
108 
109  struct ifr_handle ifh;
110  if (ifr_open(&ifh, name) == -1)
111  return -1;
112 
113  int result = ioctl(ifh.fd, SIOCGIFFLAGS, &ifh.ifr);
114  if (!result) {
115  if ((ifh.ifr.ifr_flags ^ *flags) & mask) {
116  ifh.ifr.ifr_flags &= ~mask;
117  ifh.ifr.ifr_flags |= *flags & mask;
118  result = ioctl(ifh.fd, SIOCSIFFLAGS, &ifh.ifr);
119  }
120  if (!result)
121  *flags = ifh.ifr.ifr_flags;
122  }
123  ifr_close(&ifh);
124  return result;
125 }
126 
127 #endif // __linux__
128 
129 #endif // !LELY_IO2_INTERN_LINUX_IOCTL_H_
This is the internal header file of the Windows-specific I/O declarations.
This header file is part of the C11 and POSIX compatibility library; it includes <string....
This header file is part of the C11 and POSIX compatibility library; it includes <unistd....