1#!/usr/bin/python 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 59 def testRejectTcp4(self): 60 self.CheckRejectedTcp(4, _TEST_IP4_ADDR) 61 62 def testRejectTcp6(self): 63 self.CheckRejectedTcp(6, _TEST_IP6_ADDR) 64 65 # Test a rejected UDP connect. The responding ICMP may not have skb->dev set. 66 # This tests the local-ICMP output-input path. 67 def CheckRejectedUdp(self, version, addr): 68 sock = net_test.UDPSocket(net_test.GetAddressFamily(version)) 69 netid = self.RandomNetid() 70 self.SelectInterface(sock, netid, "mark") 71 72 # Expect this to fail with ICMP unreachable 73 try: 74 sock.sendto(net_test.UDP_PAYLOAD, (addr, 53)) 75 except IOError: 76 pass 77 78 def testRejectUdp4(self): 79 self.CheckRejectedUdp(4, _TEST_IP4_ADDR) 80 81 def testRejectUdp6(self): 82 self.CheckRejectedUdp(6, _TEST_IP6_ADDR) 83 84 85if __name__ == "__main__": 86 unittest.main()