1*631d525dSJonathan T. Looney#!/usr/bin/env python 2*631d525dSJonathan T. Looney#- 3*631d525dSJonathan T. Looney# SPDX-License-Identifier: BSD-2-Clause 4*631d525dSJonathan T. Looney# 5*631d525dSJonathan T. Looney# Copyright (c) 2020 Netflix, Inc. 6*631d525dSJonathan T. Looney# 7*631d525dSJonathan T. Looney# Redistribution and use in source and binary forms, with or without 8*631d525dSJonathan T. Looney# modification, are permitted provided that the following conditions 9*631d525dSJonathan T. Looney# are met: 10*631d525dSJonathan T. Looney# 1. Redistributions of source code must retain the above copyright 11*631d525dSJonathan T. Looney# notice, this list of conditions and the following disclaimer. 12*631d525dSJonathan T. Looney# 2. Redistributions in binary form must reproduce the above copyright 13*631d525dSJonathan T. Looney# notice, this list of conditions and the following disclaimer in the 14*631d525dSJonathan T. Looney# documentation and/or other materials provided with the distribution. 15*631d525dSJonathan T. Looney# 16*631d525dSJonathan T. Looney# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17*631d525dSJonathan T. Looney# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18*631d525dSJonathan T. Looney# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19*631d525dSJonathan T. Looney# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20*631d525dSJonathan T. Looney# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21*631d525dSJonathan T. Looney# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22*631d525dSJonathan T. Looney# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23*631d525dSJonathan T. Looney# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24*631d525dSJonathan T. Looney# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25*631d525dSJonathan T. Looney# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26*631d525dSJonathan T. Looney# SUCH DAMAGE. 27*631d525dSJonathan T. Looney# 28*631d525dSJonathan T. Looney# $FreeBSD$ 29*631d525dSJonathan T. Looney# 30*631d525dSJonathan T. Looney 31*631d525dSJonathan T. Looneyimport socket 32*631d525dSJonathan T. Looneyimport os 33*631d525dSJonathan T. Looneyimport sys 34*631d525dSJonathan T. Looneyfrom subprocess import check_output 35*631d525dSJonathan T. Looneyfrom time import sleep 36*631d525dSJonathan T. Looney 37*631d525dSJonathan T. LooneyV4HOST = '127.0.0.1' 38*631d525dSJonathan T. LooneyV6HOST = '::1' 39*631d525dSJonathan T. LooneyTCPPORT = 65432 40*631d525dSJonathan T. LooneyUNIXSOCK = '/tmp/testsock' 41*631d525dSJonathan T. LooneyTYPE = socket.SOCK_STREAM 42*631d525dSJonathan T. Looney 43*631d525dSJonathan T. Looneyclass GenericTest(object): 44*631d525dSJonathan T. Looney def __init__(self): 45*631d525dSJonathan T. Looney raise NotImplementedError("Subclass must override the __init__ method") 46*631d525dSJonathan T. Looney def setup(self, af, addr): 47*631d525dSJonathan T. Looney self.sockets = [] 48*631d525dSJonathan T. Looney self.ls = None 49*631d525dSJonathan T. Looney self.ls = socket.socket(af, TYPE) 50*631d525dSJonathan T. Looney self.ls.bind(addr) 51*631d525dSJonathan T. Looney self.ls.listen(2) 52*631d525dSJonathan T. Looney self.af = af 53*631d525dSJonathan T. Looney self.addr = addr 54*631d525dSJonathan T. Looney def doTest(self, cnt): 55*631d525dSJonathan T. Looney rv = 0 56*631d525dSJonathan T. Looney for i in range(0, cnt): 57*631d525dSJonathan T. Looney try: 58*631d525dSJonathan T. Looney s = socket.socket(self.af, TYPE) 59*631d525dSJonathan T. Looney s.connect(self.addr) 60*631d525dSJonathan T. Looney except: 61*631d525dSJonathan T. Looney continue 62*631d525dSJonathan T. Looney self.sockets.append(s) 63*631d525dSJonathan T. Looney rv += 1 64*631d525dSJonathan T. Looney return rv 65*631d525dSJonathan T. Looney def __del__(self): 66*631d525dSJonathan T. Looney for s in self.sockets: 67*631d525dSJonathan T. Looney s.close() 68*631d525dSJonathan T. Looney if self.ls is not None: 69*631d525dSJonathan T. Looney self.ls.close() 70*631d525dSJonathan T. Looney 71*631d525dSJonathan T. Looneyclass IPv4Test(GenericTest): 72*631d525dSJonathan T. Looney def __init__(self): 73*631d525dSJonathan T. Looney super(IPv4Test, self).setup(socket.AF_INET, (V4HOST, TCPPORT)) 74*631d525dSJonathan T. Looney 75*631d525dSJonathan T. Looneyclass IPv6Test(GenericTest): 76*631d525dSJonathan T. Looney def __init__(self): 77*631d525dSJonathan T. Looney super(IPv6Test, self).setup(socket.AF_INET6, (V6HOST, TCPPORT)) 78*631d525dSJonathan T. Looney 79*631d525dSJonathan T. Looneyclass UnixTest(GenericTest): 80*631d525dSJonathan T. Looney def __init__(self): 81*631d525dSJonathan T. Looney super(UnixTest, self).setup(socket.AF_UNIX, UNIXSOCK) 82*631d525dSJonathan T. Looney def __del__(self): 83*631d525dSJonathan T. Looney super(UnixTest, self).__del__() 84*631d525dSJonathan T. Looney os.remove(UNIXSOCK) 85*631d525dSJonathan T. Looney 86*631d525dSJonathan T. Looneyclass LogChecker(): 87*631d525dSJonathan T. Looney def __init__(self): 88*631d525dSJonathan T. Looney # Figure out how big the dmesg buffer is. 89*631d525dSJonathan T. Looney self.dmesgOff = len(check_output("/sbin/dmesg")) 90*631d525dSJonathan T. Looney 91*631d525dSJonathan T. Looney def checkForMsg(self, expected): 92*631d525dSJonathan T. Looney newOff = self.dmesgOff 93*631d525dSJonathan T. Looney for i in range(0, 3): 94*631d525dSJonathan T. Looney dmesg = check_output("/sbin/dmesg") 95*631d525dSJonathan T. Looney newOff = len(dmesg) 96*631d525dSJonathan T. Looney if newOff >= self.dmesgOff: 97*631d525dSJonathan T. Looney dmesg = dmesg[self.dmesgOff:] 98*631d525dSJonathan T. Looney for line in dmesg.splitlines(): 99*631d525dSJonathan T. Looney try: 100*631d525dSJonathan T. Looney if str(line).find(expected) >= 0: 101*631d525dSJonathan T. Looney self.dmesgOff = newOff 102*631d525dSJonathan T. Looney return True 103*631d525dSJonathan T. Looney except: 104*631d525dSJonathan T. Looney pass 105*631d525dSJonathan T. Looney sleep(0.5) 106*631d525dSJonathan T. Looney self.dmesgOff = newOff 107*631d525dSJonathan T. Looney return False 108*631d525dSJonathan T. Looney 109*631d525dSJonathan T. Looneydef main(): 110*631d525dSJonathan T. Looney ip4 = IPv4Test() 111*631d525dSJonathan T. Looney ip6 = IPv6Test() 112*631d525dSJonathan T. Looney lcl = UnixTest() 113*631d525dSJonathan T. Looney lc = LogChecker() 114*631d525dSJonathan T. Looney failure = False 115*631d525dSJonathan T. Looney 116*631d525dSJonathan T. Looney STDLOGMSG = "Listen queue overflow: 4 already in queue awaiting acceptance (1 occurrences)" 117*631d525dSJonathan T. Looney 118*631d525dSJonathan T. Looney V4LOGMSG = "(%s:%d (proto 6)): %s" % (V4HOST, TCPPORT, STDLOGMSG) 119*631d525dSJonathan T. Looney ip4.doTest(5) 120*631d525dSJonathan T. Looney if not lc.checkForMsg(V4LOGMSG): 121*631d525dSJonathan T. Looney failure = True 122*631d525dSJonathan T. Looney sys.stderr.write("IPv4 log message not seen\n") 123*631d525dSJonathan T. Looney else: 124*631d525dSJonathan T. Looney ip4.doTest(1) 125*631d525dSJonathan T. Looney if lc.checkForMsg(V4LOGMSG): 126*631d525dSJonathan T. Looney failure = True 127*631d525dSJonathan T. Looney sys.stderr.write("Subsequent IPv4 log message not suppressed\n") 128*631d525dSJonathan T. Looney 129*631d525dSJonathan T. Looney V6LOGMSG = "([%s]:%d (proto 6)): %s" % (V6HOST, TCPPORT, STDLOGMSG) 130*631d525dSJonathan T. Looney ip6.doTest(5) 131*631d525dSJonathan T. Looney if not lc.checkForMsg(V6LOGMSG): 132*631d525dSJonathan T. Looney failure = True 133*631d525dSJonathan T. Looney sys.stderr.write("IPv6 log message not seen\n") 134*631d525dSJonathan T. Looney else: 135*631d525dSJonathan T. Looney ip6.doTest(1) 136*631d525dSJonathan T. Looney if lc.checkForMsg(V6LOGMSG): 137*631d525dSJonathan T. Looney failure = True 138*631d525dSJonathan T. Looney sys.stderr.write("Subsequent IPv6 log message not suppressed\n") 139*631d525dSJonathan T. Looney 140*631d525dSJonathan T. Looney UNIXLOGMSG = "(local:%s): %s" % (UNIXSOCK, STDLOGMSG) 141*631d525dSJonathan T. Looney lcl.doTest(5) 142*631d525dSJonathan T. Looney if not lc.checkForMsg(UNIXLOGMSG): 143*631d525dSJonathan T. Looney failure = True 144*631d525dSJonathan T. Looney sys.stderr.write("Unix socket log message not seen\n") 145*631d525dSJonathan T. Looney else: 146*631d525dSJonathan T. Looney lcl.doTest(1) 147*631d525dSJonathan T. Looney if lc.checkForMsg(UNIXLOGMSG): 148*631d525dSJonathan T. Looney failure = True 149*631d525dSJonathan T. Looney sys.stderr.write("Subsequent Unix socket log message not suppressed\n") 150*631d525dSJonathan T. Looney 151*631d525dSJonathan T. Looney if failure: 152*631d525dSJonathan T. Looney sys.exit(1) 153*631d525dSJonathan T. Looney sys.exit(0) 154*631d525dSJonathan T. Looney 155*631d525dSJonathan T. Looneyif __name__ == '__main__': 156*631d525dSJonathan T. Looney main() 157