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