Separate monitoring function plugin
[platform/core/connectivity/stc-manager.git] / src / helper / helper-nl.c
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "helper-nl.h"
18
19 #include <unistd.h>
20 #include <linux/rtnetlink.h>
21 #include <stdlib.h>
22 #include <string.h>
23
24 /**
25  * create_netlink(): Create netlink socket and returns it.
26  * Returns: Created socket on success and -1 on failure.
27  */
28 API int create_netlink(int protocol, uint32_t groups)
29 {
30         /**
31          * TODO it's one socket, in future make set of sockets
32          * unique for protocol and groups
33          */
34         int sock;
35         sock = socket(PF_NETLINK, SOCK_RAW, protocol);
36         if (sock < 0)
37                 return -EINVAL; //LCOV_EXCL_LINE
38
39         struct sockaddr_nl src_addr = { 0, };
40
41         src_addr.nl_family = AF_NETLINK;
42         src_addr.nl_groups = groups;
43
44         if (bind(sock, (struct sockaddr *)&src_addr, sizeof(src_addr)) < 0) {
45                 close(sock); //LCOV_EXCL_LINE
46                 return -1; //LCOV_EXCL_LINE
47         }
48
49         return sock;
50 }
51
52 void fill_attribute_list(struct rtattr **atb, const int max_len,
53                          struct rtattr *rt_na, int rt_len)
54 {
55         int i = 0;
56         while (RTA_OK(rt_na, rt_len)) {
57                 if (rt_na->rta_type <= max_len)
58                         atb[rt_na->rta_type] = rt_na;
59
60                 rt_na = RTA_NEXT(rt_na, rt_len);
61                 ++i;
62                 if (i >= max_len)
63                         break;
64         }
65 }
66
67 /* read netlink message from socket
68  * return opaque pointer to genl structure
69  */
70 API int read_netlink(int sock, void *buf, size_t len)
71 {
72         ssize_t ret;
73         struct sockaddr_nl addr;
74         struct iovec iov = {
75                 .iov_base       = buf,
76                 .iov_len        = len,
77         };
78         struct msghdr msg = {
79                 .msg_name       = &addr,
80                 .msg_namelen    = sizeof(struct sockaddr_nl),
81                 .msg_iov        = &iov,
82                 .msg_iovlen     = 1,
83                 .msg_control    = NULL,
84                 .msg_controllen = 0,
85                 .msg_flags      = 0,
86         };
87         ret = recvmsg(sock, &msg, 0);
88         if (ret == -1)
89                 return ret; //LCOV_EXCL_LINE
90
91         if (msg.msg_flags & MSG_TRUNC) {
92                 errno = ENOSPC; //LCOV_EXCL_LINE
93                 return -1; //LCOV_EXCL_LINE
94         }
95
96         if (msg.msg_namelen != sizeof(struct sockaddr_nl)) {
97                 errno = EINVAL; //LCOV_EXCL_LINE
98                 return -1; //LCOV_EXCL_LINE
99         }
100
101         return ret;
102 }