@@ -493,6 +493,96 @@ def test_initiate_tag_check(self):
493493 assert r .getlayer (sp .SCTPChunkInitAck )
494494 assert r .getlayer (sp .SCTP ).tag == 42
495495
496+ class TestSCTP_SRV (VnetTestTemplate ):
497+ REQUIRED_MODULES = ["sctp" , "pf" ]
498+ TOPOLOGY = {
499+ "vnet1" : {"ifaces" : ["if1" ]},
500+ "vnet2" : {"ifaces" : ["if1" ]},
501+ "if1" : {"prefixes4" : [("192.0.2.1/24" , "192.0.2.2/24" )]},
502+ }
503+
504+ def vnet2_handler (self , vnet ):
505+ ToolsHelper .print_output ("/sbin/pfctl -e" )
506+ ToolsHelper .pf_rules ([
507+ "set state-policy if-bound" ,
508+ "pass inet proto sctp" ,
509+ "pass on lo" ])
510+
511+ # Start an SCTP server process, pipe the ppid + data back to the other vnet?
512+ srv = SCTPServer (socket .AF_INET , port = 1234 )
513+ while True :
514+ srv .accept (vnet )
515+
516+ @pytest .mark .require_user ("root" )
517+ @pytest .mark .require_progs (["scapy" ])
518+ def test_initiate_tag_check (self ):
519+ # Ensure we don't send ABORTs in response to the other end's INIT_ACK
520+ # That'd interfere with our test.
521+ ToolsHelper .print_output ("/sbin/sysctl net.inet.sctp.blackhole=2" )
522+
523+ import scapy .all as sp
524+
525+ packet = sp .IP (src = "192.0.2.1" , dst = "192.0.2.2" ) \
526+ / sp .SCTP (sport = 1234 , dport = 1234 ) \
527+ / sp .SCTPChunkInit (init_tag = 1 , n_in_streams = 1 , n_out_streams = 1 , a_rwnd = 1500 )
528+ packet .show ()
529+
530+ r = sp .sr1 (packet , timeout = 3 )
531+ assert r
532+ r .show ()
533+ assert r .getlayer (sp .SCTP )
534+ assert r .getlayer (sp .SCTPChunkInitAck )
535+ assert r .getlayer (sp .SCTP ).tag == 1
536+
537+ # Send another INIT with the same initiate tag, expect another init ack
538+ packet = sp .IP (src = "192.0.2.1" , dst = "192.0.2.2" ) \
539+ / sp .SCTP (sport = 1234 , dport = 1234 ) \
540+ / sp .SCTPChunkInit (init_tag = 1 , n_in_streams = 1 , n_out_streams = 1 , a_rwnd = 1500 )
541+ packet .show ()
542+
543+ r = sp .sr1 (packet , timeout = 3 )
544+ assert r
545+ r .show ()
546+ assert r .getlayer (sp .SCTP )
547+ assert r .getlayer (sp .SCTPChunkInitAck )
548+ assert r .getlayer (sp .SCTP ).tag == 1
549+
550+ # Send an INIT with a different initiate tag, expect another init ack
551+ packet = sp .IP (src = "192.0.2.1" , dst = "192.0.2.2" ) \
552+ / sp .SCTP (sport = 1234 , dport = 1234 ) \
553+ / sp .SCTPChunkInit (init_tag = 42 , n_in_streams = 1 , n_out_streams = 1 , a_rwnd = 1500 )
554+ packet .show ()
555+
556+ r = sp .sr1 (packet , timeout = 3 )
557+ assert r
558+ r .show ()
559+ assert r .getlayer (sp .SCTP )
560+ assert r .getlayer (sp .SCTPChunkInitAck )
561+ assert r .getlayer (sp .SCTP ).tag == 42
562+
563+ @pytest .mark .require_user ("root" )
564+ @pytest .mark .require_progs (["scapy" ])
565+ def test_too_many_add_ip (self ):
566+ import scapy .all as sp
567+ DEPTH = 90
568+ params = []
569+ for i in range (0 , DEPTH ):
570+ ch = sp .SCTPChunkParamAddIPAddr (len = (DEPTH - i ) * 8 )
571+ params .append (ch )
572+ packet = sp .IP (src = "192.0.2.1" , dst = "192.0.2.2" ) \
573+ / sp .SCTP (sport = 4321 , dport = 1234 ) \
574+ / sp .SCTPChunkInit (init_tag = 1 , n_in_streams = 1 , n_out_streams = 1 , a_rwnd = 1500 ,
575+ params = params )
576+ packet .show ()
577+ sp .hexdump (packet )
578+ print ("len %d" % len (packet ))
579+
580+ r = sp .sr1 (packet , timeout = 3 )
581+ # We should not get a reply to this
582+ if r :
583+ r .show ()
584+ assert not r
585+
496586class TestSCTPv6 (VnetTestTemplate ):
497587 REQUIRED_MODULES = ["sctp" , "pf" ]
498588 TOPOLOGY = {
0 commit comments