blob: 3a7b24bdd1a703118e6954e1200b66b2a7c3cc97 [file] [log] [blame]
liubin281ac462023-07-19 14:22:54 +08001/*
2* MBTK Network Interface control.
3*
4* Author : lb
5* Date : 2021/8/20 11:44:05
6*
7*/
8#include <stdio.h>
9#include <stdlib.h>
10#include <errno.h>
11//#include <net/if.h>
12#include <sys/socket.h>
13#include <netinet/in.h>
14#include <linux/if_ether.h>
15#include <linux/sockios.h>
16//#include <cutils/properties.h>
17#include <arpa/inet.h>
18#include <pthread.h>
19#include <linux/route.h>
20#include <sys/ioctl.h>
21#include <unistd.h>
22
23#include "mbtk_type.h"
24#include "mbtk_log.h"
25#include "mbtk_utils.h"
26#include "mbtk_ifc.h"
27
28#define IFNAMSIZ 16
29
30static int ifc_ctl_sock = -1;
31static pthread_mutex_t ifc_sock_mutex = PTHREAD_MUTEX_INITIALIZER;
32
33static void ifc_init_ifr(const char *name, struct ifreq *ifr)
34{
35 memset(ifr, 0, sizeof(struct ifreq));
36 strncpy(ifr->ifr_name, name, IFNAMSIZ);
37 ifr->ifr_name[IFNAMSIZ - 1] = 0;
38}
39
40static int ifc_set_flags(int sock, const char *name, unsigned set, unsigned clr)
41{
42 struct ifreq ifr;
43 ifc_init_ifr(name, &ifr);
44
45 if(ioctl(sock, SIOCGIFFLAGS, &ifr) < 0)
46 return -1;
47 ifr.ifr_flags = (ifr.ifr_flags & (~clr)) | set;
48 return ioctl(sock, SIOCSIFFLAGS, &ifr);
49}
50
51static void init_sockaddr_in(struct sockaddr *sa, in_addr_t addr)
52{
53 struct sockaddr_in *sin = (struct sockaddr_in *) sa;
54 sin->sin_family = AF_INET;
55 sin->sin_port = 0;
56 sin->sin_addr.s_addr = addr;
57}
58
59#if 1
60static const char *ipaddr_to_string(in_addr_t addr)
61{
62 struct in_addr in_addr;
63
64 in_addr.s_addr = addr;
65 return inet_ntoa(in_addr);
66}
67#endif
68
69static in_addr_t prefixLengthToIpv4Netmask(int prefix_length)
70{
71 in_addr_t mask = 0;
72
73 // C99 (6.5.7): shifts of 32 bits have undefined results
74 if (prefix_length <= 0 || prefix_length > 32)
75 {
76 return 0;
77 }
78
79 mask = ~mask << (32 - prefix_length);
80 mask = htonl(mask);
81
82 return mask;
83}
84
85#if 1
86static int ifc_set_prefixLength(const char *name, int prefixLength)
87{
88 struct ifreq ifr;
89 // TODO - support ipv6
90// if (prefixLength > 32 || prefixLength < 0) return -1;
91
92 in_addr_t mask = prefixLengthToIpv4Netmask(prefixLength);
93 ifc_init_ifr(name, &ifr);
94 init_sockaddr_in(&ifr.ifr_addr, mask);
95
96 return ioctl(ifc_ctl_sock, SIOCSIFNETMASK, &ifr);
97}
98#endif
99
100int ifc_act_on_ipv4_route(int action, const char *ifname, struct in_addr dst, int prefix_length,
101 struct in_addr gw)
102{
103 struct rtentry rt;
104 int result;
105 in_addr_t netmask;
106
107 memset(&rt, 0, sizeof(rt));
108
109 rt.rt_dst.sa_family = AF_INET;
110 rt.rt_dev = (void*) ifname;
111
112 netmask = prefixLengthToIpv4Netmask(prefix_length);
113 init_sockaddr_in(&rt.rt_genmask, netmask);
114 init_sockaddr_in(&rt.rt_dst, dst.s_addr);
115 rt.rt_flags = RTF_UP;
116
117 if (prefix_length == 32)
118 {
119 rt.rt_flags |= RTF_HOST;
120 }
121
122 if (gw.s_addr != 0)
123 {
124 rt.rt_flags |= RTF_GATEWAY;
125 init_sockaddr_in(&rt.rt_gateway, gw.s_addr);
126 }
127
128 result = ioctl(ifc_ctl_sock, action, &rt);
129 if (result < 0)
130 {
131 if (errno == EEXIST)
132 {
133 result = 0;
134 }
135 else
136 {
137 result = -errno;
138 }
139 }
140 return result;
141}
142
143static int ifc_create_default_route1(const char *name, in_addr_t gw)
144{
145 struct in_addr in_dst, in_gw;
146
147 in_dst.s_addr = 0;
148 in_gw.s_addr = gw;
149
150 int ret = ifc_act_on_ipv4_route(SIOCADDRT, name, in_dst, 0, in_gw);
151 LOGD("ifc_create_default_route(%s, %d) = %d", name, gw, ret);
152 return ret;
153}
154
b.liu9e8584b2024-11-06 19:21:28 +0800155#if 0
liubin281ac462023-07-19 14:22:54 +0800156/* deprecated - v4 only */
157static int ifc_create_default_route2(const char *name, const char *gw)
158{
159 struct in_addr in_dst, in_gw;
160
161 in_dst.s_addr = 0;
162 if(gw == NULL)
163 {
164 in_gw.s_addr = 0;
165 }
166 else
167 {
168 if(inet_aton(gw,(struct in_addr *)&(in_gw.s_addr)) < 0)
169 {
170 LOGE("inet_aton error.");
171 return -1;
172 }
173 }
174
175 int ret = ifc_act_on_ipv4_route(SIOCADDRT, name, in_dst, 0, in_gw);
176 LOGD("ifc_create_default_route(%s) = %d", name, ret);
177 return ret;
178}
b.liu9e8584b2024-11-06 19:21:28 +0800179#endif
liubin281ac462023-07-19 14:22:54 +0800180
181int mbtk_ifc_open(void)
182{
183 pthread_mutex_lock(&ifc_sock_mutex);
184 if (ifc_ctl_sock == -1)
185 {
186 ifc_ctl_sock = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
187 if (ifc_ctl_sock < 0)
188 {
189 LOGE("socket() failed: %s\n", strerror(errno));
190 }
191 }
192
193 return ifc_ctl_sock < 0 ? -1 : 0;
194}
195
196int mbtk_ifc_close(void)
197{
198 if (ifc_ctl_sock != -1)
199 {
200 (void)close(ifc_ctl_sock);
201 ifc_ctl_sock = -1;
202 }
203 pthread_mutex_unlock(&ifc_sock_mutex);
204
205 return 0;
206}
207
208int mbtk_ifc_set_addr(const char *name, in_addr_t addr, in_addr_t netmask)
209{
210 struct ifreq ifr, irf_mask;
211 int ret;
212
213 ifc_init_ifr(name, &ifr);
214 init_sockaddr_in(&ifr.ifr_addr, addr);
215
216 ret = ioctl(ifc_ctl_sock, SIOCSIFADDR, &ifr);
217 if(ret)
218 {
219 LOGD("set_addr(%s, %x) = %d fail.", name, addr, ret);
220 }
221
222 if(netmask)
223 {
224 ifc_init_ifr(name, &irf_mask);
225 init_sockaddr_in(&irf_mask.ifr_netmask, netmask);
226 ret = ioctl(ifc_ctl_sock, SIOCSIFNETMASK, &irf_mask);
227 if(ret)
228 {
229 LOGD("set_netmask(%s, %x) = %d fail.", name, netmask, ret);
230 }
231 }
232
233 return ret;
234}
235
236int mbtk_ifc_ip_config(const char *ifname, const char *ipv4, const char *mask, const char *gateway)
237{
238 UNUSED(gateway);
239 struct ifreq ifr;
240
241// struct rtentry rt;
242 // Set IPv4
243 struct sockaddr_in *sin;
244 memset(&ifr,0,sizeof(ifr));
245 strcpy(ifr.ifr_name,ifname);
246 sin = (struct sockaddr_in*)&ifr.ifr_addr;
247 sin->sin_family = AF_INET;
248 if(ipv4) {
249 if(inet_aton(ipv4,&(sin->sin_addr)) < 0)
250 {
251 LOGE("inet_aton error.");
252 return -2;
253 }
254 } else {
255 memset(&(sin->sin_addr), 0, sizeof(struct in_addr));
256 }
257
258 if(ioctl(ifc_ctl_sock,SIOCSIFADDR,&ifr) < 0)
259 {
260 LOGE("ioctl SIOCSIFADDR error.");
261 return -3;
262 }
263
264#if 1
265#if 1
266 //netmask
267 if(mask) {
268 if(inet_aton(mask,&(sin->sin_addr)) < 0)
269 {
270 LOGE("inet_pton error.");
271 return -4;
272 }
273
274 if(ioctl(ifc_ctl_sock, SIOCSIFNETMASK, &ifr) < 0)
275 {
276 LOGE("ioctl error.");
277 return -5;
278 }
279 }
280#else
281
282 //struct ifreq ifr;
283 //strcpy(ifr.ifr_name, interface_name);
284 struct sockaddr_in netmask_addr;
285 bzero(&netmask_addr, sizeof(struct sockaddr_in));
286 netmask_addr.sin_family = PF_INET;
287 inet_aton(mask, &netmask_addr.sin_addr);
288 memcpy(&ifr.ifr_ifru.ifru_netmask, &netmask_addr,
289 sizeof(struct sockaddr_in));
290 if (ioctl(ifc_ctl_sock, SIOCSIFNETMASK, &ifr) < 0)
291 {
292 LOGE("ioctl() fail.");
293 return -1;
294 }
295#endif
296#endif
297
298#if 0
299 //gateway
300 memset(&rt, 0, sizeof(struct rtentry));
301 memset(sin, 0, sizeof(struct sockaddr_in));
302 sin->sin_family = AF_INET;
303 sin->sin_port = 0;
304 if(inet_aton(gateway, &sin->sin_addr)<0)
305 {
306 LOGE( "inet_aton error." );
307 }
308 memcpy ( &rt.rt_gateway, sin, sizeof(struct sockaddr_in));
309 ((struct sockaddr_in *)&rt.rt_dst)->sin_family=AF_INET;
310 ((struct sockaddr_in *)&rt.rt_genmask)->sin_family=AF_INET;
311 rt.rt_flags = RTF_GATEWAY;
312 if (ioctl(ifc_ctl_sock, SIOCADDRT, &rt)<0)
313 {
314 LOGE("ioctl(SIOCADDRT) error in set_default_route\n");
315 return -1;
316 }
317#endif
318 return 0;
319}
320
321int mbtk_ifc_set_netmask(const char *ifname, const char *netmask)
322{
323 int s;
324 if ((s = socket(PF_INET, SOCK_STREAM, 0)) < 0)
325 {
326 LOGE("Socket");
327 return -1;
328 }
329 struct ifreq ifr;
330 strcpy(ifr.ifr_name, ifname);
331 struct sockaddr_in netmask_addr;
332 bzero(&netmask_addr, sizeof(struct sockaddr_in));
333 netmask_addr.sin_family = PF_INET;
334 inet_aton(netmask, &netmask_addr.sin_addr);
335 memcpy(&ifr.ifr_ifru.ifru_netmask, &netmask_addr,
336 sizeof(struct sockaddr_in));
337 if (ioctl(s, SIOCSIFNETMASK, &ifr) < 0)
338 {
339 LOGE("ioctl");
340 close(s);
341 return -1;
342 }
343 close(s);
344 return 0;
345}
346
347
348int mbtk_ifc_get_addr(const char *name, void *addr)
349{
350 int ret;
351 struct ifreq ifr;
352 ifc_init_ifr(name, &ifr);
353
354 ret = ioctl(ifc_ctl_sock, SIOCGIFADDR, &ifr);
355 LOGD("ifc_get_addr(%s, %x) = %d", name, ifr.ifr_addr, ret);
356 if(ret < 0) return -1;
357
358 memcpy(addr, &ifr.ifr_addr, sizeof(struct sockaddr));
359 return 0;
360}
361
362
363int mbtk_ifc_up(const char *name)
364{
365 int ret = ifc_set_flags(ifc_ctl_sock, name, IFF_UP, 0);
366// LOGI("mbtk_ifc_up(%s) = %d", name, ret);
367 return ret;
368}
369
370int mbtk_ifc_down(const char *name)
371{
372 int ret = ifc_set_flags(ifc_ctl_sock, name, 0, IFF_UP);
373// LOGI("mbtk_ifc_down(%s) = %d", name, ret);
374 return ret;
375}
376
377int mbtk_ifc_get_hwaddr(const char *name, void *ptr)
378{
379 int r;
380 struct ifreq ifr;
381 ifc_init_ifr(name, &ifr);
382
383 r = ioctl(ifc_ctl_sock, SIOCGIFHWADDR, &ifr);
384 if(r < 0) return -1;
385
386 memcpy(ptr, &ifr.ifr_hwaddr.sa_data, ETH_ALEN);
387 return 0;
388}
389
390int mbtk_ifc_get_ifindex(const char *name, int *if_indexp)
391{
392 int r;
393 struct ifreq ifr;
394 ifc_init_ifr(name, &ifr);
395
396 r = ioctl(ifc_ctl_sock, SIOCGIFINDEX, &ifr);
397 if(r < 0) return -1;
398
399 *if_indexp = ifr.ifr_ifindex;
400 return 0;
401}
402
403int mbtk_ifc_configure1(const char *ifname,
404 in_addr_t address,
405 uint32_t prefixLength,
406 in_addr_t gateway,
407 in_addr_t netmask)
408{
409 if(mbtk_ifc_open())
410 {
411 LOGE("mbtk_ifc_open() fail.", strerror(errno));
412 return -1;
413 }
414
415 if (mbtk_ifc_up(ifname))
416 {
417 LOGE("failed to turn on interface %s: %s", ifname, strerror(errno));
418 mbtk_ifc_close();
419 return -1;
420 }
421 if (mbtk_ifc_set_addr(ifname, address, netmask))
422 {
423 LOGE("failed to set ipaddr %s: %s", ipaddr_to_string(address), strerror(errno));
424 mbtk_ifc_close();
425 return -1;
426 }
427 if (ifc_set_prefixLength(ifname, prefixLength))
428 {
429 LOGE("failed to set prefixLength %d: %s", prefixLength, strerror(errno));
430 mbtk_ifc_close();
431 return -1;
432 }
433 if (ifc_create_default_route1(ifname, gateway))
434 {
435 LOGE("failed to set default route %s: %s", ipaddr_to_string(gateway), strerror(errno));
436 mbtk_ifc_close();
437 return -1;
438 }
439
440 mbtk_ifc_close();
441 return 0;
442}
443
444int mbtk_ifc_configure2(const char *ifname,
445 const char *ipv4,
446 uint32_t prefixLength,
447 const char *gateway,
448 const char *netmask)
449{
450 if(mbtk_ifc_open())
451 {
452 LOGE("mbtk_ifc_open() fail.", strerror(errno));
453 return -1;
454 }
455
456 if(ipv4 == NULL) {
457 if (mbtk_ifc_down(ifname))
458 {
459 LOGE("failed to turn off interface %s: %s", ifname, strerror(errno));
460 mbtk_ifc_close();
461 return -1;
462 }
463 } else {
464 if (mbtk_ifc_up(ifname))
465 {
466 LOGE("failed to turn on interface %s: %s", ifname, strerror(errno));
467 mbtk_ifc_close();
468 return -1;
469 }
470 }
471
472 if (mbtk_ifc_ip_config(ifname, ipv4, netmask, gateway))
473 {
474 LOGE("failed to set ipaddr: %s", strerror(errno));
475 mbtk_ifc_close();
476 return -1;
477 }
478
479// mbtk_ifc_set_netmask(ifname, netmask);
480
481#if 0
482 if (ifc_set_prefixLength(ifname, prefixLength))
483 {
484 LOGE("failed to set prefixLength %d: %s", prefixLength, strerror(errno));
485 mbtk_ifc_close();
486 return -1;
487 }
488#endif
489
490#if 0
491 if (ifc_create_default_route2(ifname, gateway))
492 {
493 LOGE("failed to set default route: %s", strerror(errno));
494 mbtk_ifc_close();
495 return -1;
496 }
497#endif
498
499 mbtk_ifc_close();
500
501 return 0;
502}
503
504struct in6_ifreq {
505 struct in6_addr addr;
506 uint32_t prefixlen;
507 unsigned int ifindex;
508};
509
510int mbtk_ipv6_config(const char *ifname, const char *ipv6, uint32_t prefixLength)
511{
512 struct ifreq ifr;
513 struct in6_ifreq ifr6;
514 int sockfd;
515 int err = 0;
516
517 // Create IPv6 socket to perform the ioctl operations on
518 sockfd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_IP);
519 if(sockfd < 0) {
520 LOGE("socket() fail.[%d]", errno);
521 return -1;
522 }
523
524 if(ipv6) {
525 if(ifc_set_flags(sockfd, ifname, IFF_UP, 0) < 0) {
526 LOGE("if up fail[%d].", errno);
527 err = -1;
528 goto exit;
529 }
530
531 // Copy the interface name to the ifreq struct
532 strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
533 // Get the ifrindex of the interface
534 if(ioctl(sockfd, SIOGIFINDEX, &ifr) < 0)
535 {
536 LOGE("ioctl SIOGIFINDEX error.");
537 err = -1;
538 goto exit;
539 }
540
541 // Prepare the in6_ifreq struct and set the address to the interface
542 if(inet_pton(AF_INET6, ipv6, &ifr6.addr) < 0) {
543 LOGE("inet_pton() fail[%d].", errno);
544 err = -1;
545 goto exit;
546 }
547 } else {
548 if(ifc_set_flags(sockfd, ifname, 0, IFF_UP) < 0) {
549 LOGE("if down fail[%d].", errno);
550 err = -1;
551 goto exit;
552 }
553
554 // Copy the interface name to the ifreq struct
555 strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
556 // Get the ifrindex of the interface
557 if(ioctl(sockfd, SIOGIFINDEX, &ifr) < 0)
558 {
559 LOGE("ioctl SIOGIFINDEX error.");
560 err = -1;
561 goto exit;
562 }
563
564 // Set IPv6 to 0.
565 memset(&(ifr6.addr), 0, sizeof(struct in6_addr));
566 }
567 ifr6.ifindex = ifr.ifr_ifindex;
568 ifr6.prefixlen = prefixLength;
569 if(ioctl(sockfd, SIOCSIFADDR, &ifr6) < 0) {
570 LOGE("ioctl SIOCSIFADDR error.");
571 err = -1;
572 goto exit;
573 }
574
575 LOGD("Set IPv6 : %s success.", ipv6);
576exit:
b.liu9e8584b2024-11-06 19:21:28 +0800577 mbtk_close(sockfd);
liubin281ac462023-07-19 14:22:54 +0800578 return err;
579}