1#!/usr/bin/python3 2# 3# Copyright 2018 The Android Open Source Project 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16 17import unittest 18 19import errno 20from socket import * 21 22import multinetwork_base 23import net_test 24 25_TEST_IP4_ADDR = "192.0.2.1" 26_TEST_IP6_ADDR = "2001:db8::" 27 28 29# Regression tests for interactions between kernel networking and netfilter 30# 31# These tests were added to ensure that the lookup path for local-ICMP errors 32# do not cause failures. Specifically, local-ICMP packets do not have a 33# net_device in the skb, and has been known to trigger bugs in surrounding code. 34class NetilterRejectTargetTest(multinetwork_base.MultiNetworkBaseTest): 35 36 def setUp(self): 37 multinetwork_base.MultiNetworkBaseTest.setUp(self) 38 net_test.RunIptablesCommand(4, "-A OUTPUT -d " + _TEST_IP4_ADDR + " -j REJECT") 39 net_test.RunIptablesCommand(6, "-A OUTPUT -d " + _TEST_IP6_ADDR + " -j REJECT") 40 41 def tearDown(self): 42 net_test.RunIptablesCommand(4, "-D OUTPUT -d " + _TEST_IP4_ADDR + " -j REJECT") 43 net_test.RunIptablesCommand(6, "-D OUTPUT -d " + _TEST_IP6_ADDR + " -j REJECT") 44 multinetwork_base.MultiNetworkBaseTest.tearDown(self) 45 46 # Test a rejected TCP connect. The responding ICMP may not have skb->dev set. 47 # This tests the local-ICMP output-input path. 48 def CheckRejectedTcp(self, version, addr): 49 sock = net_test.TCPSocket(net_test.GetAddressFamily(version)) 50 netid = self.RandomNetid() 51 self.SelectInterface(sock, netid, "mark") 52 53 # Expect this to fail with ICMP unreachable 54 try: 55 sock.connect((addr, 53)) 56 except IOError: 57 pass 58 sock.close() 59 60 def testRejectTcp4(self): 61 self.CheckRejectedTcp(4, _TEST_IP4_ADDR) 62 63 def testRejectTcp6(self): 64 self.CheckRejectedTcp(6, _TEST_IP6_ADDR) 65 66 # Test a rejected UDP connect. The responding ICMP may not have skb->dev set. 67 # This tests the local-ICMP output-input path. 68 def CheckRejectedUdp(self, version, addr): 69 sock = net_test.UDPSocket(net_test.GetAddressFamily(version)) 70 netid = self.RandomNetid() 71 self.SelectInterface(sock, netid, "mark") 72 73 # Expect this to fail with ICMP unreachable 74 try: 75 sock.sendto(net_test.UDP_PAYLOAD, (addr, 53)) 76 except IOError: 77 pass 78 sock.close() 79 80 def testRejectUdp4(self): 81 self.CheckRejectedUdp(4, _TEST_IP4_ADDR) 82 83 def testRejectUdp6(self): 84 self.CheckRejectedUdp(6, _TEST_IP6_ADDR) 85 86 87if __name__ == "__main__": 88 unittest.main()