aboutsummaryrefslogtreecommitdiffstats
path: root/src/fnet/interface.c
diff options
context:
space:
mode:
authorLibravatar netblue30 <netblue30@yahoo.com>2016-10-30 15:54:05 -0400
committerLibravatar netblue30 <netblue30@yahoo.com>2016-10-30 15:54:05 -0400
commitf898290fd79e0e64d13ceef56fc5960da879d179 (patch)
tree7112345d8121d1d61f90995e09754bbfbfbf467f /src/fnet/interface.c
parentMerge pull request #878 from msva/patch-1 (diff)
downloadfirejail-f898290fd79e0e64d13ceef56fc5960da879d179.tar.gz
firejail-f898290fd79e0e64d13ceef56fc5960da879d179.tar.zst
firejail-f898290fd79e0e64d13ceef56fc5960da879d179.zip
major cleanup
Diffstat (limited to 'src/fnet/interface.c')
-rw-r--r--src/fnet/interface.c212
1 files changed, 212 insertions, 0 deletions
diff --git a/src/fnet/interface.c b/src/fnet/interface.c
index b1903dd46..67af062bf 100644
--- a/src/fnet/interface.c
+++ b/src/fnet/interface.c
@@ -180,4 +180,216 @@ void net_set_mtu(const char *ifname, int mtu) {
180 close(s); 180 close(s);
181} 181}
182 182
183// scan interfaces in current namespace and print IP address/mask for each interface
184void net_ifprint(int scan) {
185 uint32_t ip;
186 uint32_t mask;
187 struct ifaddrs *ifaddr, *ifa;
183 188
189 if (getifaddrs(&ifaddr) == -1)
190 errExit("getifaddrs");
191
192 printf("%-17.17s%-19.19s%-17.17s%-17.17s%-6.6s\n",
193 "Interface", "MAC", "IP", "Mask", "Status");
194 // walk through the linked list
195 for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
196 if (ifa->ifa_addr == NULL)
197 continue;
198
199 if (ifa->ifa_addr->sa_family == AF_INET) {
200 struct sockaddr_in *si = (struct sockaddr_in *) ifa->ifa_netmask;
201 mask = ntohl(si->sin_addr.s_addr);
202 si = (struct sockaddr_in *) ifa->ifa_addr;
203 ip = ntohl(si->sin_addr.s_addr);
204
205 // interface status
206 char *status;
207 if (ifa->ifa_flags & IFF_RUNNING && ifa->ifa_flags & IFF_UP)
208 status = "UP";
209 else
210 status = "DOWN";
211
212 // ip address and mask
213 char ipstr[30];
214 sprintf(ipstr, "%d.%d.%d.%d", PRINT_IP(ip));
215 char maskstr[30];
216 sprintf(maskstr, "%d.%d.%d.%d", PRINT_IP(mask));
217
218 // mac address
219 unsigned char mac[6];
220 net_get_mac(ifa->ifa_name, mac);
221 char macstr[30];
222 if (strcmp(ifa->ifa_name, "lo") == 0)
223 macstr[0] = '\0';
224 else
225 sprintf(macstr, "%02x:%02x:%02x:%02x:%02x:%02x", PRINT_MAC(mac));
226
227 // print
228 printf("%-17.17s%-19.19s%-17.17s%-17.17s%-6.6s\n",
229 ifa->ifa_name, macstr, ipstr, maskstr, status);
230
231 // network scanning
232 if (!scan) // scanning disabled
233 continue;
234 if (strcmp(ifa->ifa_name, "lo") == 0) // no loopbabck scanning
235 continue;
236 if (mask2bits(mask) < 16) // not scanning large networks
237 continue;
238 if (!ip) // if not configured
239 continue;
240 // only if the interface is up and running
241 if (ifa->ifa_flags & IFF_RUNNING && ifa->ifa_flags & IFF_UP)
242 arp_scan(ifa->ifa_name, ip, mask);
243 }
244 }
245 freeifaddrs(ifaddr);
246}
247
248int net_get_mac(const char *ifname, unsigned char mac[6]) {
249
250 struct ifreq ifr;
251 int sock;
252
253 if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
254 errExit("socket");
255
256 memset(&ifr, 0, sizeof(ifr));
257 strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
258 ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER;
259
260 if (ioctl(sock, SIOCGIFHWADDR, &ifr) == -1)
261 errExit("ioctl");
262 memcpy(mac, ifr.ifr_hwaddr.sa_data, 6);
263
264 close(sock);
265 return 0;
266}
267
268// configure interface ipv4 address
269void net_if_ip(const char *ifname, uint32_t ip, uint32_t mask, int mtu) {
270 if (strlen(ifname) > IFNAMSIZ) {
271 fprintf(stderr, "Error: invalid network device name %s\n", ifname);
272 exit(1);
273 }
274
275 int sock = socket(AF_INET,SOCK_DGRAM,0);
276 if (sock < 0)
277 errExit("socket");
278
279 struct ifreq ifr;
280 memset(&ifr, 0, sizeof(ifr));
281 strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
282 ifr.ifr_addr.sa_family = AF_INET;
283
284 ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr = htonl(ip);
285 if (ioctl( sock, SIOCSIFADDR, &ifr ) < 0) {
286 close(sock);
287 errExit("ioctl");
288 }
289
290 if (ip != 0) {
291 ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr = htonl(mask);
292 if (ioctl( sock, SIOCSIFNETMASK, &ifr ) < 0) {
293 close(sock);
294 errExit("ioctl");
295 }
296 }
297
298 // configure mtu
299 if (mtu > 0) {
300 ifr.ifr_mtu = mtu;
301 if (ioctl( sock, SIOCSIFMTU, &ifr ) < 0) {
302 close(sock);
303 errExit("ioctl");
304 }
305 }
306
307 close(sock);
308 usleep(10000); // sleep 10ms
309}
310
311int net_if_mac(const char *ifname, const unsigned char mac[6]) {
312 struct ifreq ifr;
313 int sock;
314
315 if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
316 errExit("socket");
317
318 memset(&ifr, 0, sizeof(ifr));
319 strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
320 ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER;
321 memcpy(ifr.ifr_hwaddr.sa_data, mac, 6);
322
323 if (ioctl(sock, SIOCSIFHWADDR, &ifr) == -1)
324 errExit("ioctl");
325 close(sock);
326 return 0;
327}
328
329// configure interface ipv6 address
330// ex: firejail --net=eth0 --ip6=2001:0db8:0:f101::1/64
331struct ifreq6 {
332 struct in6_addr ifr6_addr;
333 uint32_t ifr6_prefixlen;
334 unsigned int ifr6_ifindex;
335};
336void net_if_ip6(const char *ifname, const char *addr6) {
337 if (strchr(addr6, ':') == NULL) {
338 fprintf(stderr, "Error fnet: invalid IPv6 address %s\n", addr6);
339 exit(1);
340 }
341
342 // extract prefix
343 unsigned long prefix;
344 char *ptr;
345 if ((ptr = strchr(addr6, '/'))) {
346 prefix = atol(ptr + 1);
347 if (prefix > 128) {
348 fprintf(stderr, "Error fnet: invalid prefix for IPv6 address %s\n", addr6);
349 exit(1);
350 }
351 *ptr = '\0'; // mark the end of the address
352 }
353 else
354 prefix = 128;
355
356 // extract address
357 struct sockaddr_in6 sin6;
358 memset(&sin6, 0, sizeof(sin6));
359 sin6.sin6_family = AF_INET6;
360 int rv = inet_pton(AF_INET6, addr6, sin6.sin6_addr.s6_addr);
361 if (rv <= 0) {
362 fprintf(stderr, "Error fnet: invalid IPv6 address %s\n", addr6);
363 exit(1);
364 }
365
366 // open socket
367 int sock = socket(PF_INET6, SOCK_DGRAM, IPPROTO_IP);
368 if (sock < 0) {
369 fprintf(stderr, "Error fnet: IPv6 is not supported on this system\n");
370 exit(1);
371 }
372
373 // find interface index
374 struct ifreq ifr;
375 memset(&ifr, 0, sizeof(ifr));
376 strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
377 ifr.ifr_addr.sa_family = AF_INET;
378 if (ioctl(sock, SIOGIFINDEX, &ifr) < 0) {
379 perror("ioctl SIOGIFINDEX");
380 exit(1);
381 }
382
383 // configure address
384 struct ifreq6 ifr6;
385 memset(&ifr6, 0, sizeof(ifr6));
386 ifr6.ifr6_prefixlen = prefix;
387 ifr6.ifr6_ifindex = ifr.ifr_ifindex;
388 memcpy((char *) &ifr6.ifr6_addr, (char *) &sin6.sin6_addr, sizeof(struct in6_addr));
389 if (ioctl(sock, SIOCSIFADDR, &ifr6) < 0) {
390 perror("ioctl SIOCSIFADDR");
391 exit(1);
392 }
393
394 close(sock);
395}