def testFlowLabel(self): s = net_test.IPv6PingSocket() # Specifying a flowlabel without having set IPV6_FLOWINFO_SEND succeeds but # the flow label in the packet is not set. s.sendto(net_test.IPV6_PING, (net_test.IPV6_ADDR, 93, 0xdead, 0)) self.assertValidPingResponse(s, net_test.IPV6_PING) # Checks flow label==0. # If IPV6_FLOWINFO_SEND is set on the socket, attempting to set a flow label # that is not registered with the flow manager should return EINVAL... s.setsockopt(net_test.SOL_IPV6, net_test.IPV6_FLOWINFO_SEND, 1) # ... but this doesn't work yet. if False: self.assertRaisesErrno(errno.EINVAL, s.sendto, net_test.IPV6_PING, (net_test.IPV6_ADDR, 93, 0xdead, 0)) # After registering the flow label, it gets sent properly, appears in the # output packet, and is returned in the response. net_test.SetFlowLabel(s, net_test.IPV6_ADDR, 0xdead) self.assertEqual(1, s.getsockopt(net_test.SOL_IPV6, net_test.IPV6_FLOWINFO_SEND)) s.sendto(net_test.IPV6_PING, (net_test.IPV6_ADDR, 93, 0xdead, 0)) _, src = s.recvfrom(32768) _, _, flowlabel, _ = src self.assertEqual(0xdead, flowlabel & 0xfffff)
def CheckPktinfoRouting(self, version): for _ in xrange(self.ITERATIONS): for netid in self.tuns: family = self.GetProtocolFamily(version) s = net_test.UDPSocket(family) if version == 6: # Create a flowlabel so we can use it. net_test.SetFlowLabel(s, net_test.IPV6_ADDR, 0xbeef) # Specify some arbitrary options. cmsgs = [ (net_test.SOL_IPV6, IPV6_HOPLIMIT, 39), (net_test.SOL_IPV6, IPV6_TCLASS, 0x83), (net_test.SOL_IPV6, IPV6_FLOWINFO, int(htonl(0xbeef))), ] else: # Support for setting IPv4 TOS and TTL via cmsg only appeared in 3.13. cmsgs = [] s.setsockopt(net_test.SOL_IP, IP_TTL, 39) s.setsockopt(net_test.SOL_IP, IP_TOS, 0x83) dstaddr = self.GetRemoteAddress(version) self.SendOnNetid(version, s, dstaddr, 53, netid, UDP_PAYLOAD, cmsgs) sport = s.getsockname()[1] srcaddr = self.MyAddress(version, netid) desc, expected = packets.UDPWithOptions(version, srcaddr, dstaddr, sport=sport) msg = "IPv%d UDP using pktinfo routing: expected %s on %s" % ( version, desc, self.GetInterfaceName(netid)) self.ExpectPacketOn(netid, msg, expected)
def testIPv6StickyPktinfo(self): for _ in xrange(self.ITERATIONS): for netid in self.tuns: s = net_test.UDPSocket(AF_INET6) # Set a flowlabel. net_test.SetFlowLabel(s, net_test.IPV6_ADDR, 0xdead) s.setsockopt(net_test.SOL_IPV6, net_test.IPV6_FLOWINFO_SEND, 1) # Set some destination options. nonce = "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c" dstopts = "".join([ "\x11\x02", # Next header=UDP, 24 bytes of options. "\x01\x06", "\x00" * 6, # PadN, 6 bytes of padding. "\x8b\x0c", # ILNP nonce, 12 bytes. nonce ]) s.setsockopt(net_test.SOL_IPV6, IPV6_DSTOPTS, dstopts) s.setsockopt(net_test.SOL_IPV6, IPV6_UNICAST_HOPS, 255) pktinfo = multinetwork_base.MakePktInfo( 6, None, self.ifindices[netid]) # Set the sticky pktinfo option. s.setsockopt(net_test.SOL_IPV6, IPV6_PKTINFO, pktinfo) # Specify the flowlabel in the destination address. s.sendto(UDP_PAYLOAD, (net_test.IPV6_ADDR, 53, 0xdead, 0)) sport = s.getsockname()[1] srcaddr = self.MyAddress(6, netid) expected = (scapy.IPv6( src=srcaddr, dst=net_test.IPV6_ADDR, fl=0xdead, hlim=255) / scapy.IPv6ExtHdrDestOpt(options=[ scapy.PadN(optdata="\x00\x00\x00\x00\x00\x00"), scapy.HBHOptUnknown(otype=0x8b, optdata=nonce) ]) / scapy.UDP(sport=sport, dport=53) / UDP_PAYLOAD) msg = "IPv6 UDP using sticky pktinfo: expected UDP packet on %s" % ( self.GetInterfaceName(netid)) self.ExpectPacketOn(netid, msg, expected)