# Copyright (c) 2013 The Chromium OS Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. import logging, socket from collections import namedtuple from autotest_lib.client.bin import test from autotest_lib.client.common_lib import error PROTO_FILE = '/proc/net/protocols' # Defines that python's socket lacks. IPPROTO_UDPLITE = 193 AF_BLUETOOTH = 31 BTPROTO_L2CAP = 0 BTPROTO_HCI = 1 BTPROTO_SCO = 2 BTPROTO_RFCOMM = 3 # Contains information needed to create a socket using a particular # protocol. Protocol = namedtuple('Protocol', ['name', 'domain', 'socket_type', 'proto_num']) REQUIRED = set([ Protocol('RFCOMM', AF_BLUETOOTH, socket.SOCK_STREAM, BTPROTO_RFCOMM), Protocol('RFCOMM', AF_BLUETOOTH, socket.SOCK_SEQPACKET, BTPROTO_SCO), Protocol('L2CAP', AF_BLUETOOTH, socket.SOCK_STREAM, BTPROTO_L2CAP), Protocol('HCI', AF_BLUETOOTH, socket.SOCK_RAW, BTPROTO_HCI), Protocol('PACKET', socket.AF_PACKET, socket.SOCK_DGRAM, 0), Protocol('RAWv6', socket.AF_INET6, socket.SOCK_RAW, 0), Protocol('UDPLITEv6', socket.AF_INET6, socket.SOCK_DGRAM, IPPROTO_UDPLITE), Protocol('UDPv6', socket.AF_INET6, socket.SOCK_DGRAM, 0), Protocol('TCPv6', socket.AF_INET6, socket.SOCK_STREAM, 0), Protocol('UNIX', socket.AF_UNIX, socket.SOCK_STREAM, 0), Protocol('UDP-Lite', socket.AF_INET, socket.SOCK_DGRAM, IPPROTO_UDPLITE), Protocol('PING', socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_ICMP), Protocol('RAW', socket.AF_INET, socket.SOCK_RAW, 0), Protocol('UDP', socket.AF_INET, socket.SOCK_DGRAM, 0), Protocol('TCP', socket.AF_INET, socket.SOCK_STREAM, 0), Protocol('NETLINK', socket.AF_NETLINK, socket.SOCK_DGRAM, 0), ]) class kernel_ProtocolCheck(test.test): version = 1 def _try_protocol(self, proto): """ Try to create a socket with the specified protocol. @param proto Protocol to use to create a socket. """ try: sock = socket.socket(proto.domain, proto.socket_type, proto.proto_num) sock.close() logging.info('created socket with protocol %s' % (proto.name)) except socket.error: # We don't really care if it fails, any required module should've # been loaded anyways. logging.info('failed to create socket with protocol %s' % (proto.name)) def _get_supported_protocols(self): """ Returns the set of supported protocols from /proc/net/protocols. """ f = open(PROTO_FILE) if not f: raise error.TestError('failed to open %s' % (PROTO_FILE)) lines = f.readlines()[1:] supported = set(line.split()[0] for line in lines) f.close() return supported def run_once(self): """ Check that the kernel supports all required network protocols. """ for proto in REQUIRED: # Opening a socket with a protocol should ensure that all necessary # modules get loaded. self._try_protocol(proto) supported = self._get_supported_protocols() # Check that each required protocol is supported. required = set(proto.name for proto in REQUIRED) failures = required - supported # Fail if any protocols were unsupported. if failures: raise error.TestFail('required protocols are unsupported: %s' % (", ".join(failures)))