6
6
#include <stdlib.h>
7
7
#include <string.h>
8
8
#include <unistd.h>
9
+ #include <limits.h>
9
10
10
11
#include <sys/socket.h>
11
12
#include <sys/types.h>
@@ -26,6 +27,7 @@ static void syntax(char *argv[])
26
27
{
27
28
fprintf (stderr , "%s add|get|set|del|flush|dump|accept [<args>]\n" , argv [0 ]);
28
29
fprintf (stderr , "\tadd [flags signal|subflow|backup|fullmesh] [id <nr>] [dev <name>] <ip>\n" );
30
+ fprintf (stderr , "\tann <local-ip> id <local-id> token <token> [port <local-port>] [dev <name>]\n" );
29
31
fprintf (stderr , "\tdel <id> [<ip>]\n" );
30
32
fprintf (stderr , "\tget <id>\n" );
31
33
fprintf (stderr , "\tset [<ip>] [id <nr>] flags [no]backup|[no]fullmesh [port <nr>]\n" );
@@ -170,6 +172,133 @@ static int resolve_mptcp_pm_netlink(int fd)
170
172
return genl_parse_getfamily ((void * )data );
171
173
}
172
174
175
+ int announce_addr (int fd , int pm_family , int argc , char * argv [])
176
+ {
177
+ char data [NLMSG_ALIGN (sizeof (struct nlmsghdr )) +
178
+ NLMSG_ALIGN (sizeof (struct genlmsghdr )) +
179
+ 1024 ];
180
+ u_int32_t flags = MPTCP_PM_ADDR_FLAG_SIGNAL ;
181
+ u_int32_t token = UINT_MAX ;
182
+ struct rtattr * rta , * addr ;
183
+ u_int32_t id = UINT_MAX ;
184
+ struct nlmsghdr * nh ;
185
+ u_int16_t family ;
186
+ int addr_start ;
187
+ int off = 0 ;
188
+ int arg ;
189
+
190
+ memset (data , 0 , sizeof (data ));
191
+ nh = (void * )data ;
192
+ off = init_genl_req (data , pm_family , MPTCP_PM_CMD_ANNOUNCE ,
193
+ MPTCP_PM_VER );
194
+
195
+ if (argc < 7 )
196
+ syntax (argv );
197
+
198
+ /* local-ip header */
199
+ addr_start = off ;
200
+ addr = (void * )(data + off );
201
+ addr -> rta_type = NLA_F_NESTED | MPTCP_PM_ATTR_ADDR ;
202
+ addr -> rta_len = RTA_LENGTH (0 );
203
+ off += NLMSG_ALIGN (addr -> rta_len );
204
+
205
+ /* local-ip data */
206
+ /* record addr type */
207
+ rta = (void * )(data + off );
208
+ if (inet_pton (AF_INET , argv [2 ], RTA_DATA (rta ))) {
209
+ family = AF_INET ;
210
+ rta -> rta_type = MPTCP_PM_ADDR_ATTR_ADDR4 ;
211
+ rta -> rta_len = RTA_LENGTH (4 );
212
+ } else if (inet_pton (AF_INET6 , argv [2 ], RTA_DATA (rta ))) {
213
+ family = AF_INET6 ;
214
+ rta -> rta_type = MPTCP_PM_ADDR_ATTR_ADDR6 ;
215
+ rta -> rta_len = RTA_LENGTH (16 );
216
+ } else
217
+ error (1 , errno , "can't parse ip %s" , argv [2 ]);
218
+ off += NLMSG_ALIGN (rta -> rta_len );
219
+
220
+ /* addr family */
221
+ rta = (void * )(data + off );
222
+ rta -> rta_type = MPTCP_PM_ADDR_ATTR_FAMILY ;
223
+ rta -> rta_len = RTA_LENGTH (2 );
224
+ memcpy (RTA_DATA (rta ), & family , 2 );
225
+ off += NLMSG_ALIGN (rta -> rta_len );
226
+
227
+ for (arg = 3 ; arg < argc ; arg ++ ) {
228
+ if (!strcmp (argv [arg ], "id" )) {
229
+ /* local-id */
230
+ if (++ arg >= argc )
231
+ error (1 , 0 , " missing id value" );
232
+
233
+ id = atoi (argv [arg ]);
234
+ rta = (void * )(data + off );
235
+ rta -> rta_type = MPTCP_PM_ADDR_ATTR_ID ;
236
+ rta -> rta_len = RTA_LENGTH (1 );
237
+ memcpy (RTA_DATA (rta ), & id , 1 );
238
+ off += NLMSG_ALIGN (rta -> rta_len );
239
+ } else if (!strcmp (argv [arg ], "dev" )) {
240
+ /* for the if_index */
241
+ int32_t ifindex ;
242
+
243
+ if (++ arg >= argc )
244
+ error (1 , 0 , " missing dev name" );
245
+
246
+ ifindex = if_nametoindex (argv [arg ]);
247
+ if (!ifindex )
248
+ error (1 , errno , "unknown device %s" , argv [arg ]);
249
+
250
+ rta = (void * )(data + off );
251
+ rta -> rta_type = MPTCP_PM_ADDR_ATTR_IF_IDX ;
252
+ rta -> rta_len = RTA_LENGTH (4 );
253
+ memcpy (RTA_DATA (rta ), & ifindex , 4 );
254
+ off += NLMSG_ALIGN (rta -> rta_len );
255
+ } else if (!strcmp (argv [arg ], "port" )) {
256
+ /* local-port (optional) */
257
+ u_int16_t port ;
258
+
259
+ if (++ arg >= argc )
260
+ error (1 , 0 , " missing port value" );
261
+
262
+ port = atoi (argv [arg ]);
263
+ rta = (void * )(data + off );
264
+ rta -> rta_type = MPTCP_PM_ADDR_ATTR_PORT ;
265
+ rta -> rta_len = RTA_LENGTH (2 );
266
+ memcpy (RTA_DATA (rta ), & port , 2 );
267
+ off += NLMSG_ALIGN (rta -> rta_len );
268
+ } else if (!strcmp (argv [arg ], "token" )) {
269
+ /* MPTCP connection token */
270
+ if (++ arg >= argc )
271
+ error (1 , 0 , " missing token value" );
272
+
273
+ token = atoi (argv [arg ]);
274
+ } else
275
+ error (1 , 0 , "unknown keyword %s" , argv [arg ]);
276
+ }
277
+
278
+ /* addr flags */
279
+ rta = (void * )(data + off );
280
+ rta -> rta_type = MPTCP_PM_ADDR_ATTR_FLAGS ;
281
+ rta -> rta_len = RTA_LENGTH (4 );
282
+ memcpy (RTA_DATA (rta ), & flags , 4 );
283
+ off += NLMSG_ALIGN (rta -> rta_len );
284
+
285
+ addr -> rta_len = off - addr_start ;
286
+
287
+ if (id == UINT_MAX || token == UINT_MAX )
288
+ error (1 , 0 , " missing mandatory inputs" );
289
+
290
+ /* token */
291
+ rta = (void * )(data + off );
292
+ rta -> rta_type = MPTCP_PM_ATTR_TOKEN ;
293
+ rta -> rta_len = RTA_LENGTH (4 );
294
+ memcpy (RTA_DATA (rta ), & token , 4 );
295
+ off += NLMSG_ALIGN (rta -> rta_len );
296
+
297
+ do_nl_req (fd , nh , off , 0 );
298
+
299
+ return 0 ;
300
+ }
301
+
173
302
int add_addr (int fd , int pm_family , int argc , char * argv [])
174
303
{
175
304
char data [NLMSG_ALIGN (sizeof (struct nlmsghdr )) +
@@ -786,6 +915,8 @@ int main(int argc, char *argv[])
786
915
787
916
if (!strcmp (argv [1 ], "add" ))
788
917
return add_addr (fd , pm_family , argc , argv );
918
+ else if (!strcmp (argv [1 ], "ann" ))
919
+ return announce_addr (fd , pm_family , argc , argv );
789
920
else if (!strcmp (argv [1 ], "del" ))
790
921
return del_addr (fd , pm_family , argc , argv );
791
922
else if (!strcmp (argv [1 ], "flush" ))
0 commit comments