@@ -43,11 +43,11 @@ struct api_hostfwd {
43
43
int is_udp ;
44
44
int is_ipv4 ;
45
45
int is_ipv6 ;
46
- struct in_addr host_addr ;
47
- struct in6_addr host_addr6 ;
46
+ struct sockaddr_in host ;
47
+ struct sockaddr_in guest ;
48
+ struct sockaddr_in6 host6 ;
49
+ struct sockaddr_in6 guest6 ;
48
50
int host_port ;
49
- struct in_addr guest_addr ;
50
- struct in6_addr guest_addr6 ;
51
51
int guest_port ;
52
52
};
53
53
@@ -103,10 +103,8 @@ static int api_handle_req_add_hostfwd(Slirp *slirp, int fd, struct api_ctx *ctx,
103
103
const char * proto_s = json_object_dotget_string (jo , "arguments.proto" );
104
104
const char * host_addr_s =
105
105
json_object_dotget_string (jo , "arguments.host_addr" );
106
- char * host_addr6_s = NULL ;
107
106
const char * guest_addr_s =
108
107
json_object_dotget_string (jo , "arguments.guest_addr" );
109
- char * guest_addr6_s = NULL ;
110
108
struct api_hostfwd * fwd = g_malloc0 (sizeof (* fwd ));
111
109
if (fwd == NULL ) {
112
110
perror ("fatal: malloc" );
@@ -127,10 +125,46 @@ static int api_handle_req_add_hostfwd(Slirp *slirp, int fd, struct api_ctx *ctx,
127
125
}
128
126
int flags = (fwd -> is_udp ? SLIRP_HOSTFWD_UDP : 0 );
129
127
128
+ if (host_addr_s == NULL || host_addr_s [0 ] == '\0' ) {
129
+ host_addr_s = "0.0.0.0" ;
130
+ }
131
+ if (strcmp ("0.0.0.0" , host_addr_s ) == 0 ||
132
+ strcmp ("::" , host_addr_s ) == 0 ||
133
+ strcmp ("::0" , host_addr_s ) == 0 ) {
134
+ fwd -> is_ipv4 = 1 ;
135
+ fwd -> is_ipv6 = ctx -> cfg -> enable_ipv6 ;
136
+ host_addr_s = "0.0.0.0" ;
137
+ } else {
138
+ if (strchr (host_addr_s , '.' )) {
139
+ fwd -> is_ipv4 = 1 ;
140
+ }
141
+ else if (strchr (host_addr_s , ':' )) {
142
+ if (!ctx -> cfg -> enable_ipv6 ) {
143
+ const char * err =
144
+ "{\"error\":{\"desc\":\"bad request: add_hostfwd: "
145
+ "bad arguments.host_addr\"}}" ;
146
+ wrc = write (fd , err , strlen (err ));
147
+ free (fwd );
148
+ goto finish ;
149
+ }
150
+ fwd -> is_ipv6 = 1 ;
151
+ }
152
+ }
153
+
130
154
if (strlen (proto_s ) == 4 ) {
131
155
if (proto_s [3 ] == '4' ) {
132
156
fwd -> is_ipv4 = 1 ;
157
+ fwd -> is_ipv6 = 0 ;
133
158
} else if (proto_s [3 ] == '6' ) {
159
+ if (!ctx -> cfg -> enable_ipv6 ) {
160
+ const char * err =
161
+ "{\"error\":{\"desc\":\"bad request: add_hostfwd: "
162
+ "bad arguments.proto\"}}" ;
163
+ wrc = write (fd , err , strlen (err ));
164
+ free (fwd );
165
+ goto finish ;
166
+ }
167
+ fwd -> is_ipv4 = 0 ;
134
168
fwd -> is_ipv6 = 1 ;
135
169
} else {
136
170
const char * err =
@@ -140,9 +174,6 @@ static int api_handle_req_add_hostfwd(Slirp *slirp, int fd, struct api_ctx *ctx,
140
174
free (fwd );
141
175
goto finish ;
142
176
}
143
- } else {
144
- fwd -> is_ipv4 = 1 ;
145
- fwd -> is_ipv6 = 1 ;
146
177
}
147
178
148
179
fwd -> host_port = (int )json_object_dotget_number (jo , "arguments.host_port" );
@@ -164,39 +195,30 @@ static int api_handle_req_add_hostfwd(Slirp *slirp, int fd, struct api_ctx *ctx,
164
195
}
165
196
166
197
if (fwd -> is_ipv4 ) {
198
+ fwd -> host .sin_family = AF_INET ;
199
+ fwd -> guest .sin_family = AF_INET ;
200
+ fwd -> host .sin_port = htons (fwd -> host_port );
201
+ fwd -> guest .sin_port = htons (fwd -> guest_port );
167
202
if (guest_addr_s == NULL || guest_addr_s [0 ] == '\0' ) {
168
- fwd -> guest_addr = ctx -> cfg -> recommended_vguest ;
169
- } else if (inet_pton (AF_INET , guest_addr_s , & fwd -> guest_addr ) != 1 ) {
203
+ fwd -> guest . sin_addr = ctx -> cfg -> recommended_vguest ;
204
+ } else if (inet_pton (AF_INET , guest_addr_s , & fwd -> guest . sin_addr ) != 1 ) {
170
205
const char * err = "{\"error\":{\"desc\":\"bad request: add_hostfwd: "
171
206
"bad arguments.guest_addr\"}}" ;
172
207
wrc = write (fd , err , strlen (err ));
173
208
free (fwd );
174
209
goto finish ;
175
210
}
176
- if (host_addr_s == NULL || host_addr_s [0 ] == '\0' ) {
177
- host_addr_s = "0.0.0.0" ;
178
- }
179
- if (inet_pton (AF_INET , host_addr_s , & fwd -> host_addr ) != 1 ) {
211
+ if (inet_pton (AF_INET , host_addr_s , & fwd -> host .sin_addr ) != 1 ) {
180
212
const char * err =
181
213
"{\"error\":{\"desc\":\"bad request: add_hostfwd: "
182
214
"bad arguments.host_addr\"}}" ;
183
215
wrc = write (fd , err , strlen (err ));
184
216
free (fwd );
185
217
goto finish ;
186
218
}
187
- struct sockaddr_in host ;
188
- memset (& host , 0 , sizeof (host ));
189
- host .sin_family = AF_INET ;
190
- host .sin_addr .s_addr = fwd -> host_addr .s_addr ;
191
- host .sin_port = htons (fwd -> host_port );
192
- struct sockaddr_in guest ;
193
- memset (& guest , 0 , sizeof (guest ));
194
- guest .sin_family = AF_INET ;
195
- guest .sin_addr .s_addr = fwd -> guest_addr .s_addr ;
196
- guest .sin_port = htons (fwd -> guest_port );
197
219
if (slirp_add_hostxfwd (slirp ,
198
- (const struct sockaddr * )& host , sizeof (host ),
199
- (const struct sockaddr * )& guest , sizeof (guest ), flags ) < 0 ) {
220
+ (const struct sockaddr * )& fwd -> host , sizeof (fwd -> host ),
221
+ (const struct sockaddr * )& fwd -> guest , sizeof (fwd -> guest ), flags ) < 0 ) {
200
222
const char * err =
201
223
"{\"error\":{\"desc\":\"bad request: add_hostfwd: "
202
224
"slirp_add_hostxfwd failed\"}}" ;
@@ -205,44 +227,39 @@ static int api_handle_req_add_hostfwd(Slirp *slirp, int fd, struct api_ctx *ctx,
205
227
goto finish ;
206
228
}
207
229
}
230
+
208
231
if (fwd -> is_ipv6 ) {
232
+ fwd -> host6 .sin6_family = AF_INET6 ;
233
+ fwd -> guest6 .sin6_family = AF_INET6 ;
234
+ fwd -> host6 .sin6_port = htons (fwd -> host_port );
235
+ fwd -> guest6 .sin6_port = htons (fwd -> guest_port );
209
236
if (guest_addr_s == NULL || guest_addr_s [0 ] == '\0' ) {
210
- fwd -> guest_addr6 = ctx -> cfg -> recommended_vguest6 ;
211
- } else if (inet_pton (AF_INET6 , guest_addr_s , & fwd -> guest_addr6 ) != 1 ) {
237
+ fwd -> guest6 . sin6_addr = ctx -> cfg -> recommended_vguest6 ;
238
+ } else if (inet_pton (AF_INET6 , guest_addr_s , & fwd -> guest6 . sin6_addr ) != 1 ) {
212
239
const char * err = "{\"error\":{\"desc\":\"bad request: add_hostfwd: "
213
240
"bad arguments.guest_addr\"}}" ;
214
241
wrc = write (fd , err , strlen (err ));
215
242
free (fwd );
216
243
goto finish ;
217
244
}
218
- if (host_addr_s == NULL || host_addr_s [0 ] == '\0' ||
219
- strcmp (host_addr_s , "0.0.0.0" ) == 0 ) {
245
+ if (strcmp (host_addr_s , "0.0.0.0" ) == 0 ) {
220
246
host_addr_s = "::" ;
221
247
}
222
- if (inet_pton (AF_INET6 , host_addr_s , & fwd -> host_addr6 ) != 1 ) {
248
+ if (inet_pton (AF_INET6 , host_addr_s , & fwd -> host6 . sin6_addr ) != 1 ) {
223
249
const char * err =
224
250
"{\"error\":{\"desc\":\"bad request: add_hostfwd: "
225
251
"bad arguments.host_addr\"}}" ;
226
252
wrc = write (fd , err , strlen (err ));
227
253
free (fwd );
228
254
goto finish ;
229
255
}
230
- struct sockaddr_in6 host ;
231
- memset (& host , 0 , sizeof (host ));
232
- host .sin6_family = AF_INET6 ;
233
- host .sin6_addr = fwd -> host_addr6 ;
234
- host .sin6_port = htons (fwd -> host_port );
235
- struct sockaddr_in6 guest ;
236
- memset (& guest , 0 , sizeof (guest ));
237
- guest .sin6_family = AF_INET6 ;
238
- guest .sin6_addr = fwd -> guest_addr6 ;
239
- guest .sin6_port = htons (fwd -> guest_port );
256
+ flags |= SLIRP_HOSTFWD_V6ONLY ;
240
257
if (slirp_add_hostxfwd (slirp ,
241
- (const struct sockaddr * )& host , sizeof (host ),
242
- (const struct sockaddr * )& guest , sizeof (guest ), flags ) < 0 ) {
258
+ (const struct sockaddr * )& fwd -> host6 , sizeof (fwd -> host6 ),
259
+ (const struct sockaddr * )& fwd -> guest6 , sizeof (fwd -> guest6 ), flags ) < 0 ) {
243
260
const char * err =
244
261
"{\"error\":{\"desc\":\"bad request: add_hostfwd: "
245
- "slirp_add_hostfwd failed\"}}" ;
262
+ "slirp_add_hostxfwd failed\"}}" ;
246
263
wrc = write (fd , err , strlen (err ));
247
264
free (fwd );
248
265
goto finish ;
@@ -270,36 +287,42 @@ static void api_handle_req_list_hostfwd_foreach(gpointer data,
270
287
JSON_Object * entry_object = json_value_get_object (entry_value );
271
288
char host_addr [INET_ADDRSTRLEN ], guest_addr [INET_ADDRSTRLEN ];
272
289
char host_addr6 [INET6_ADDRSTRLEN ], guest_addr6 [INET6_ADDRSTRLEN ];
273
- if (inet_ntop (AF_INET , & fwd -> host_addr , host_addr , sizeof (host_addr )) ==
274
- NULL ) {
275
- perror ("fatal: inet_ntop" );
276
- exit (EXIT_FAILURE );
277
- }
278
- if (inet_ntop (AF_INET , & fwd -> guest_addr , guest_addr , sizeof (guest_addr )) ==
279
- NULL ) {
280
- perror ("fatal: inet_ntop" );
281
- exit (EXIT_FAILURE );
290
+ if (fwd -> is_ipv4 ) {
291
+ if (inet_ntop (AF_INET , & fwd -> host .sin_addr , host_addr , sizeof (host_addr )) ==
292
+ NULL ) {
293
+ perror ("fatal: inet_ntop" );
294
+ exit (EXIT_FAILURE );
295
+ }
296
+ if (inet_ntop (AF_INET , & fwd -> guest .sin_addr , guest_addr , sizeof (guest_addr )) ==
297
+ NULL ) {
298
+ perror ("fatal: inet_ntop" );
299
+ exit (EXIT_FAILURE );
300
+ }
282
301
}
283
302
if (fwd -> is_ipv6 ) {
284
- if (inet_ntop (AF_INET6 , & fwd -> host_addr6 , host_addr6 , sizeof (host_addr6 )) ==
303
+ if (inet_ntop (AF_INET6 , & fwd -> host6 . sin6_addr , host_addr6 , sizeof (host_addr6 )) ==
285
304
NULL ) {
286
305
perror ("fatal: inet_ntop" );
287
306
exit (EXIT_FAILURE );
288
307
}
289
- if (inet_ntop (AF_INET6 , & fwd -> guest_addr6 , guest_addr6 , sizeof (guest_addr6 )) ==
308
+ if (inet_ntop (AF_INET6 , & fwd -> guest6 . sin6_addr , guest_addr6 , sizeof (guest_addr6 )) ==
290
309
NULL ) {
291
310
perror ("fatal: inet_ntop" );
292
311
exit (EXIT_FAILURE );
293
312
}
294
313
}
295
314
json_object_set_number (entry_object , "id" , fwd -> id );
296
315
json_object_set_string (entry_object , "proto" , fwd -> is_udp ? "udp" : "tcp" );
297
- json_object_set_string (entry_object , "host_addr" , host_addr );
316
+ if (fwd -> is_ipv4 ) {
317
+ json_object_set_string (entry_object , "host_addr" , host_addr );
318
+ }
298
319
if (fwd -> is_ipv6 ) {
299
320
json_object_set_string (entry_object , "host_addr6" , host_addr6 );
300
321
}
301
322
json_object_set_number (entry_object , "host_port" , fwd -> host_port );
302
- json_object_set_string (entry_object , "guest_addr" , guest_addr );
323
+ if (fwd -> is_ipv4 ) {
324
+ json_object_set_string (entry_object , "guest_addr" , guest_addr );
325
+ }
303
326
if (fwd -> is_ipv6 ) {
304
327
json_object_set_string (entry_object , "guest_addr6" , guest_addr6 );
305
328
}
@@ -360,16 +383,25 @@ static int api_handle_req_remove_hostfwd(Slirp *slirp, int fd,
360
383
} else {
361
384
struct api_hostfwd * fwd = found -> data ;
362
385
const char * api_ok = "{\"return\":{}}" ;
363
- if (slirp_remove_hostfwd (slirp , fwd -> is_udp , fwd -> host_addr ,
364
- fwd -> host_port ) < 0 ) {
365
- const char * err = "{\"error\":{\"desc\":\"bad request: "
366
- "remove_hostfwd: slirp_remove_hostfwd failed\"}}" ;
367
- wrc = write (fd , err , strlen (err ));
368
- } else {
369
- ctx -> hostfwds = g_list_remove (ctx -> hostfwds , fwd );
370
- g_free (fwd );
371
- wrc = write (fd , api_ok , strlen (api_ok ));
386
+ if (fwd -> is_ipv4 ) {
387
+ if (slirp_remove_hostxfwd (slirp ,
388
+ (const struct sockaddr * )& fwd -> host , sizeof (fwd -> host ), 0 ) < 0 ) {
389
+ const char * err = "{\"error\":{\"desc\":\"bad request: "
390
+ "remove_hostfwd: slirp_remove_hostxfwd failed\"}}" ;
391
+ return write (fd , err , strlen (err ));
392
+ }
393
+ }
394
+ if (fwd -> is_ipv6 ) {
395
+ if (slirp_remove_hostxfwd (slirp ,
396
+ (const struct sockaddr * )& fwd -> host6 , sizeof (fwd -> host6 ), 0 ) < 0 ) {
397
+ const char * err = "{\"error\":{\"desc\":\"bad request: "
398
+ "remove_hostfwd: slirp_remove_hostxfwd failed\"}}" ;
399
+ return write (fd , err , strlen (err ));
400
+ }
372
401
}
402
+ ctx -> hostfwds = g_list_remove (ctx -> hostfwds , fwd );
403
+ g_free (fwd );
404
+ wrc = write (fd , api_ok , strlen (api_ok ));
373
405
}
374
406
return wrc ;
375
407
}
0 commit comments