Signed-off-by: YAMAMOTO Takashi <[email protected]>
---
 ryu/lib/sockaddr.py | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 ryu/lib/sockopt.py  | 69 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 143 insertions(+)
 create mode 100644 ryu/lib/sockaddr.py
 create mode 100644 ryu/lib/sockopt.py

diff --git a/ryu/lib/sockaddr.py b/ryu/lib/sockaddr.py
new file mode 100644
index 0000000..460f215
--- /dev/null
+++ b/ryu/lib/sockaddr.py
@@ -0,0 +1,74 @@
+# Copyright (C) 2014 Nippon Telegraph and Telephone Corporation.
+# Copyright (C) 2014 YAMAMOTO Takashi <yamamoto at valinux co jp>
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# 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 platform
+import socket
+import struct
+
+from ryu.lib import addrconv
+
+
+system = platform.system()
+if system == 'Linux':
+    # on linux,
+    #    no ss_len
+    #    u16 ss_family
+    _HDR_FMT = "H"
+    _HAVE_SS_LEN = False
+else:
+    # assume
+    #    u8 ss_len
+    #    u8 ss_family
+    _HDR_FMT = "BB"
+    _HAVE_SS_LEN = True
+
+
+# RFC 2553
+_SS_MAXSIZE = 128
+_SS_ALIGNSIZE = 8
+
+_SIN_SIZE = 16  # sizeof(struct sockaddr_in)
+
+_HDR_LEN = struct.calcsize(_HDR_FMT)
+
+
+def _hdr(ss_len, af):
+    if _HAVE_SS_LEN:
+        return struct.pack(_HDR_FMT, ss_len, af)
+    else:
+        return struct.pack(_HDR_FMT, af)
+
+
+def _pad_to(data, total_len):
+    pad_len = total_len - len(data)
+    return data + pad_len * '\0'
+
+
+def sa_in4(addr, port=0):
+    data = struct.pack("!H4s", port, addrconv.ipv4.text_to_bin(addr))
+    hdr = _hdr(_SIN_SIZE, socket.AF_INET)
+    return _pad_to(hdr + data, _SIN_SIZE)
+
+
+def sa_in6(addr, port=0, flowinfo=0, scope_id=0):
+    data = struct.pack("!HI16sI", port, flowinfo,
+                       addrconv.ipv6.text_to_bin(addr), scope_id)
+    hdr = _hdr(_HDR_LEN + len(data), socket.AF_INET6)
+    return hdr + data
+
+
+def sa_to_ss(sa):
+    return _pad_to(sa, _SS_MAXSIZE)
diff --git a/ryu/lib/sockopt.py b/ryu/lib/sockopt.py
new file mode 100644
index 0000000..6e53358
--- /dev/null
+++ b/ryu/lib/sockopt.py
@@ -0,0 +1,69 @@
+# Copyright (C) 2014 Nippon Telegraph and Telephone Corporation.
+# Copyright (C) 2014 YAMAMOTO Takashi <yamamoto at valinux co jp>
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# 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 platform
+import socket
+import struct
+
+from ryu.lib import sockaddr
+
+
+def _set_tcp_md5sig_linux(s, addr, key):
+    # struct tcp_md5sig {
+    #     struct sockaddr_storage addr;
+    #     u16 pad1;
+    #     u16 keylen;
+    #     u32 pad2;
+    #     u8 key[80];
+    # }
+    TCP_MD5SIG = 14
+    af = s.family
+    if af == socket.AF_INET:
+        sa = sockaddr.sa_in4(addr)
+    elif af == socket.AF_INET6:
+        sa = sockaddr.sa_in6(addr)
+    else:
+        raise ValueError("unsupported af %s" % (af,))
+    ss = sockaddr.sa_to_ss(sa)
+    tcp_md5sig = ss + struct.pack("2xH4x80s", len(key), key)
+    s.setsockopt(socket.IPPROTO_TCP, TCP_MD5SIG, tcp_md5sig)
+
+
+def _set_tcp_md5sig_bsd(s, _addr, _key):
+    # NOTE: On this platform, address and key need to be set using setkey(8).
+    TCP_MD5SIG = 0x10
+    tcp_md5sig = struct.pack("I", 1)
+    s.setsockopt(socket.IPPROTO_TCP, TCP_MD5SIG, tcp_md5sig)
+
+
+def set_tcp_md5sig(s, addr, key):
+    """Enable TCP-MD5 on the given socket.
+
+    :param s: Socket
+    :param addr: Associated address.  On some platforms, this has no effect.
+    :param key: Key.  On some platforms, this has no effect.
+    """
+    impls = {
+        'FreeBSD': _set_tcp_md5sig_bsd,
+        'Linux': _set_tcp_md5sig_linux,
+        'NetBSD': _set_tcp_md5sig_bsd,
+    }
+    system = platform.system()
+    try:
+        impl = impls[system]
+    except KeyError:
+        raise NotImplementedError("TCP-MD5 unsupported on this platform")
+    impl(s, addr, key)
-- 
1.8.3.1


------------------------------------------------------------------------------
HPCC Systems Open Source Big Data Platform from LexisNexis Risk Solutions
Find What Matters Most in Your Big Data with HPCC Systems
Open Source. Fast. Scalable. Simple. Ideal for Dirty Data.
Leverages Graph Analysis for Fast Processing & Easy Data Exploration
http://p.sf.net/sfu/hpccsystems
_______________________________________________
Ryu-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ryu-devel

Reply via email to