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