xref: /f-stack/tools/libnetgraph/compat.c (revision d4a07e70)
1*d4a07e70Sfengbojiang /*
2*d4a07e70Sfengbojiang  * Copyright (C) 2017-2021 THL A29 Limited, a Tencent company.
3*d4a07e70Sfengbojiang  * All rights reserved.
4*d4a07e70Sfengbojiang  *
5*d4a07e70Sfengbojiang  * Redistribution and use in source and binary forms, with or without
6*d4a07e70Sfengbojiang  * modification, are permitted provided that the following conditions are met:
7*d4a07e70Sfengbojiang  *
8*d4a07e70Sfengbojiang  * 1. Redistributions of source code must retain the above copyright notice, this
9*d4a07e70Sfengbojiang  *   list of conditions and the following disclaimer.
10*d4a07e70Sfengbojiang  * 2. Redistributions in binary form must reproduce the above copyright notice,
11*d4a07e70Sfengbojiang  *   this list of conditions and the following disclaimer in the documentation
12*d4a07e70Sfengbojiang  *   and/or other materials provided with the distribution.
13*d4a07e70Sfengbojiang  *
14*d4a07e70Sfengbojiang  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
15*d4a07e70Sfengbojiang  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16*d4a07e70Sfengbojiang  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17*d4a07e70Sfengbojiang  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
18*d4a07e70Sfengbojiang  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19*d4a07e70Sfengbojiang  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20*d4a07e70Sfengbojiang  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21*d4a07e70Sfengbojiang  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22*d4a07e70Sfengbojiang  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23*d4a07e70Sfengbojiang  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24*d4a07e70Sfengbojiang  *
25*d4a07e70Sfengbojiang  *
26*d4a07e70Sfengbojiang  */
27*d4a07e70Sfengbojiang 
28*d4a07e70Sfengbojiang 
29*d4a07e70Sfengbojiang #include <sys/types.h>
30*d4a07e70Sfengbojiang #include <sys/socket.h>
31*d4a07e70Sfengbojiang #include <sys/sysproto.h>
32*d4a07e70Sfengbojiang #include <string.h>
33*d4a07e70Sfengbojiang 
34*d4a07e70Sfengbojiang #include "ff_api.h"
35*d4a07e70Sfengbojiang #include "ff_ipc.h"
36*d4a07e70Sfengbojiang #include "netgraph.h"
37*d4a07e70Sfengbojiang 
38*d4a07e70Sfengbojiang static int
ngctl(int cmd,void * data,size_t len)39*d4a07e70Sfengbojiang ngctl(int cmd, void *data, size_t len)
40*d4a07e70Sfengbojiang {
41*d4a07e70Sfengbojiang     struct ff_msg *msg, *retmsg = NULL;
42*d4a07e70Sfengbojiang 
43*d4a07e70Sfengbojiang     msg = ff_ipc_msg_alloc();
44*d4a07e70Sfengbojiang     if (msg == NULL) {
45*d4a07e70Sfengbojiang         errno = ENOMEM;
46*d4a07e70Sfengbojiang         return -1;
47*d4a07e70Sfengbojiang     }
48*d4a07e70Sfengbojiang 
49*d4a07e70Sfengbojiang     if (len > msg->buf_len) {
50*d4a07e70Sfengbojiang         errno = EINVAL;
51*d4a07e70Sfengbojiang         ff_ipc_msg_free(msg);
52*d4a07e70Sfengbojiang         return -1;
53*d4a07e70Sfengbojiang     }
54*d4a07e70Sfengbojiang 
55*d4a07e70Sfengbojiang     msg->msg_type = FF_NGCTL;
56*d4a07e70Sfengbojiang     msg->ngctl.cmd = cmd;
57*d4a07e70Sfengbojiang     msg->ngctl.data = msg->buf_addr;
58*d4a07e70Sfengbojiang 
59*d4a07e70Sfengbojiang     switch (cmd) {
60*d4a07e70Sfengbojiang         case NGCTL_SOCKET:
61*d4a07e70Sfengbojiang         case NGCTL_CLOSE:
62*d4a07e70Sfengbojiang             memcpy(msg->ngctl.data, data, len);
63*d4a07e70Sfengbojiang             break;
64*d4a07e70Sfengbojiang         case NGCTL_BIND:
65*d4a07e70Sfengbojiang         case NGCTL_CONNECT:
66*d4a07e70Sfengbojiang         {
67*d4a07e70Sfengbojiang             struct bind_args *src = (struct bind_args *)data;
68*d4a07e70Sfengbojiang             struct bind_args *dst = (struct bind_args *)(msg->ngctl.data);
69*d4a07e70Sfengbojiang             dst->s = src->s;
70*d4a07e70Sfengbojiang             dst->name = (char *)msg->buf_addr + sizeof(struct bind_args);
71*d4a07e70Sfengbojiang             dst->namelen = src->namelen;
72*d4a07e70Sfengbojiang             memcpy(dst->name, src->name, src->namelen);
73*d4a07e70Sfengbojiang             break;
74*d4a07e70Sfengbojiang         }
75*d4a07e70Sfengbojiang         case NGCTL_SEND:
76*d4a07e70Sfengbojiang         {
77*d4a07e70Sfengbojiang             struct sendto_args *src = (struct sendto_args *)data;
78*d4a07e70Sfengbojiang             struct sendto_args *dst = (struct sendto_args *)(msg->ngctl.data);
79*d4a07e70Sfengbojiang             dst->s = src->s;
80*d4a07e70Sfengbojiang             dst->buf = (char *)msg->buf_addr + sizeof(struct sendto_args);
81*d4a07e70Sfengbojiang             dst->len = src->len;
82*d4a07e70Sfengbojiang             dst->flags = src->flags;
83*d4a07e70Sfengbojiang             dst->to = dst->buf + src->len;
84*d4a07e70Sfengbojiang             dst->tolen = src->tolen;
85*d4a07e70Sfengbojiang             memcpy(dst->buf, src->buf, src->len);
86*d4a07e70Sfengbojiang             memcpy(dst->to, src->to, src->tolen);
87*d4a07e70Sfengbojiang             break;
88*d4a07e70Sfengbojiang         }
89*d4a07e70Sfengbojiang         case NGCTL_RECV:
90*d4a07e70Sfengbojiang         {
91*d4a07e70Sfengbojiang             struct recvfrom_args *src = (struct recvfrom_args *)data;
92*d4a07e70Sfengbojiang             struct recvfrom_args *dst = (struct recvfrom_args *)(msg->ngctl.data);
93*d4a07e70Sfengbojiang             dst->s = src->s;
94*d4a07e70Sfengbojiang             dst->buf = msg->buf_addr + sizeof(struct recvfrom_args);
95*d4a07e70Sfengbojiang             dst->len = src->len;
96*d4a07e70Sfengbojiang             dst->flags = src->flags;
97*d4a07e70Sfengbojiang             dst->from = (struct sockaddr *)dst->buf + src->len;
98*d4a07e70Sfengbojiang             dst->fromlenaddr = (socklen_t *)dst->buf + src->len + *(src->fromlenaddr);
99*d4a07e70Sfengbojiang             memcpy(dst->buf, src->buf, src->len);
100*d4a07e70Sfengbojiang             memcpy(dst->from, src->from, *(src->fromlenaddr));
101*d4a07e70Sfengbojiang             memcpy(dst->fromlenaddr, src->fromlenaddr, sizeof(socklen_t));
102*d4a07e70Sfengbojiang             break;
103*d4a07e70Sfengbojiang         }
104*d4a07e70Sfengbojiang         default:
105*d4a07e70Sfengbojiang             errno = EINVAL;
106*d4a07e70Sfengbojiang             ff_ipc_msg_free(msg);
107*d4a07e70Sfengbojiang             return -1;
108*d4a07e70Sfengbojiang     }
109*d4a07e70Sfengbojiang 
110*d4a07e70Sfengbojiang     int ret = ff_ipc_send(msg);
111*d4a07e70Sfengbojiang     if (ret < 0) {
112*d4a07e70Sfengbojiang         errno = EPIPE;
113*d4a07e70Sfengbojiang         ff_ipc_msg_free(msg);
114*d4a07e70Sfengbojiang         return -1;
115*d4a07e70Sfengbojiang     }
116*d4a07e70Sfengbojiang 
117*d4a07e70Sfengbojiang     do {
118*d4a07e70Sfengbojiang         if (retmsg != NULL) {
119*d4a07e70Sfengbojiang             ff_ipc_msg_free(retmsg);
120*d4a07e70Sfengbojiang         }
121*d4a07e70Sfengbojiang         ret = ff_ipc_recv(&retmsg, msg->msg_type);
122*d4a07e70Sfengbojiang         if (ret < 0) {
123*d4a07e70Sfengbojiang             errno = EPIPE;
124*d4a07e70Sfengbojiang             return -1;
125*d4a07e70Sfengbojiang         }
126*d4a07e70Sfengbojiang     } while (msg != retmsg);
127*d4a07e70Sfengbojiang 
128*d4a07e70Sfengbojiang     if (retmsg->result != 0) {
129*d4a07e70Sfengbojiang         ret = -1;
130*d4a07e70Sfengbojiang         errno = retmsg->result;
131*d4a07e70Sfengbojiang     } else {
132*d4a07e70Sfengbojiang         ret = msg->ngctl.ret;
133*d4a07e70Sfengbojiang 
134*d4a07e70Sfengbojiang         if (cmd == NGCTL_RECV) {
135*d4a07e70Sfengbojiang             struct recvfrom_args *dst = (struct recvfrom_args *)data;
136*d4a07e70Sfengbojiang             struct recvfrom_args *src = (struct recvfrom_args *)(msg->ngctl.data);
137*d4a07e70Sfengbojiang             memcpy(dst->buf, src->buf, src->len);
138*d4a07e70Sfengbojiang             memcpy(dst->from, src->from, *(src->fromlenaddr));
139*d4a07e70Sfengbojiang             memcpy(dst->fromlenaddr, src->fromlenaddr, sizeof(socklen_t));
140*d4a07e70Sfengbojiang         }
141*d4a07e70Sfengbojiang     }
142*d4a07e70Sfengbojiang 
143*d4a07e70Sfengbojiang     ff_ipc_msg_free(msg);
144*d4a07e70Sfengbojiang 
145*d4a07e70Sfengbojiang     return ret;
146*d4a07e70Sfengbojiang }
147*d4a07e70Sfengbojiang 
148*d4a07e70Sfengbojiang int
ng_socket(int domain,int type,int protocol)149*d4a07e70Sfengbojiang ng_socket(int domain, int type, int protocol)
150*d4a07e70Sfengbojiang {
151*d4a07e70Sfengbojiang     struct socket_args sa;
152*d4a07e70Sfengbojiang     sa.domain = domain;
153*d4a07e70Sfengbojiang     sa.type = type;
154*d4a07e70Sfengbojiang     sa.protocol = protocol;
155*d4a07e70Sfengbojiang 
156*d4a07e70Sfengbojiang     return ngctl(NGCTL_SOCKET, (void *)&sa, sizeof(sa));
157*d4a07e70Sfengbojiang }
158*d4a07e70Sfengbojiang 
159*d4a07e70Sfengbojiang int
ng_bind(int sockfd,const struct sockaddr * addr,socklen_t addrlen)160*d4a07e70Sfengbojiang ng_bind(int sockfd, const struct sockaddr *addr,
161*d4a07e70Sfengbojiang     socklen_t addrlen)
162*d4a07e70Sfengbojiang {
163*d4a07e70Sfengbojiang     size_t len;
164*d4a07e70Sfengbojiang     struct bind_args ba;
165*d4a07e70Sfengbojiang 
166*d4a07e70Sfengbojiang     ba.s = sockfd;
167*d4a07e70Sfengbojiang     ba.name = (char *)addr;
168*d4a07e70Sfengbojiang     ba.namelen = addrlen;
169*d4a07e70Sfengbojiang 
170*d4a07e70Sfengbojiang     len = sizeof(ba) + addrlen;
171*d4a07e70Sfengbojiang 
172*d4a07e70Sfengbojiang     return ngctl(NGCTL_BIND, (void *)&ba, len);
173*d4a07e70Sfengbojiang }
174*d4a07e70Sfengbojiang 
175*d4a07e70Sfengbojiang int
ng_connect(int sockfd,const struct sockaddr * addr,socklen_t addrlen)176*d4a07e70Sfengbojiang ng_connect(int sockfd, const struct sockaddr *addr,
177*d4a07e70Sfengbojiang     socklen_t addrlen)
178*d4a07e70Sfengbojiang {
179*d4a07e70Sfengbojiang     size_t len;
180*d4a07e70Sfengbojiang     struct connect_args ca;
181*d4a07e70Sfengbojiang 
182*d4a07e70Sfengbojiang     ca.s = sockfd;
183*d4a07e70Sfengbojiang     ca.name = (char *)addr;
184*d4a07e70Sfengbojiang     ca.namelen = addrlen;
185*d4a07e70Sfengbojiang 
186*d4a07e70Sfengbojiang     len = sizeof(ca) + addrlen;
187*d4a07e70Sfengbojiang 
188*d4a07e70Sfengbojiang     return ngctl(NGCTL_CONNECT, (void *)&ca, len);
189*d4a07e70Sfengbojiang }
190*d4a07e70Sfengbojiang 
191*d4a07e70Sfengbojiang ssize_t
ng_sendto(int sockfd,const void * buf,size_t len,int flags,const struct sockaddr * dest_addr,socklen_t addrlen)192*d4a07e70Sfengbojiang ng_sendto(int sockfd, const void *buf, size_t len, int flags,
193*d4a07e70Sfengbojiang     const struct sockaddr *dest_addr, socklen_t addrlen)
194*d4a07e70Sfengbojiang {
195*d4a07e70Sfengbojiang     size_t datalen;
196*d4a07e70Sfengbojiang 
197*d4a07e70Sfengbojiang     struct sendto_args sa;
198*d4a07e70Sfengbojiang     sa.s = sockfd;
199*d4a07e70Sfengbojiang     sa.buf = (void *)buf;
200*d4a07e70Sfengbojiang     sa.len = len;
201*d4a07e70Sfengbojiang     sa.flags = flags;
202*d4a07e70Sfengbojiang     sa.to = (char *)dest_addr;
203*d4a07e70Sfengbojiang     sa.tolen = addrlen;
204*d4a07e70Sfengbojiang 
205*d4a07e70Sfengbojiang     datalen = sizeof(sa) + len + addrlen;
206*d4a07e70Sfengbojiang     return ngctl(NGCTL_SEND, (void *)&sa, datalen);
207*d4a07e70Sfengbojiang }
208*d4a07e70Sfengbojiang 
209*d4a07e70Sfengbojiang ssize_t
ng_recvfrom(int sockfd,void * buf,size_t len,int flags,struct sockaddr * src_addr,socklen_t * addrlen)210*d4a07e70Sfengbojiang ng_recvfrom(int sockfd, void *buf, size_t len, int flags,
211*d4a07e70Sfengbojiang     struct sockaddr *src_addr, socklen_t *addrlen)
212*d4a07e70Sfengbojiang {
213*d4a07e70Sfengbojiang     size_t datalen;
214*d4a07e70Sfengbojiang 
215*d4a07e70Sfengbojiang     struct recvfrom_args ra;
216*d4a07e70Sfengbojiang     ra.s = sockfd;
217*d4a07e70Sfengbojiang     ra.buf = buf;
218*d4a07e70Sfengbojiang     ra.len = len;
219*d4a07e70Sfengbojiang     ra.flags = flags;
220*d4a07e70Sfengbojiang     ra.from = src_addr;
221*d4a07e70Sfengbojiang     ra.fromlenaddr = addrlen;
222*d4a07e70Sfengbojiang 
223*d4a07e70Sfengbojiang     datalen = sizeof(ra) + len + (*addrlen) + sizeof(socklen_t);
224*d4a07e70Sfengbojiang     return ngctl(NGCTL_RECV, (void *)&ra, datalen);
225*d4a07e70Sfengbojiang }
226*d4a07e70Sfengbojiang 
227*d4a07e70Sfengbojiang int
ng_close(int fd)228*d4a07e70Sfengbojiang ng_close(int fd)
229*d4a07e70Sfengbojiang {
230*d4a07e70Sfengbojiang     struct close_args ca;
231*d4a07e70Sfengbojiang     ca.fd = fd;
232*d4a07e70Sfengbojiang 
233*d4a07e70Sfengbojiang     return ngctl(NGCTL_CLOSE, (void *)&ca, sizeof(ca));
234*d4a07e70Sfengbojiang }
235*d4a07e70Sfengbojiang 
236