xref: /f-stack/tools/ipfw/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 <string.h>
32*d4a07e70Sfengbojiang 
33*d4a07e70Sfengbojiang #include "ff_ipc.h"
34*d4a07e70Sfengbojiang 
35*d4a07e70Sfengbojiang static int
ipfw_ctl(int cmd,int level,int optname,void * optval,socklen_t * optlen)36*d4a07e70Sfengbojiang ipfw_ctl(int cmd, int level, int optname, void *optval, socklen_t *optlen)
37*d4a07e70Sfengbojiang {
38*d4a07e70Sfengbojiang     struct ff_msg *msg, *retmsg = NULL;
39*d4a07e70Sfengbojiang     int len;
40*d4a07e70Sfengbojiang 
41*d4a07e70Sfengbojiang     switch (cmd) {
42*d4a07e70Sfengbojiang 	case FF_IPFW_GET:
43*d4a07e70Sfengbojiang             if (optval == NULL || optlen == NULL) {
44*d4a07e70Sfengbojiang                 return EINVAL;
45*d4a07e70Sfengbojiang             }
46*d4a07e70Sfengbojiang             break;
47*d4a07e70Sfengbojiang         case FF_IPFW_SET:
48*d4a07e70Sfengbojiang             break;
49*d4a07e70Sfengbojiang         default:
50*d4a07e70Sfengbojiang             return EINVAL;
51*d4a07e70Sfengbojiang     }
52*d4a07e70Sfengbojiang 
53*d4a07e70Sfengbojiang     msg = ff_ipc_msg_alloc();
54*d4a07e70Sfengbojiang     if (msg == NULL) {
55*d4a07e70Sfengbojiang         errno = ENOMEM;
56*d4a07e70Sfengbojiang         return -1;
57*d4a07e70Sfengbojiang     }
58*d4a07e70Sfengbojiang 
59*d4a07e70Sfengbojiang     len = sizeof(struct ff_ipfw_args) + *optlen + sizeof(socklen_t);
60*d4a07e70Sfengbojiang     if (len > msg->buf_len) {
61*d4a07e70Sfengbojiang         errno = EINVAL;
62*d4a07e70Sfengbojiang         ff_ipc_msg_free(msg);
63*d4a07e70Sfengbojiang         return -1;
64*d4a07e70Sfengbojiang     }
65*d4a07e70Sfengbojiang 
66*d4a07e70Sfengbojiang     msg->msg_type = FF_IPFW_CTL;
67*d4a07e70Sfengbojiang     msg->ipfw.cmd = cmd;
68*d4a07e70Sfengbojiang     msg->ipfw.level = level;
69*d4a07e70Sfengbojiang     msg->ipfw.optname = optname;
70*d4a07e70Sfengbojiang     msg->ipfw.optval = (void *)msg->buf_addr;
71*d4a07e70Sfengbojiang     msg->ipfw.optlen = (socklen_t *)(msg->buf_addr + (*optlen));
72*d4a07e70Sfengbojiang 
73*d4a07e70Sfengbojiang     memcpy(msg->ipfw.optval, optval, *optlen);
74*d4a07e70Sfengbojiang     memcpy(msg->ipfw.optlen, optlen, sizeof(socklen_t));
75*d4a07e70Sfengbojiang 
76*d4a07e70Sfengbojiang     int ret = ff_ipc_send(msg);
77*d4a07e70Sfengbojiang     if (ret < 0) {
78*d4a07e70Sfengbojiang         errno = EPIPE;
79*d4a07e70Sfengbojiang         ff_ipc_msg_free(msg);
80*d4a07e70Sfengbojiang         return -1;
81*d4a07e70Sfengbojiang     }
82*d4a07e70Sfengbojiang 
83*d4a07e70Sfengbojiang     do {
84*d4a07e70Sfengbojiang         if (retmsg != NULL) {
85*d4a07e70Sfengbojiang             ff_ipc_msg_free(retmsg);
86*d4a07e70Sfengbojiang         }
87*d4a07e70Sfengbojiang         ret = ff_ipc_recv(&retmsg, msg->msg_type);
88*d4a07e70Sfengbojiang         if (ret < 0) {
89*d4a07e70Sfengbojiang             errno = EPIPE;
90*d4a07e70Sfengbojiang             return -1;
91*d4a07e70Sfengbojiang         }
92*d4a07e70Sfengbojiang     } while (msg != retmsg);
93*d4a07e70Sfengbojiang 
94*d4a07e70Sfengbojiang     if (retmsg->result != 0) {
95*d4a07e70Sfengbojiang         ret = -1;
96*d4a07e70Sfengbojiang         errno = retmsg->result;
97*d4a07e70Sfengbojiang     } else {
98*d4a07e70Sfengbojiang         ret = 0;
99*d4a07e70Sfengbojiang 
100*d4a07e70Sfengbojiang         if (cmd == FF_IPFW_GET) {
101*d4a07e70Sfengbojiang             memcpy(optval, retmsg->ipfw.optval, *(retmsg->ipfw.optlen));
102*d4a07e70Sfengbojiang             memcpy(optlen, retmsg->ipfw.optlen, sizeof(socklen_t));
103*d4a07e70Sfengbojiang         }
104*d4a07e70Sfengbojiang     }
105*d4a07e70Sfengbojiang 
106*d4a07e70Sfengbojiang     ff_ipc_msg_free(msg);
107*d4a07e70Sfengbojiang 
108*d4a07e70Sfengbojiang     return ret;
109*d4a07e70Sfengbojiang }
110*d4a07e70Sfengbojiang 
111*d4a07e70Sfengbojiang int
ff_socket(int domain,int type,int protocol)112*d4a07e70Sfengbojiang ff_socket(int domain, int type, int protocol)
113*d4a07e70Sfengbojiang {
114*d4a07e70Sfengbojiang     return 0;
115*d4a07e70Sfengbojiang }
116*d4a07e70Sfengbojiang 
ff_getsockopt(int sockfd,int level,int optname,void * optval,socklen_t * optlen)117*d4a07e70Sfengbojiang int ff_getsockopt(int sockfd, int level, int optname,
118*d4a07e70Sfengbojiang     void *optval, socklen_t *optlen)
119*d4a07e70Sfengbojiang {
120*d4a07e70Sfengbojiang     return ipfw_ctl(FF_IPFW_GET, level, optname, optval, optlen);
121*d4a07e70Sfengbojiang }
122*d4a07e70Sfengbojiang 
ff_setsockopt(int sockfd,int level,int optname,const void * optval,socklen_t optlen)123*d4a07e70Sfengbojiang int ff_setsockopt(int sockfd, int level, int optname,
124*d4a07e70Sfengbojiang     const void *optval, socklen_t optlen)
125*d4a07e70Sfengbojiang {
126*d4a07e70Sfengbojiang     return ipfw_ctl(FF_IPFW_SET, level, optname, (void *)optval, &optlen);
127*d4a07e70Sfengbojiang }
128*d4a07e70Sfengbojiang 
129