blob: 51267f583818eb18434a1a4744757640cc91eddc [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
155/* deprecated - v4 only */
156static int ifc_create_default_route2(const char *name, const char *gw)
157{
158 struct in_addr in_dst, in_gw;
159
160 in_dst.s_addr = 0;
161 if(gw == NULL)
162 {
163 in_gw.s_addr = 0;
164 }
165 else
166 {
167 if(inet_aton(gw,(struct in_addr *)&(in_gw.s_addr)) < 0)
168 {
169 LOGE("inet_aton error.");
170 return -1;
171 }
172 }
173
174 int ret = ifc_act_on_ipv4_route(SIOCADDRT, name, in_dst, 0, in_gw);
175 LOGD("ifc_create_default_route(%s) = %d", name, ret);
176 return ret;
177}
178
179int mbtk_ifc_open(void)
180{
181 pthread_mutex_lock(&ifc_sock_mutex);
182 if (ifc_ctl_sock == -1)
183 {
184 ifc_ctl_sock = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
185 if (ifc_ctl_sock < 0)
186 {
187 LOGE("socket() failed: %s\n", strerror(errno));
188 }
189 }
190
191 return ifc_ctl_sock < 0 ? -1 : 0;
192}
193
194int mbtk_ifc_close(void)
195{
196 if (ifc_ctl_sock != -1)
197 {
198 (void)close(ifc_ctl_sock);
199 ifc_ctl_sock = -1;
200 }
201 pthread_mutex_unlock(&ifc_sock_mutex);
202
203 return 0;
204}
205
206int mbtk_ifc_set_addr(const char *name, in_addr_t addr, in_addr_t netmask)
207{
208 struct ifreq ifr, irf_mask;
209 int ret;
210
211 ifc_init_ifr(name, &ifr);
212 init_sockaddr_in(&ifr.ifr_addr, addr);
213
214 ret = ioctl(ifc_ctl_sock, SIOCSIFADDR, &ifr);
215 if(ret)
216 {
217 LOGD("set_addr(%s, %x) = %d fail.", name, addr, ret);
218 }
219
220 if(netmask)
221 {
222 ifc_init_ifr(name, &irf_mask);
223 init_sockaddr_in(&irf_mask.ifr_netmask, netmask);
224 ret = ioctl(ifc_ctl_sock, SIOCSIFNETMASK, &irf_mask);
225 if(ret)
226 {
227 LOGD("set_netmask(%s, %x) = %d fail.", name, netmask, ret);
228 }
229 }
230
231 return ret;
232}
233
234int mbtk_ifc_ip_config(const char *ifname, const char *ipv4, const char *mask, const char *gateway)
235{
236 UNUSED(gateway);
237 struct ifreq ifr;
238
239// struct rtentry rt;
240 // Set IPv4
241 struct sockaddr_in *sin;
242 memset(&ifr,0,sizeof(ifr));
243 strcpy(ifr.ifr_name,ifname);
244 sin = (struct sockaddr_in*)&ifr.ifr_addr;
245 sin->sin_family = AF_INET;
246 if(ipv4) {
247 if(inet_aton(ipv4,&(sin->sin_addr)) < 0)
248 {
249 LOGE("inet_aton error.");
250 return -2;
251 }
252 } else {
253 memset(&(sin->sin_addr), 0, sizeof(struct in_addr));
254 }
255
256 if(ioctl(ifc_ctl_sock,SIOCSIFADDR,&ifr) < 0)
257 {
258 LOGE("ioctl SIOCSIFADDR error.");
259 return -3;
260 }
261
262#if 1
263#if 1
264 //netmask
265 if(mask) {
266 if(inet_aton(mask,&(sin->sin_addr)) < 0)
267 {
268 LOGE("inet_pton error.");
269 return -4;
270 }
271
272 if(ioctl(ifc_ctl_sock, SIOCSIFNETMASK, &ifr) < 0)
273 {
274 LOGE("ioctl error.");
275 return -5;
276 }
277 }
278#else
279
280 //struct ifreq ifr;
281 //strcpy(ifr.ifr_name, interface_name);
282 struct sockaddr_in netmask_addr;
283 bzero(&netmask_addr, sizeof(struct sockaddr_in));
284 netmask_addr.sin_family = PF_INET;
285 inet_aton(mask, &netmask_addr.sin_addr);
286 memcpy(&ifr.ifr_ifru.ifru_netmask, &netmask_addr,
287 sizeof(struct sockaddr_in));
288 if (ioctl(ifc_ctl_sock, SIOCSIFNETMASK, &ifr) < 0)
289 {
290 LOGE("ioctl() fail.");
291 return -1;
292 }
293#endif
294#endif
295
296#if 0
297 //gateway
298 memset(&rt, 0, sizeof(struct rtentry));
299 memset(sin, 0, sizeof(struct sockaddr_in));
300 sin->sin_family = AF_INET;
301 sin->sin_port = 0;
302 if(inet_aton(gateway, &sin->sin_addr)<0)
303 {
304 LOGE( "inet_aton error." );
305 }
306 memcpy ( &rt.rt_gateway, sin, sizeof(struct sockaddr_in));
307 ((struct sockaddr_in *)&rt.rt_dst)->sin_family=AF_INET;
308 ((struct sockaddr_in *)&rt.rt_genmask)->sin_family=AF_INET;
309 rt.rt_flags = RTF_GATEWAY;
310 if (ioctl(ifc_ctl_sock, SIOCADDRT, &rt)<0)
311 {
312 LOGE("ioctl(SIOCADDRT) error in set_default_route\n");
313 return -1;
314 }
315#endif
316 return 0;
317}
318
319int mbtk_ifc_set_netmask(const char *ifname, const char *netmask)
320{
321 int s;
322 if ((s = socket(PF_INET, SOCK_STREAM, 0)) < 0)
323 {
324 LOGE("Socket");
325 return -1;
326 }
327 struct ifreq ifr;
328 strcpy(ifr.ifr_name, ifname);
329 struct sockaddr_in netmask_addr;
330 bzero(&netmask_addr, sizeof(struct sockaddr_in));
331 netmask_addr.sin_family = PF_INET;
332 inet_aton(netmask, &netmask_addr.sin_addr);
333 memcpy(&ifr.ifr_ifru.ifru_netmask, &netmask_addr,
334 sizeof(struct sockaddr_in));
335 if (ioctl(s, SIOCSIFNETMASK, &ifr) < 0)
336 {
337 LOGE("ioctl");
338 close(s);
339 return -1;
340 }
341 close(s);
342 return 0;
343}
344
345
346int mbtk_ifc_get_addr(const char *name, void *addr)
347{
348 int ret;
349 struct ifreq ifr;
350 ifc_init_ifr(name, &ifr);
351
352 ret = ioctl(ifc_ctl_sock, SIOCGIFADDR, &ifr);
353 LOGD("ifc_get_addr(%s, %x) = %d", name, ifr.ifr_addr, ret);
354 if(ret < 0) return -1;
355
356 memcpy(addr, &ifr.ifr_addr, sizeof(struct sockaddr));
357 return 0;
358}
359
360
361int mbtk_ifc_up(const char *name)
362{
363 int ret = ifc_set_flags(ifc_ctl_sock, name, IFF_UP, 0);
364// LOGI("mbtk_ifc_up(%s) = %d", name, ret);
365 return ret;
366}
367
368int mbtk_ifc_down(const char *name)
369{
370 int ret = ifc_set_flags(ifc_ctl_sock, name, 0, IFF_UP);
371// LOGI("mbtk_ifc_down(%s) = %d", name, ret);
372 return ret;
373}
374
375int mbtk_ifc_get_hwaddr(const char *name, void *ptr)
376{
377 int r;
378 struct ifreq ifr;
379 ifc_init_ifr(name, &ifr);
380
381 r = ioctl(ifc_ctl_sock, SIOCGIFHWADDR, &ifr);
382 if(r < 0) return -1;
383
384 memcpy(ptr, &ifr.ifr_hwaddr.sa_data, ETH_ALEN);
385 return 0;
386}
387
388int mbtk_ifc_get_ifindex(const char *name, int *if_indexp)
389{
390 int r;
391 struct ifreq ifr;
392 ifc_init_ifr(name, &ifr);
393
394 r = ioctl(ifc_ctl_sock, SIOCGIFINDEX, &ifr);
395 if(r < 0) return -1;
396
397 *if_indexp = ifr.ifr_ifindex;
398 return 0;
399}
400
401int mbtk_ifc_configure1(const char *ifname,
402 in_addr_t address,
403 uint32_t prefixLength,
404 in_addr_t gateway,
405 in_addr_t netmask)
406{
407 if(mbtk_ifc_open())
408 {
409 LOGE("mbtk_ifc_open() fail.", strerror(errno));
410 return -1;
411 }
412
413 if (mbtk_ifc_up(ifname))
414 {
415 LOGE("failed to turn on interface %s: %s", ifname, strerror(errno));
416 mbtk_ifc_close();
417 return -1;
418 }
419 if (mbtk_ifc_set_addr(ifname, address, netmask))
420 {
421 LOGE("failed to set ipaddr %s: %s", ipaddr_to_string(address), strerror(errno));
422 mbtk_ifc_close();
423 return -1;
424 }
425 if (ifc_set_prefixLength(ifname, prefixLength))
426 {
427 LOGE("failed to set prefixLength %d: %s", prefixLength, strerror(errno));
428 mbtk_ifc_close();
429 return -1;
430 }
431 if (ifc_create_default_route1(ifname, gateway))
432 {
433 LOGE("failed to set default route %s: %s", ipaddr_to_string(gateway), strerror(errno));
434 mbtk_ifc_close();
435 return -1;
436 }
437
438 mbtk_ifc_close();
439 return 0;
440}
441
442int mbtk_ifc_configure2(const char *ifname,
443 const char *ipv4,
444 uint32_t prefixLength,
445 const char *gateway,
446 const char *netmask)
447{
448 if(mbtk_ifc_open())
449 {
450 LOGE("mbtk_ifc_open() fail.", strerror(errno));
451 return -1;
452 }
453
454 if(ipv4 == NULL) {
455 if (mbtk_ifc_down(ifname))
456 {
457 LOGE("failed to turn off interface %s: %s", ifname, strerror(errno));
458 mbtk_ifc_close();
459 return -1;
460 }
461 } else {
462 if (mbtk_ifc_up(ifname))
463 {
464 LOGE("failed to turn on interface %s: %s", ifname, strerror(errno));
465 mbtk_ifc_close();
466 return -1;
467 }
468 }
469
470 if (mbtk_ifc_ip_config(ifname, ipv4, netmask, gateway))
471 {
472 LOGE("failed to set ipaddr: %s", strerror(errno));
473 mbtk_ifc_close();
474 return -1;
475 }
476
477// mbtk_ifc_set_netmask(ifname, netmask);
478
479#if 0
480 if (ifc_set_prefixLength(ifname, prefixLength))
481 {
482 LOGE("failed to set prefixLength %d: %s", prefixLength, strerror(errno));
483 mbtk_ifc_close();
484 return -1;
485 }
486#endif
487
488#if 0
489 if (ifc_create_default_route2(ifname, gateway))
490 {
491 LOGE("failed to set default route: %s", strerror(errno));
492 mbtk_ifc_close();
493 return -1;
494 }
495#endif
496
497 mbtk_ifc_close();
498
499 return 0;
500}
501
502struct in6_ifreq {
503 struct in6_addr addr;
504 uint32_t prefixlen;
505 unsigned int ifindex;
506};
507
508int mbtk_ipv6_config(const char *ifname, const char *ipv6, uint32_t prefixLength)
509{
510 struct ifreq ifr;
511 struct in6_ifreq ifr6;
512 int sockfd;
513 int err = 0;
514
515 // Create IPv6 socket to perform the ioctl operations on
516 sockfd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_IP);
517 if(sockfd < 0) {
518 LOGE("socket() fail.[%d]", errno);
519 return -1;
520 }
521
522 if(ipv6) {
523 if(ifc_set_flags(sockfd, ifname, IFF_UP, 0) < 0) {
524 LOGE("if up fail[%d].", errno);
525 err = -1;
526 goto exit;
527 }
528
529 // Copy the interface name to the ifreq struct
530 strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
531 // Get the ifrindex of the interface
532 if(ioctl(sockfd, SIOGIFINDEX, &ifr) < 0)
533 {
534 LOGE("ioctl SIOGIFINDEX error.");
535 err = -1;
536 goto exit;
537 }
538
539 // Prepare the in6_ifreq struct and set the address to the interface
540 if(inet_pton(AF_INET6, ipv6, &ifr6.addr) < 0) {
541 LOGE("inet_pton() fail[%d].", errno);
542 err = -1;
543 goto exit;
544 }
545 } else {
546 if(ifc_set_flags(sockfd, ifname, 0, IFF_UP) < 0) {
547 LOGE("if down fail[%d].", errno);
548 err = -1;
549 goto exit;
550 }
551
552 // Copy the interface name to the ifreq struct
553 strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
554 // Get the ifrindex of the interface
555 if(ioctl(sockfd, SIOGIFINDEX, &ifr) < 0)
556 {
557 LOGE("ioctl SIOGIFINDEX error.");
558 err = -1;
559 goto exit;
560 }
561
562 // Set IPv6 to 0.
563 memset(&(ifr6.addr), 0, sizeof(struct in6_addr));
564 }
565 ifr6.ifindex = ifr.ifr_ifindex;
566 ifr6.prefixlen = prefixLength;
567 if(ioctl(sockfd, SIOCSIFADDR, &ifr6) < 0) {
568 LOGE("ioctl SIOCSIFADDR error.");
569 err = -1;
570 goto exit;
571 }
572
573 LOGD("Set IPv6 : %s success.", ipv6);
574exit:
575 close(socket);
576 return err;
577}