blob: 461d2abdf91ba9433849b1cb54ebee6cd756fd46 [file] [log] [blame]
# 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)))