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--FILE-- 50<?php 51include __DIR__."/mcast_helpers.php.inc"; 52$domain = AF_INET6; 53$level = IPPROTO_IPV6; 54$interface = 0; 55$mcastaddr = 'ff01::114'; 56$sblock = "?"; 57 58echo "creating send socket\n"; 59$sends1 = socket_create($domain, SOCK_DGRAM, SOL_UDP) or die("err"); 60var_dump($sends1); 61 62echo "creating receive socket\n"; 63$s = socket_create($domain, SOCK_DGRAM, SOL_UDP) or die("err"); 64var_dump($s); 65$br = socket_bind($s, '::0', 0) or die("err"); 66var_dump($br); 67socket_getsockname($s, $unused, $port); 68 69$so = socket_set_option($s, $level, MCAST_JOIN_GROUP, array( 70 "group" => $mcastaddr, 71 "interface" => $interface, 72)) or die("err"); 73var_dump($so); 74 75$r = socket_sendto($sends1, $m = "testing packet", strlen($m), 0, $mcastaddr, $port); 76var_dump($r); 77checktimeout($s, 500); 78$r = socket_recvfrom($s, $str, 2000, 0, $from, $fromPort); 79var_dump($r, $str, $from); 80$sblock = $from; 81 82$r = socket_sendto($sends1, $m = "initial packet", strlen($m), 0, $mcastaddr, $port); 83var_dump($r); 84 85$i = 0; 86checktimeout($s, 500); 87while (($str = socket_read($s, 3000)) !== FALSE) { 88 $i++; 89 echo "$i> ", $str, "\n"; 90 91if ($i == 1) { 92 echo "leaving group\n"; 93 $so = socket_set_option($s, $level, MCAST_LEAVE_GROUP, array( 94 "group" => $mcastaddr, 95 "interface" => $interface, 96 )); 97 var_dump($so); 98 $r = socket_sendto($sends1, $m = "ignored mcast packet", strlen($m), 0, $mcastaddr, $port); 99 var_dump($r); 100 $r = socket_sendto($sends1, $m = "unicast packet", strlen($m), 0, "::1", $port); 101 var_dump($r); 102} 103if ($i == 2) { 104 echo "re-joining group\n"; 105 $so = socket_set_option($s, $level, MCAST_JOIN_GROUP, array( 106 "group" => $mcastaddr, 107 "interface" => $interface, 108 )); 109 var_dump($so); 110 $r = socket_sendto($sends1, $m = "mcast packet", strlen($m), 0, $mcastaddr, $port); 111 var_dump($r); 112} 113if ($i == 3) { 114 echo "blocking source\n"; 115 $so = socket_set_option($s, $level, MCAST_BLOCK_SOURCE, array( 116 "group" => $mcastaddr, 117 "interface" => $interface, 118 "source" => $sblock, 119 )); 120 var_dump($so); 121 $r = socket_sendto($sends1, $m = "ignored packet (blocked source)", strlen($m), 0, $mcastaddr, $port); 122 var_dump($r); 123 $r = socket_sendto($sends1, $m = "unicast packet", strlen($m), 0, "::1", $port); 124 var_dump($r); 125} 126if ($i == 4) { 127 echo "unblocking source\n"; 128 $so = socket_set_option($s, $level, MCAST_UNBLOCK_SOURCE, array( 129 "group" => $mcastaddr, 130 "interface" => $interface, 131 "source" => $sblock, 132 )); 133 var_dump($so); 134 $r = socket_sendto($sends1, $m = "mcast packet", strlen($m), 0, $mcastaddr, $port); 135 var_dump($r); 136} 137if ($i == 5) { 138 echo "leaving group\n"; 139 $so = socket_set_option($s, $level, MCAST_LEAVE_GROUP, array( 140 "group" => $mcastaddr, 141 "interface" => $interface, 142 )); 143 var_dump($so); 144 $r = socket_sendto($sends1, $m = "ignored mcast packet", strlen($m), 0, $mcastaddr, $port); 145 var_dump($r); 146 $r = socket_sendto($sends1, $m = "unicast packet", strlen($m), 0, "::1", $port); 147 var_dump($r); 148} 149if ($i == 6) { 150 echo "joining source group\n"; 151 $so = socket_set_option($s, $level, MCAST_JOIN_SOURCE_GROUP, array( 152 "group" => $mcastaddr, 153 "interface" => $interface, 154 "source" => $sblock, 155 )); 156 var_dump($so); 157 $r = socket_sendto($sends1, $m = "mcast packet from desired source", strlen($m), 0, $mcastaddr, $port); 158 var_dump($r); 159} 160if ($i == 7) { 161 echo "leaving source group\n"; 162 $so = socket_set_option($s, $level, MCAST_LEAVE_SOURCE_GROUP, array( 163 "group" => $mcastaddr, 164 "interface" => $interface, 165 "source" => $sblock, 166 )); 167 var_dump($so); 168 $r = socket_sendto($sends1, $m = "ignored mcast packet", strlen($m), 0, $mcastaddr, $port); 169 var_dump($r); 170 $r = socket_sendto($sends1, $m = "unicast packet", strlen($m), 0, "::1", $port); 171 var_dump($r); 172} 173if ($i == 8) { 174 /*echo "joining source group\n"; 175 $so = socket_set_option($s, $level, MCAST_JOIN_SOURCE_GROUP, array( 176 "group" => $mcastaddr, 177 "interface" => $interface, 178 "source" => $sblock, 179 )); 180 var_dump($so);*/ 181 break; 182} 183 184} 185?> 186--EXPECTF-- 187creating send socket 188object(Socket)#%d (0) { 189} 190creating receive socket 191object(Socket)#%d (0) { 192} 193bool(true) 194bool(true) 195int(14) 196int(14) 197string(14) "testing packet" 198string(%d) "%s" 199int(14) 2001> initial packet 201leaving group 202bool(true) 203int(20) 204int(14) 2052> unicast packet 206re-joining group 207bool(true) 208int(12) 2093> mcast packet 210blocking source 211bool(true) 212int(31) 213int(14) 2144> unicast packet 215unblocking source 216bool(true) 217int(12) 2185> mcast packet 219leaving group 220bool(true) 221int(20) 222int(14) 2236> unicast packet 224joining source group 225bool(true) 226int(32) 2277> mcast packet from desired source 228leaving source group 229bool(true) 230int(20) 231int(14) 2328> unicast packet 233