def testCstructOffset(self): TestStruct = cstruct.Struct("TestStruct", "B16si16AH", "byte1 string2 int3 ascii4 word5") nullstr = "hello" + (16 - len("hello")) * "\x00" t = TestStruct((2, nullstr, 12345, nullstr, 33210)) self.assertEquals(0, t.offset("byte1")) self.assertEquals(1, t.offset("string2")) # sizeof(byte) self.assertEquals(17, t.offset("int3")) # sizeof(byte) + 16*sizeof(char) # The integer is automatically padded by the struct module # to match native alignment. # offset = sizeof(byte) + 16*sizeof(char) + padding + sizeof(int) self.assertEquals(24, t.offset("ascii4")) self.assertEquals(40, t.offset("word5")) self.assertRaises(KeyError, t.offset, "random") # TODO: Add support for nested struct offset Nested = cstruct.Struct("Nested", "!HSSi", "word1 nest2 nest3 int4", [TestStructA, TestStructB]) DoubleNested = cstruct.Struct("DoubleNested", "SSB", "nest1 nest2 byte3", [TestStructA, Nested]) d = DoubleNested((TestStructA( (1, 2)), Nested((5, TestStructA((3, 4)), TestStructB( (7, 8)), 9)), 6)) self.assertEqual(0, d.offset("nest1")) self.assertEqual(len(TestStructA), d.offset("nest2")) self.assertEqual(len(TestStructA) + len(Nested), d.offset("byte3")) self.assertRaises(KeyError, t.offset, "word1")
def testNestedStructs(self): Nested = cstruct.Struct("Nested", "!HSSi", "word1 nest2 nest3 int4", [TestStructA, TestStructB]) DoubleNested = cstruct.Struct("DoubleNested", "SSB", "nest1 nest2 byte3", [TestStructA, Nested]) d = DoubleNested((TestStructA( (1, 2)), Nested((5, TestStructA((3, 4)), TestStructB( (7, 8)), 9)), 6)) expectedlen = (len(TestStructA) + 2 + len(TestStructA) + len(TestStructB) + 4 + 1) self.assertEquals(expectedlen, len(DoubleNested)) self.assertEquals(7, d.nest2.nest3.byte1) d.byte3 = 252 d.nest2.word1 = 33214 n = d.nest2 n.int4 = -55 t = n.nest3 t.int2 = 33627591 self.assertEquals(33627591, d.nest2.nest3.int2) expected = ( "DoubleNested(nest1=TestStructA(byte1=1, int2=2)," " nest2=Nested(word1=33214, nest2=TestStructA(byte1=3, int2=4)," " nest3=TestStructB(byte1=7, int2=33627591), int4=-55), byte3=252)" ) self.assertEquals(expected, str(d)) expected = ("01" "02000000" "81be" "03" "04000000" "07" "c71d0102" "ffffffc9" "fc").decode("hex") self.assertEquals(expected, d.Pack()) unpacked = DoubleNested(expected) self.CheckEquals(unpacked, d)
def testZeroInitialization(self): TestStruct = cstruct.Struct("TestStruct", "B16si16AH", "byte1 string2 int3 ascii4 word5") t = TestStruct() self.assertEquals(0, t.byte1) self.assertEquals("\x00" * 16, t.string2) self.assertEquals(0, t.int3) self.assertEquals("\x00" * 16, t.ascii4) self.assertEquals(0, t.word5) self.assertEquals("\x00" * len(TestStruct), t.Pack())
def testKeywordInitialization(self): TestStruct = cstruct.Struct("TestStruct", "=B16sIH", "byte1 string2 int3 word4") text = "hello world! ^_^" text_bytes = text.encode("hex") # Populate all fields t1 = TestStruct(byte1=1, string2=text, int3=0xFEDCBA98, word4=0x1234) expected = ("01" + text_bytes + "98BADCFE" "3412").decode("hex") self.assertEquals(expected, t1.Pack()) # Partially populated t1 = TestStruct(string2=text, word4=0x1234) expected = ("00" + text_bytes + "00000000" "3412").decode("hex") self.assertEquals(expected, t1.Pack())
def testNullTerminatedStrings(self): TestStruct = cstruct.Struct("TestStruct", "B16si16AH", "byte1 string2 int3 ascii4 word5") nullstr = "hello" + (16 - len("hello")) * "\x00" t = TestStruct((2, nullstr, 12345, nullstr, 33210)) expected = ( "TestStruct(byte1=2, string2=68656c6c6f0000000000000000000000," " int3=12345, ascii4=hello, word5=33210)") self.assertEquals(expected, str(t)) embeddednull = "hello\x00visible123" t = TestStruct((2, embeddednull, 12345, embeddednull, 33210)) expected = ( "TestStruct(byte1=2, string2=68656c6c6f0076697369626c65313233," " int3=12345, ascii4=hello\x00visible123, word5=33210)") self.assertEquals(expected, str(t))
INET_DIAG_DCTCPINFO = 9 # Bytecode operations. INET_DIAG_BC_NOP = 0 INET_DIAG_BC_JMP = 1 INET_DIAG_BC_S_GE = 2 INET_DIAG_BC_S_LE = 3 INET_DIAG_BC_D_GE = 4 INET_DIAG_BC_D_LE = 5 INET_DIAG_BC_AUTO = 6 INET_DIAG_BC_S_COND = 7 INET_DIAG_BC_D_COND = 8 # Data structure formats. # These aren't constants, they're classes. So, pylint: disable=invalid-name InetDiagSockId = cstruct.Struct( "InetDiagSockId", "!HH16s16sI8s", "sport dport src dst iface cookie") InetDiagReqV2 = cstruct.Struct( "InetDiagReqV2", "=BBBxIS", "family protocol ext states id", [InetDiagSockId]) InetDiagMsg = cstruct.Struct( "InetDiagMsg", "=BBBBSLLLLL", "family state timer retrans id expires rqueue wqueue uid inode", [InetDiagSockId]) InetDiagMeminfo = cstruct.Struct( "InetDiagMeminfo", "=IIII", "rmem wmem fmem tmem") InetDiagBcOp = cstruct.Struct("InetDiagBcOp", "BBH", "code yes no") InetDiagHostcond = cstruct.Struct("InetDiagHostcond", "=BBxxi", "family prefix_len port") SkMeminfo = cstruct.Struct( "SkMeminfo", "=IIIIIIII",
# You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import unittest import cstruct # These aren't constants, they're classes. So, pylint: disable=invalid-name TestStructA = cstruct.Struct("TestStructA", "=BI", "byte1 int2") TestStructB = cstruct.Struct("TestStructB", "=BI", "byte1 int2") class CstructTest(unittest.TestCase): def CheckEquals(self, a, b): self.assertEquals(a, b) self.assertEquals(b, a) assert a == b assert b == a assert not (a != b) # pylint: disable=g-comparison-negation,superfluous-parens assert not (b != a) # pylint: disable=g-comparison-negation,superfluous-parens def CheckNotEquals(self, a, b): self.assertNotEquals(a, b) self.assertNotEquals(b, a)
SADB_EXT_SUPPORTED_ENCRYPT = 15 SADB_EXT_SPIRANGE = 16 SADB_X_EXT_KMPRIVATE = 17 SADB_X_EXT_POLICY = 18 SADB_X_EXT_SA2 = 19 SADB_X_EXT_NAT_T_TYPE = 20 SADB_X_EXT_NAT_T_SPORT = 21 SADB_X_EXT_NAT_T_DPORT = 22 SADB_X_EXT_NAT_T_OA = 23 SADB_X_EXT_SEC_CTX = 24 SADB_X_EXT_KMADDRESS = 25 SADB_X_EXT_FILTER = 26 # Data structure formats. # These aren't constants, they're classes. So, pylint: disable=invalid-name SadbMsg = cstruct.Struct( "SadbMsg", "=BBBBHHII", "version type errno satype len reserved seq pid") # Fake struct containing the common beginning of all extension structs. SadbExt = cstruct.Struct("SadbExt", "=HH", "len exttype") SadbSa = cstruct.Struct( "SadbSa", "=IBBBBI", "spi replay state auth encrypt flags") SadbLifetime = cstruct.Struct( "SadbLifetime", "=IQQQ", "allocations bytes addtime usetime") SadbAddress = cstruct.Struct("SadbAddress", "=BB2x", "proto prefixlen") SadbKey = cstruct.Struct("SadbKey", "=H2x", "bits") SadbXSa2 = cstruct.Struct("SadbXSa2", "=B3xII", "mode sequence reqid")
import os from socket import * # pylint: disable=wildcard-import import threading import time import unittest import cstruct import multinetwork_base import net_test IPV6_JOIN_ANYCAST = 27 IPV6_LEAVE_ANYCAST = 28 # pylint: disable=invalid-name IPv6Mreq = cstruct.Struct("IPv6Mreq", "=16si", "multiaddr ifindex") _CLOSE_HUNG = False def CauseOops(): open("/proc/sysrq-trigger", "w").write("c") class CloseFileDescriptorThread(threading.Thread): def __init__(self, fd): super(CloseFileDescriptorThread, self).__init__() self.daemon = True self._fd = fd self.finished = False
XFRM_MODE_IN_TRIGGER = 3 XFRM_MODE_BEET = 4 XFRM_MODE_MAX = 5 # Actions. XFRM_POLICY_ALLOW = 0 XFRM_POLICY_BLOCK = 1 # Flags. XFRM_POLICY_LOCALOK = 1 XFRM_POLICY_ICMP = 2 # Data structure formats. # These aren't constants, they're classes. So, pylint: disable=invalid-name XfrmSelector = cstruct.Struct( "XfrmSelector", "=16s16sHHHHHBBBxxxiI", "daddr saddr dport dport_mask sport sport_mask " "family prefixlen_d prefixlen_s proto ifindex user") XfrmLifetimeCfg = cstruct.Struct( "XfrmLifetimeCfg", "=QQQQQQQQ", "soft_byte hard_byte soft_packet hard_packet " "soft_add_expires hard_add_expires soft_use_expires hard_use_expires") XfrmLifetimeCur = cstruct.Struct("XfrmLifetimeCur", "=QQQQ", "bytes packets add_time use_time") XfrmAlgo = cstruct.Struct("XfrmAlgo", "=64AI", "name key_len") XfrmAlgoAuth = cstruct.Struct("XfrmAlgoAuth", "=64AII", "name key_len trunc_len")
# Request constants. NLM_F_REQUEST = 1 NLM_F_ACK = 4 NLM_F_REPLACE = 0x100 NLM_F_EXCL = 0x200 NLM_F_CREATE = 0x400 NLM_F_DUMP = 0x300 # Message types. NLMSG_ERROR = 2 NLMSG_DONE = 3 # Data structure formats. # These aren't constants, they're classes. So, pylint: disable=invalid-name NLMsgHdr = cstruct.Struct("NLMsgHdr", "=LHHLL", "length type flags seq pid") NLMsgErr = cstruct.Struct("NLMsgErr", "=i", "error") NLAttr = cstruct.Struct("NLAttr", "=HH", "nla_len nla_type") # Alignment / padding. NLA_ALIGNTO = 4 ### rtnetlink constants. See include/uapi/linux/rtnetlink.h. # Message types. RTM_NEWLINK = 16 RTM_DELLINK = 17 RTM_GETLINK = 18 RTM_NEWADDR = 20 RTM_DELADDR = 21 RTM_GETADDR = 22 RTM_NEWROUTE = 24
# Attributes. CTRL_ATTR_FAMILY_ID = 1 CTRL_ATTR_FAMILY_NAME = 2 CTRL_ATTR_VERSION = 3 CTRL_ATTR_HDRSIZE = 4 CTRL_ATTR_MAXATTR = 5 CTRL_ATTR_OPS = 6 CTRL_ATTR_MCAST_GROUPS = 7 # Attributes netsted inside CTRL_ATTR_OPS. CTRL_ATTR_OP_ID = 1 CTRL_ATTR_OP_FLAGS = 2 # Data structure formats. # These aren't constants, they're classes. So, pylint: disable=invalid-name Genlmsghdr = cstruct.Struct("genlmsghdr", "BBxx", "cmd version") class GenericNetlink(netlink.NetlinkSocket): """Base class for all generic netlink classes.""" NL_DEBUG = [] def __init__(self): super(GenericNetlink, self).__init__(netlink.NETLINK_GENERIC) def _SendCommand(self, family, command, version, data, flags): genlmsghdr = Genlmsghdr((command, version)) self._SendNlRequest(family, genlmsghdr.Pack() + data, flags) def _Dump(self, family, command, version):
# limitations under the License. """Python wrapper for C socket calls and data structures.""" import ctypes import ctypes.util import os import socket import struct import cstruct # Data structures. # These aren't constants, they're classes. So, pylint: disable=invalid-name CMsgHdr = cstruct.Struct("cmsghdr", "@Lii", "len level type") Iovec = cstruct.Struct("iovec", "@LL", "base len") MsgHdr = cstruct.Struct("msghdr", "@LLLLLLi", "name namelen iov iovlen control msg_controllen flags") SockaddrIn = cstruct.Struct("sockaddr_in", "=HH4sxxxxxxxx", "family port addr") SockaddrIn6 = cstruct.Struct("sockaddr_in6", "=HHI16sI", "family port flowinfo addr scope_id") # Constants. CMSG_ALIGNTO = struct.calcsize("@L") # The kernel defines this as sizeof(long). MSG_CONFIRM = 0X800 # Find the C library. libc = ctypes.CDLL(ctypes.util.find_library("c"), use_errno=True)
BPF_JNE = 0x50 BPF_JSGT = 0x60 BPF_JSGE = 0x70 BPF_CALL = 0x80 BPF_EXIT = 0x90 # BPF helper function constants BPF_FUNC_unspec = 0 BPF_FUNC_map_lookup_elem = 1 BPF_FUNC_map_update_elem = 2 BPF_FUNC_map_delete_elem = 3 # BPF attr struct BpfAttrCreate = cstruct.Struct("bpf_attr_create", "=IIII", "map_type key_size value_size max_entries") BpfAttrOps = cstruct.Struct("bpf_attr_ops", "=QQQQ", "map_fd key_ptr value_ptr flags") BpfAttrProgLoad = cstruct.Struct( "bpf_attr_prog_load", "=IIQQIIQI", "prog_type insn_cnt insns" " license log_level log_size log_buf kern_version") BpfInsn = cstruct.Struct("bpf_insn", "=BBhi", "code dst_src_reg off imm") libc = ctypes.CDLL(ctypes.util.find_library("c"), use_errno=True) HAVE_EBPF_SUPPORT = net_test.LINUX_VERSION >= (4, 4, 0) # BPF program syscalls def CreateMap(map_type, key_size, value_size, max_entries): attr = BpfAttrCreate((map_type, key_size, value_size, max_entries)) ret = libc.syscall(__NR_bpf, BPF_MAP_CREATE, attr.CPointer(), len(attr))
# Request constants. NLM_F_REQUEST = 1 NLM_F_ACK = 4 NLM_F_REPLACE = 0x100 NLM_F_EXCL = 0x200 NLM_F_CREATE = 0x400 NLM_F_DUMP = 0x300 # Message types. NLMSG_ERROR = 2 NLMSG_DONE = 3 # Data structure formats. # These aren't constants, they're classes. So, pylint: disable=invalid-name NLMsgHdr = cstruct.Struct("NLMsgHdr", "=LHHLL", "length type flags seq pid") NLMsgErr = cstruct.Struct("NLMsgErr", "=i", "error") NLAttr = cstruct.Struct("NLAttr", "=HH", "nla_len nla_type") # Alignment / padding. NLA_ALIGNTO = 4 def PaddedLength(length): # TODO: This padding is probably overly simplistic. return NLA_ALIGNTO * ((length / NLA_ALIGNTO) + (length % NLA_ALIGNTO != 0)) class NetlinkSocket(object): """A basic netlink socket object."""
IPV4_LOOPBACK_ADDR = "127.0.0.1" IPV6_LOOPBACK_ADDR = "::1" LOOPBACK_DEV = "lo" LOOPBACK_IFINDEX = 1 SIOCKILLADDR = 0x8939 DEFAULT_TCP_PORT = 8001 DEFAULT_BUFFER_SIZE = 20 DEFAULT_TEST_MESSAGE = "TCP NUKE ADDR TEST" DEFAULT_TEST_RUNS = 100 HASH_TEST_RUNS = 4000 HASH_TEST_NOFILE = 16384 Ifreq = cstruct.Struct("Ifreq", "=16s16s", "name data") In6Ifreq = cstruct.Struct("In6Ifreq", "=16sIi", "addr prefixlen ifindex") @contextlib.contextmanager def RunInBackground(thread): """Starts a thread and waits until it joins. Args: thread: A not yet started threading.Thread object. """ try: thread.start() yield thread finally: thread.join()
RTA_METRICS = 8 RTA_CACHEINFO = 12 RTA_TABLE = 15 RTA_MARK = 16 RTA_PREF = 20 RTA_UID = 25 # Netlink groups. RTMGRP_IPV6_IFADDR = 0x100 # Route metric attributes. RTAX_MTU = 2 RTAX_HOPLIMIT = 10 # Data structure formats. IfinfoMsg = cstruct.Struct( "IfinfoMsg", "=BBHiII", "family pad type index flags change") RTMsg = cstruct.Struct( "RTMsg", "=BBBBBBBBI", "family dst_len src_len tos table protocol scope type flags") RTACacheinfo = cstruct.Struct( "RTACacheinfo", "=IIiiI", "clntref lastuse expires error used") ### Interface address constants. See include/uapi/linux/if_addr.h. # Interface address attributes. IFA_ADDRESS = 1 IFA_LOCAL = 2 IFA_LABEL = 3 IFA_CACHEINFO = 6 # Address flags.
def testDefinitionFieldMismatch(self): cstruct.Struct("TestA", "=BI", "byte1 int2") cstruct.Struct("TestA", "=BxxxxxIx", "byte1 int2") with self.assertRaises(ValueError): cstruct.Struct("TestA", "=B", "byte1 int2") with self.assertRaises(ValueError): cstruct.Struct("TestA", "=BI", "byte1") Nested = cstruct.Struct("Nested", "!II", "int1 int2") cstruct.Struct("TestB", "=BSI", "byte1 nest2 int3", [Nested]) cstruct.Struct("TestB", "=BxSxIx", "byte1 nest2 int3", [Nested]) with self.assertRaises(ValueError): cstruct.Struct("TestB", "=BSI", "byte1 int3", [Nested]) with self.assertRaises(ValueError): cstruct.Struct("TestB", "=BSI", "byte1 nest2", [Nested]) cstruct.Struct("TestC", "=BSSI", "byte1 nest2 nest3 int4", [Nested, Nested]) with self.assertRaises(ValueError): cstruct.Struct("TestC", "=BSSI", "byte1 nest2 int4", [Nested, Nested])
# See the License for the specific language governing permissions and # limitations under the License. """Python wrapper for C socket calls and data structures.""" import ctypes import ctypes.util import os import socket import struct import sys import cstruct # Data structures. # These aren't constants, they're classes. So, pylint: disable=invalid-name CMsgHdr = cstruct.Struct("cmsghdr", "@Lii", "len level type") Iovec = cstruct.Struct("iovec", "@LL", "base len") MsgHdr = cstruct.Struct( "msghdr", "@LLLLLLi", "name namelen iov iovlen control msg_controllen flags") SockaddrIn = cstruct.Struct("sockaddr_in", "=HH4sxxxxxxxx", "family port addr") SockaddrIn6 = cstruct.Struct("sockaddr_in6", "=HHI16sI", "family port flowinfo addr scope_id") SockaddrStorage = cstruct.Struct("sockaddr_storage", "=H126s", "family data") SockExtendedErr = cstruct.Struct("sock_extended_err", "@IBBBxII", "errno origin type code info data") InPktinfo = cstruct.Struct("in_pktinfo", "@i4s4s", "ifindex spec_dst addr") In6Pktinfo = cstruct.Struct("in6_pktinfo", "@16si", "addr ifindex") # Constants. # IPv4 socket options and cmsg types.
# Setsockopt values. IP_UNICAST_IF = 50 IPV6_MULTICAST_IF = 17 IPV6_UNICAST_IF = 76 # Cmsg values. IP_TTL = 2 IP_PKTINFO = 8 IPV6_2292PKTOPTIONS = 6 IPV6_FLOWINFO = 11 IPV6_PKTINFO = 50 IPV6_HOPLIMIT = 52 # Different from IPV6_UNICAST_HOPS, this is cmsg only. # Data structures. # These aren't constants, they're classes. So, pylint: disable=invalid-name InPktinfo = cstruct.Struct("in_pktinfo", "@i4s4s", "ifindex spec_dst addr") In6Pktinfo = cstruct.Struct("in6_pktinfo", "@16si", "addr ifindex") def HaveUidRouting(): """Checks whether the kernel supports UID routing.""" # Create a rule with the UID range selector. If the kernel doesn't understand # the selector, it will create a rule with no selectors. try: iproute.IPRoute().UidRangeRule(6, True, 1000, 2000, 100, 10000) except IOError: return False # Dump all the rules. If we find a rule using the UID range selector, then the # kernel supports UID range routing. rules = iproute.IPRoute().DumpRules(6)