Esempio n. 1
0
    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)
Esempio n. 3
0
 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())
Esempio n. 4
0
    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)
Esempio n. 8
0
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
Esempio n. 10
0
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")
Esempio n. 11
0
# 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):
Esempio n. 13
0
# 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)

Esempio n. 14
0
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))
Esempio n. 15
0
# 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."""
Esempio n. 16
0
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()
Esempio n. 17
0
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.
Esempio n. 18
0
    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])
Esempio n. 19
0
# 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.
Esempio n. 20
0
# 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)