22
22
#ifndef MPTCP_PM_NAME
23
23
#define MPTCP_PM_NAME "mptcp_pm"
24
24
#endif
25
+ #ifndef MPTCP_PM_EVENTS
26
+ #define MPTCP_PM_EVENTS "mptcp_pm_events"
27
+ #endif
25
28
26
29
static void syntax (char * argv [])
27
30
{
@@ -37,6 +40,7 @@ static void syntax(char *argv[])
37
40
fprintf (stderr , "\tflush\n" );
38
41
fprintf (stderr , "\tdump\n" );
39
42
fprintf (stderr , "\tlimits [<rcv addr max> <subflow max>]\n" );
43
+ fprintf (stderr , "\tevents\n" );
40
44
exit (0 );
41
45
}
42
46
@@ -88,6 +92,108 @@ static void nl_error(struct nlmsghdr *nh)
88
92
}
89
93
}
90
94
95
+ static int capture_events (int fd , int event_group )
96
+ {
97
+ u_int8_t buffer [NLMSG_ALIGN (sizeof (struct nlmsghdr )) +
98
+ NLMSG_ALIGN (sizeof (struct genlmsghdr )) + 1024 ];
99
+ struct genlmsghdr * ghdr ;
100
+ struct rtattr * attrs ;
101
+ struct nlmsghdr * nh ;
102
+ int ret = 0 ;
103
+ int res_len ;
104
+ int msg_len ;
105
+ fd_set rfds ;
106
+
107
+ if (setsockopt (fd , SOL_NETLINK , NETLINK_ADD_MEMBERSHIP ,
108
+ & event_group , sizeof (event_group )) < 0 )
109
+ error (1 , errno , "could not join the " MPTCP_PM_EVENTS " mcast group" );
110
+
111
+ do {
112
+ FD_ZERO (& rfds );
113
+ FD_SET (fd , & rfds );
114
+ res_len = NLMSG_ALIGN (sizeof (struct nlmsghdr )) +
115
+ NLMSG_ALIGN (sizeof (struct genlmsghdr )) + 1024 ;
116
+
117
+ ret = select (FD_SETSIZE , & rfds , NULL , NULL , NULL );
118
+
119
+ if (ret < 0 )
120
+ error (1 , ret , "error in select() on NL socket" );
121
+
122
+ res_len = recv (fd , buffer , res_len , 0 );
123
+ if (res_len < 0 )
124
+ error (1 , res_len , "error on recv() from NL socket" );
125
+
126
+ nh = (struct nlmsghdr * )buffer ;
127
+
128
+ for (; NLMSG_OK (nh , res_len ); nh = NLMSG_NEXT (nh , res_len )) {
129
+ if (nh -> nlmsg_type == NLMSG_ERROR )
130
+ error (1 , NLMSG_ERROR , "received invalid NL message" );
131
+
132
+ ghdr = (struct genlmsghdr * )NLMSG_DATA (nh );
133
+
134
+ if (ghdr -> cmd == 0 )
135
+ continue ;
136
+
137
+ fprintf (stderr , "type:%d" , ghdr -> cmd );
138
+
139
+ msg_len = nh -> nlmsg_len - NLMSG_LENGTH (GENL_HDRLEN );
140
+
141
+ attrs = (struct rtattr * ) ((char * ) ghdr + GENL_HDRLEN );
142
+ while (RTA_OK (attrs , msg_len )) {
143
+ if (attrs -> rta_type == MPTCP_ATTR_TOKEN )
144
+ fprintf (stderr , ",token:%u" , * (__u32 * )RTA_DATA (attrs ));
145
+ else if (attrs -> rta_type == MPTCP_ATTR_FAMILY )
146
+ fprintf (stderr , ",family:%u" , * (__u16 * )RTA_DATA (attrs ));
147
+ else if (attrs -> rta_type == MPTCP_ATTR_LOC_ID )
148
+ fprintf (stderr , ",loc_id:%u" , * (__u8 * )RTA_DATA (attrs ));
149
+ else if (attrs -> rta_type == MPTCP_ATTR_REM_ID )
150
+ fprintf (stderr , ",rem_id:%u" , * (__u8 * )RTA_DATA (attrs ));
151
+ else if (attrs -> rta_type == MPTCP_ATTR_SADDR4 ) {
152
+ u_int32_t saddr4 = ntohl (* (__u32 * )RTA_DATA (attrs ));
153
+
154
+ fprintf (stderr , ",saddr4:%u.%u.%u.%u" , saddr4 >> 24 ,
155
+ (saddr4 >> 16 ) & 0xFF , (saddr4 >> 8 ) & 0xFF ,
156
+ (saddr4 & 0xFF ));
157
+ } else if (attrs -> rta_type == MPTCP_ATTR_SADDR6 ) {
158
+ char buf [INET6_ADDRSTRLEN ];
159
+
160
+ if (inet_ntop (AF_INET6 , RTA_DATA (attrs ), buf ,
161
+ sizeof (buf )) != NULL )
162
+ fprintf (stderr , ",saddr6:%s" , buf );
163
+ } else if (attrs -> rta_type == MPTCP_ATTR_DADDR4 ) {
164
+ u_int32_t daddr4 = ntohl (* (__u32 * )RTA_DATA (attrs ));
165
+
166
+ fprintf (stderr , ",daddr4:%u.%u.%u.%u" , daddr4 >> 24 ,
167
+ (daddr4 >> 16 ) & 0xFF , (daddr4 >> 8 ) & 0xFF ,
168
+ (daddr4 & 0xFF ));
169
+ } else if (attrs -> rta_type == MPTCP_ATTR_DADDR6 ) {
170
+ char buf [INET6_ADDRSTRLEN ];
171
+
172
+ if (inet_ntop (AF_INET6 , RTA_DATA (attrs ), buf ,
173
+ sizeof (buf )) != NULL )
174
+ fprintf (stderr , ",daddr6:%s" , buf );
175
+ } else if (attrs -> rta_type == MPTCP_ATTR_SPORT )
176
+ fprintf (stderr , ",sport:%u" ,
177
+ ntohs (* (__u16 * )RTA_DATA (attrs )));
178
+ else if (attrs -> rta_type == MPTCP_ATTR_DPORT )
179
+ fprintf (stderr , ",dport:%u" ,
180
+ ntohs (* (__u16 * )RTA_DATA (attrs )));
181
+ else if (attrs -> rta_type == MPTCP_ATTR_BACKUP )
182
+ fprintf (stderr , ",backup:%u" , * (__u8 * )RTA_DATA (attrs ));
183
+ else if (attrs -> rta_type == MPTCP_ATTR_ERROR )
184
+ fprintf (stderr , ",error:%u" , * (__u8 * )RTA_DATA (attrs ));
185
+ else if (attrs -> rta_type == MPTCP_ATTR_SERVER_SIDE )
186
+ fprintf (stderr , ",server_side:%u" , * (__u8 * )RTA_DATA (attrs ));
187
+
188
+ attrs = RTA_NEXT (attrs , msg_len );
189
+ }
190
+ }
191
+ fprintf (stderr , "\n" );
192
+ } while (1 );
193
+
194
+ return 0 ;
195
+ }
196
+
91
197
/* do a netlink command and, if max > 0, fetch the reply */
92
198
static int do_nl_req (int fd , struct nlmsghdr * nh , int len , int max )
93
199
{
@@ -121,11 +227,18 @@ static int do_nl_req(int fd, struct nlmsghdr *nh, int len, int max)
121
227
return ret ;
122
228
}
123
229
124
- static int genl_parse_getfamily (struct nlmsghdr * nlh )
230
+ static int genl_parse_getfamily (struct nlmsghdr * nlh , int * pm_family ,
231
+ int * events_mcast_grp )
125
232
{
126
233
struct genlmsghdr * ghdr = NLMSG_DATA (nlh );
127
234
int len = nlh -> nlmsg_len ;
128
235
struct rtattr * attrs ;
236
+ struct rtattr * grps ;
237
+ struct rtattr * grp ;
238
+ int got_events_grp ;
239
+ int got_family ;
240
+ int grps_len ;
241
+ int grp_len ;
129
242
130
243
if (nlh -> nlmsg_type != GENL_ID_CTRL )
131
244
error (1 , errno , "Not a controller message, len=%d type=0x%x\n" ,
@@ -140,17 +253,50 @@ static int genl_parse_getfamily(struct nlmsghdr *nlh)
140
253
error (1 , errno , "Unknown controller command %d\n" , ghdr -> cmd );
141
254
142
255
attrs = (struct rtattr * ) ((char * ) ghdr + GENL_HDRLEN );
256
+ got_family = 0 ;
257
+ got_events_grp = 0 ;
258
+
143
259
while (RTA_OK (attrs , len )) {
144
- if (attrs -> rta_type == CTRL_ATTR_FAMILY_ID )
145
- return * (__u16 * )RTA_DATA (attrs );
260
+ if (attrs -> rta_type == CTRL_ATTR_FAMILY_ID ) {
261
+ * pm_family = * (__u16 * )RTA_DATA (attrs );
262
+ got_family = 1 ;
263
+ } else if (attrs -> rta_type == CTRL_ATTR_MCAST_GROUPS ) {
264
+ grps = RTA_DATA (attrs );
265
+ grps_len = RTA_PAYLOAD (attrs );
266
+
267
+ while (RTA_OK (grps , grps_len )) {
268
+ grp = RTA_DATA (grps );
269
+ grp_len = RTA_PAYLOAD (grps );
270
+ got_events_grp = 0 ;
271
+
272
+ while (RTA_OK (grp , grp_len )) {
273
+ if (grp -> rta_type == CTRL_ATTR_MCAST_GRP_ID )
274
+ * events_mcast_grp = * (__u32 * )RTA_DATA (grp );
275
+ else if (grp -> rta_type == CTRL_ATTR_MCAST_GRP_NAME &&
276
+ !strcmp (RTA_DATA (grp ), MPTCP_PM_EVENTS ))
277
+ got_events_grp = 1 ;
278
+
279
+ grp = RTA_NEXT (grp , grp_len );
280
+ }
281
+
282
+ if (got_events_grp )
283
+ break ;
284
+
285
+ grps = RTA_NEXT (grps , grps_len );
286
+ }
287
+ }
288
+
289
+ if (got_family && got_events_grp )
290
+ return 0 ;
291
+
146
292
attrs = RTA_NEXT (attrs , len );
147
293
}
148
294
149
295
error (1 , errno , "can't find CTRL_ATTR_FAMILY_ID attr" );
150
296
return -1 ;
151
297
}
152
298
153
- static int resolve_mptcp_pm_netlink (int fd )
299
+ static int resolve_mptcp_pm_netlink (int fd , int * pm_family , int * events_mcast_grp )
154
300
{
155
301
char data [NLMSG_ALIGN (sizeof (struct nlmsghdr )) +
156
302
NLMSG_ALIGN (sizeof (struct genlmsghdr )) +
@@ -172,7 +318,7 @@ static int resolve_mptcp_pm_netlink(int fd)
172
318
off += NLMSG_ALIGN (rta -> rta_len );
173
319
174
320
do_nl_req (fd , nh , off , sizeof (data ));
175
- return genl_parse_getfamily ((void * )data );
321
+ return genl_parse_getfamily ((void * )data , pm_family , events_mcast_grp );
176
322
}
177
323
178
324
int dsf (int fd , int pm_family , int argc , char * argv [])
@@ -1192,7 +1338,9 @@ int set_flags(int fd, int pm_family, int argc, char *argv[])
1192
1338
1193
1339
int main (int argc , char * argv [])
1194
1340
{
1195
- int fd , pm_family ;
1341
+ int events_mcast_grp ;
1342
+ int pm_family ;
1343
+ int fd ;
1196
1344
1197
1345
if (argc < 2 )
1198
1346
syntax (argv );
@@ -1201,7 +1349,7 @@ int main(int argc, char *argv[])
1201
1349
if (fd == -1 )
1202
1350
error (1 , errno , "socket netlink" );
1203
1351
1204
- pm_family = resolve_mptcp_pm_netlink (fd );
1352
+ resolve_mptcp_pm_netlink (fd , & pm_family , & events_mcast_grp );
1205
1353
1206
1354
if (!strcmp (argv [1 ], "add" ))
1207
1355
return add_addr (fd , pm_family , argc , argv );
@@ -1225,6 +1373,8 @@ int main(int argc, char *argv[])
1225
1373
return get_set_limits (fd , pm_family , argc , argv );
1226
1374
else if (!strcmp (argv [1 ], "set" ))
1227
1375
return set_flags (fd , pm_family , argc , argv );
1376
+ else if (!strcmp (argv [1 ], "events" ))
1377
+ return capture_events (fd , events_mcast_grp );
1228
1378
1229
1379
fprintf (stderr , "unknown sub-command: %s" , argv [1 ]);
1230
1380
syntax (argv );
0 commit comments