1--TEST-- 2Multicast support: IPv6 receive options 3--EXTENSIONS-- 4sockets 5--SKIPIF-- 6<?php 7 8if (!defined('IPPROTO_IPV6')) { 9 die('skip IPv6 not available.'); 10} 11$s = socket_create(AF_INET6, SOCK_DGRAM, SOL_UDP); 12if ($s === false) { 13 die("skip unable to create socket"); 14} 15$br = socket_bind($s, '::', 0); 16socket_getsockname($s, $unused, $port); 17/* On Linux, there is no route ff00::/8 by default on lo, which makes it 18 * troublesome to send multicast traffic from lo, which we must since 19 * we're dealing with interface-local traffic... */ 20$so = @socket_set_option($s, IPPROTO_IPV6, MCAST_JOIN_GROUP, array( 21 "group" => 'ff01::114', 22 "interface" => 0, 23)); 24if ($so === false) { 25 die('skip unable to join multicast group on any interface.'); 26} 27$r = socket_sendto($s, $m = "testing packet", strlen($m), 0, 'ff01::114', $port); 28if ($r === false) { 29 die('skip unable to send multicast packet.'); 30} 31 32if (!defined("MCAST_JOIN_SOURCE_GROUP")) 33 die('skip source operations are unavailable'); 34 35$so = @socket_set_option($s, IPPROTO_IPV6, MCAST_LEAVE_GROUP, array( 36 "group" => 'ff01::114', 37 "interface" => 0, 38)); 39$so = @socket_set_option($s, IPPROTO_IPV6, MCAST_JOIN_SOURCE_GROUP, array( 40 "group" => 'ff01::114', 41 "interface" => 0, 42 "source" => '2001::dead:beef', 43)); 44if ($so === false) { 45 die('skip protocol independent multicast API is unavailable.'); 46} 47--FILE-- 48<?php 49include __DIR__."/mcast_helpers.php.inc"; 50$domain = AF_INET6; 51$level = IPPROTO_IPV6; 52$interface = 0; 53$mcastaddr = 'ff01::114'; 54$sblock = "?"; 55 56echo "creating send socket\n"; 57$sends1 = socket_create($domain, SOCK_DGRAM, SOL_UDP) or die("err"); 58var_dump($sends1); 59 60echo "creating receive socket\n"; 61$s = socket_create($domain, SOCK_DGRAM, SOL_UDP) or die("err"); 62var_dump($s); 63$br = socket_bind($s, '::0', 0) or die("err"); 64var_dump($br); 65socket_getsockname($s, $unused, $port); 66 67$so = socket_set_option($s, $level, MCAST_JOIN_GROUP, array( 68 "group" => $mcastaddr, 69 "interface" => $interface, 70)) or die("err"); 71var_dump($so); 72 73$r = socket_sendto($sends1, $m = "testing packet", strlen($m), 0, $mcastaddr, $port); 74var_dump($r); 75checktimeout($s, 500); 76$r = socket_recvfrom($s, $str, 2000, 0, $from, $fromPort); 77var_dump($r, $str, $from); 78$sblock = $from; 79 80$r = socket_sendto($sends1, $m = "initial packet", strlen($m), 0, $mcastaddr, $port); 81var_dump($r); 82 83$i = 0; 84checktimeout($s, 500); 85while (($str = socket_read($s, 3000)) !== FALSE) { 86 $i++; 87 echo "$i> ", $str, "\n"; 88 89if ($i == 1) { 90 echo "leaving group\n"; 91 $so = socket_set_option($s, $level, MCAST_LEAVE_GROUP, array( 92 "group" => $mcastaddr, 93 "interface" => $interface, 94 )); 95 var_dump($so); 96 $r = socket_sendto($sends1, $m = "ignored mcast packet", strlen($m), 0, $mcastaddr, $port); 97 var_dump($r); 98 $r = socket_sendto($sends1, $m = "unicast packet", strlen($m), 0, "::1", $port); 99 var_dump($r); 100} 101if ($i == 2) { 102 echo "re-joining group\n"; 103 $so = socket_set_option($s, $level, MCAST_JOIN_GROUP, array( 104 "group" => $mcastaddr, 105 "interface" => $interface, 106 )); 107 var_dump($so); 108 $r = socket_sendto($sends1, $m = "mcast packet", strlen($m), 0, $mcastaddr, $port); 109 var_dump($r); 110} 111if ($i == 3) { 112 echo "blocking source\n"; 113 $so = socket_set_option($s, $level, MCAST_BLOCK_SOURCE, array( 114 "group" => $mcastaddr, 115 "interface" => $interface, 116 "source" => $sblock, 117 )); 118 var_dump($so); 119 $r = socket_sendto($sends1, $m = "ignored packet (blocked source)", strlen($m), 0, $mcastaddr, $port); 120 var_dump($r); 121 $r = socket_sendto($sends1, $m = "unicast packet", strlen($m), 0, "::1", $port); 122 var_dump($r); 123} 124if ($i == 4) { 125 echo "unblocking source\n"; 126 $so = socket_set_option($s, $level, MCAST_UNBLOCK_SOURCE, array( 127 "group" => $mcastaddr, 128 "interface" => $interface, 129 "source" => $sblock, 130 )); 131 var_dump($so); 132 $r = socket_sendto($sends1, $m = "mcast packet", strlen($m), 0, $mcastaddr, $port); 133 var_dump($r); 134} 135if ($i == 5) { 136 echo "leaving group\n"; 137 $so = socket_set_option($s, $level, MCAST_LEAVE_GROUP, array( 138 "group" => $mcastaddr, 139 "interface" => $interface, 140 )); 141 var_dump($so); 142 $r = socket_sendto($sends1, $m = "ignored mcast packet", strlen($m), 0, $mcastaddr, $port); 143 var_dump($r); 144 $r = socket_sendto($sends1, $m = "unicast packet", strlen($m), 0, "::1", $port); 145 var_dump($r); 146} 147if ($i == 6) { 148 echo "joining source group\n"; 149 $so = socket_set_option($s, $level, MCAST_JOIN_SOURCE_GROUP, array( 150 "group" => $mcastaddr, 151 "interface" => $interface, 152 "source" => $sblock, 153 )); 154 var_dump($so); 155 $r = socket_sendto($sends1, $m = "mcast packet from desired source", strlen($m), 0, $mcastaddr, $port); 156 var_dump($r); 157} 158if ($i == 7) { 159 echo "leaving source group\n"; 160 $so = socket_set_option($s, $level, MCAST_LEAVE_SOURCE_GROUP, array( 161 "group" => $mcastaddr, 162 "interface" => $interface, 163 "source" => $sblock, 164 )); 165 var_dump($so); 166 $r = socket_sendto($sends1, $m = "ignored mcast packet", strlen($m), 0, $mcastaddr, $port); 167 var_dump($r); 168 $r = socket_sendto($sends1, $m = "unicast packet", strlen($m), 0, "::1", $port); 169 var_dump($r); 170} 171if ($i == 8) { 172 /*echo "joining source group\n"; 173 $so = socket_set_option($s, $level, MCAST_JOIN_SOURCE_GROUP, array( 174 "group" => $mcastaddr, 175 "interface" => $interface, 176 "source" => $sblock, 177 )); 178 var_dump($so);*/ 179 break; 180} 181 182} 183?> 184--EXPECTF-- 185creating send socket 186object(Socket)#%d (0) { 187} 188creating receive socket 189object(Socket)#%d (0) { 190} 191bool(true) 192bool(true) 193int(14) 194int(14) 195string(14) "testing packet" 196string(%d) "%s" 197int(14) 1981> initial packet 199leaving group 200bool(true) 201int(20) 202int(14) 2032> unicast packet 204re-joining group 205bool(true) 206int(12) 2073> mcast packet 208blocking source 209bool(true) 210int(31) 211int(14) 2124> unicast packet 213unblocking source 214bool(true) 215int(12) 2165> mcast packet 217leaving group 218bool(true) 219int(20) 220int(14) 2216> unicast packet 222joining source group 223bool(true) 224int(32) 2257> mcast packet from desired source 226leaving source group 227bool(true) 228int(20) 229int(14) 2308> unicast packet 231