12
12
13
13
#include <linux/module.h>
14
14
15
- #include "dccp.h"
16
15
#include "ccid.h"
17
16
#include "feat.h"
18
17
@@ -23,9 +22,17 @@ int dccp_feat_change(struct dccp_minisock *dmsk, u8 type, u8 feature,
23
22
{
24
23
struct dccp_opt_pend * opt ;
25
24
26
- dccp_pr_debug ( "feat change type=%d feat=%d\n" , type , feature );
25
+ dccp_feat_debug ( type , feature , * val );
27
26
28
- /* XXX sanity check feat change request */
27
+ if (!dccp_feat_is_valid_type (type )) {
28
+ pr_info ("option type %d invalid in negotiation\n" , type );
29
+ return 1 ;
30
+ }
31
+ if (!dccp_feat_is_valid_length (type , feature , len )) {
32
+ pr_info ("invalid length %d\n" , len );
33
+ return 1 ;
34
+ }
35
+ /* XXX add further sanity checks */
29
36
30
37
/* check if that feature is already being negotiated */
31
38
list_for_each_entry (opt , & dmsk -> dccpms_pending , dccpop_node ) {
@@ -95,14 +102,14 @@ static int dccp_feat_update_ccid(struct sock *sk, u8 type, u8 new_ccid_nr)
95
102
/* XXX taking only u8 vals */
96
103
static int dccp_feat_update (struct sock * sk , u8 type , u8 feat , u8 val )
97
104
{
98
- dccp_pr_debug ( "changing [%d] feat %d to %d\n" , type , feat , val );
105
+ dccp_feat_debug ( type , feat , val );
99
106
100
107
switch (feat ) {
101
108
case DCCPF_CCID :
102
109
return dccp_feat_update_ccid (sk , type , val );
103
110
default :
104
- dccp_pr_debug ("IMPLEMENT changing [%d] feat %d to %d \n" ,
105
- type , feat , val );
111
+ dccp_pr_debug ("UNIMPLEMENTED: %s(%d, ...) \n" ,
112
+ dccp_feat_typename ( type ) , feat );
106
113
break ;
107
114
}
108
115
return 0 ;
@@ -265,10 +272,10 @@ static int dccp_feat_nn(struct sock *sk, u8 type, u8 feature, u8 *val, u8 len)
265
272
u8 * copy ;
266
273
int rc ;
267
274
268
- /* NN features must be change L */
269
- if (type == DCCPO_CHANGE_R ) {
270
- dccp_pr_debug ("received CHANGE_R %d for NN feat %d\n" ,
271
- type , feature );
275
+ /* NN features must be Change L (sec. 6.3.2) */
276
+ if (type != DCCPO_CHANGE_L ) {
277
+ dccp_pr_debug ("received %s for NN feature %d\n" ,
278
+ dccp_feat_typename ( type ) , feature );
272
279
return - EFAULT ;
273
280
}
274
281
@@ -299,7 +306,8 @@ static int dccp_feat_nn(struct sock *sk, u8 type, u8 feature, u8 *val, u8 len)
299
306
return rc ;
300
307
}
301
308
302
- dccp_pr_debug ("Confirming NN feature %d (val=%d)\n" , feature , * copy );
309
+ dccp_feat_debug (type , feature , * copy );
310
+
303
311
list_add_tail (& opt -> dccpop_node , & dmsk -> dccpms_conf );
304
312
305
313
return 0 ;
@@ -318,14 +326,19 @@ static void dccp_feat_empty_confirm(struct dccp_minisock *dmsk,
318
326
return ;
319
327
}
320
328
321
- opt -> dccpop_type = type == DCCPO_CHANGE_L ? DCCPO_CONFIRM_R :
322
- DCCPO_CONFIRM_L ;
329
+ switch (type ) {
330
+ case DCCPO_CHANGE_L : opt -> dccpop_type = DCCPO_CONFIRM_R ; break ;
331
+ case DCCPO_CHANGE_R : opt -> dccpop_type = DCCPO_CONFIRM_L ; break ;
332
+ default : pr_info ("invalid type %d\n" , type ); return ;
333
+
334
+ }
323
335
opt -> dccpop_feat = feature ;
324
336
opt -> dccpop_val = NULL ;
325
337
opt -> dccpop_len = 0 ;
326
338
327
339
/* change feature */
328
- dccp_pr_debug ("Empty confirm feature %d type %d\n" , feature , type );
340
+ dccp_pr_debug ("Empty %s(%d)\n" , dccp_feat_typename (type ), feature );
341
+
329
342
list_add_tail (& opt -> dccpop_node , & dmsk -> dccpms_conf );
330
343
}
331
344
@@ -359,7 +372,7 @@ int dccp_feat_change_recv(struct sock *sk, u8 type, u8 feature, u8 *val, u8 len)
359
372
{
360
373
int rc ;
361
374
362
- dccp_pr_debug ( "got feat change type=%d feat=%d\n" , type , feature );
375
+ dccp_feat_debug ( type , feature , * val );
363
376
364
377
/* figure out if it's SP or NN feature */
365
378
switch (feature ) {
@@ -375,6 +388,8 @@ int dccp_feat_change_recv(struct sock *sk, u8 type, u8 feature, u8 *val, u8 len)
375
388
376
389
/* XXX implement other features */
377
390
default :
391
+ dccp_pr_debug ("UNIMPLEMENTED: not handling %s(%d, ...)\n" ,
392
+ dccp_feat_typename (type ), feature );
378
393
rc = - EFAULT ;
379
394
break ;
380
395
}
@@ -403,20 +418,27 @@ int dccp_feat_confirm_recv(struct sock *sk, u8 type, u8 feature,
403
418
u8 t ;
404
419
struct dccp_opt_pend * opt ;
405
420
struct dccp_minisock * dmsk = dccp_msk (sk );
406
- int rc = 1 ;
421
+ int found = 0 ;
407
422
int all_confirmed = 1 ;
408
423
409
- dccp_pr_debug ("got feat confirm type=%d feat=%d\n" , type , feature );
410
-
411
- /* XXX sanity check type & feat */
424
+ dccp_feat_debug (type , feature , * val );
412
425
413
426
/* locate our change request */
414
- t = type == DCCPO_CONFIRM_L ? DCCPO_CHANGE_R : DCCPO_CHANGE_L ;
427
+ switch (type ) {
428
+ case DCCPO_CONFIRM_L : t = DCCPO_CHANGE_R ; break ;
429
+ case DCCPO_CONFIRM_R : t = DCCPO_CHANGE_L ; break ;
430
+ default : pr_info ("invalid type %d\n" , type );
431
+ return 1 ;
432
+
433
+ }
434
+ /* XXX sanity check feature value */
415
435
416
436
list_for_each_entry (opt , & dmsk -> dccpms_pending , dccpop_node ) {
417
437
if (!opt -> dccpop_conf && opt -> dccpop_type == t &&
418
438
opt -> dccpop_feat == feature ) {
419
- /* we found it */
439
+ found = 1 ;
440
+ dccp_pr_debug ("feature %d found\n" , opt -> dccpop_feat );
441
+
420
442
/* XXX do sanity check */
421
443
422
444
opt -> dccpop_conf = 1 ;
@@ -425,9 +447,7 @@ int dccp_feat_confirm_recv(struct sock *sk, u8 type, u8 feature,
425
447
dccp_feat_update (sk , opt -> dccpop_type ,
426
448
opt -> dccpop_feat , * val );
427
449
428
- dccp_pr_debug ("feat %d type %d confirmed %d\n" ,
429
- feature , type , * val );
430
- rc = 0 ;
450
+ /* XXX check the return value of dccp_feat_update */
431
451
break ;
432
452
}
433
453
@@ -446,9 +466,9 @@ int dccp_feat_confirm_recv(struct sock *sk, u8 type, u8 feature,
446
466
inet_csk_clear_xmit_timer (sk , ICSK_TIME_RETRANS );
447
467
}
448
468
449
- if (rc )
450
- dccp_pr_debug ("feat %d type %d never requested\n" ,
451
- feature , type );
469
+ if (! found )
470
+ dccp_pr_debug ("%s(%d, ...) never requested\n" ,
471
+ dccp_feat_typename ( type ), feature );
452
472
return 0 ;
453
473
}
454
474
@@ -583,3 +603,45 @@ int dccp_feat_init(struct dccp_minisock *dmsk)
583
603
}
584
604
585
605
EXPORT_SYMBOL_GPL (dccp_feat_init );
606
+
607
+ #ifdef CONFIG_IP_DCCP_DEBUG
608
+ const char * dccp_feat_typename (const u8 type )
609
+ {
610
+ switch (type ) {
611
+ case DCCPO_CHANGE_L : return ("ChangeL" );
612
+ case DCCPO_CONFIRM_L : return ("ConfirmL" );
613
+ case DCCPO_CHANGE_R : return ("ChangeR" );
614
+ case DCCPO_CONFIRM_R : return ("ConfirmR" );
615
+ /* the following case must not appear in feature negotation */
616
+ default : dccp_pr_debug ("unknown type %d [BUG!]\n" , type );
617
+ }
618
+ return NULL ;
619
+ }
620
+
621
+ EXPORT_SYMBOL_GPL (dccp_feat_typename );
622
+
623
+ const char * dccp_feat_name (const u8 feat )
624
+ {
625
+ static const char * feature_names [] = {
626
+ [DCCPF_RESERVED ] = "Reserved" ,
627
+ [DCCPF_CCID ] = "CCID" ,
628
+ [DCCPF_SHORT_SEQNOS ] = "Allow Short Seqnos" ,
629
+ [DCCPF_SEQUENCE_WINDOW ] = "Sequence Window" ,
630
+ [DCCPF_ECN_INCAPABLE ] = "ECN Incapable" ,
631
+ [DCCPF_ACK_RATIO ] = "Ack Ratio" ,
632
+ [DCCPF_SEND_ACK_VECTOR ] = "Send ACK Vector" ,
633
+ [DCCPF_SEND_NDP_COUNT ] = "Send NDP Count" ,
634
+ [DCCPF_MIN_CSUM_COVER ] = "Min. Csum Coverage" ,
635
+ [DCCPF_DATA_CHECKSUM ] = "Send Data Checksum" ,
636
+ };
637
+ if (feat >= DCCPF_MIN_CCID_SPECIFIC )
638
+ return "CCID-specific" ;
639
+
640
+ if (dccp_feat_is_reserved (feat ))
641
+ return feature_names [DCCPF_RESERVED ];
642
+
643
+ return feature_names [feat ];
644
+ }
645
+
646
+ EXPORT_SYMBOL_GPL (dccp_feat_name );
647
+ #endif /* CONFIG_IP_DCCP_DEBUG */
0 commit comments