help-smalltalk
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Help-smalltalk] [PATCH 2/2] netlink: Introduce a Linux/Netlink extensio


From: Holger Hans Peter Freyther
Subject: [Help-smalltalk] [PATCH 2/2] netlink: Introduce a Linux/Netlink extension for GNU Smalltalk
Date: Tue, 25 Mar 2014 18:58:21 +0100

The module only supports one query right now but it could and
should grow over time. The Transport of the OsmoSIP binds to the
unknown address but when addressing a UAS/Proxy it needs to fill
in a real IPv4 Address in the Contact header. This module can be
used for that.

  (Sockets.SocketAddress byName: 'remote') determineSourceAddress

2014-03-25  Holger Hans Peter Freyther  <address@hidden>

        * Extensions.st: Add file.
        * Netlink.st: Add file.
        * netlink.c: Add file.
        * package.xml: Add file.
---
 .gitignore                      |   1 +
 NEWS                            |   2 +
 configure.ac                    |   4 +
 packages/netlink/ChangeLog      |   6 ++
 packages/netlink/Extensions.st  |  55 ++++++++++++++
 packages/netlink/Makefile.am    |   9 +++
 packages/netlink/Makefile.frag  |   5 ++
 packages/netlink/Netlink.st     |  46 ++++++++++++
 packages/netlink/NetlinkTest.st |  41 ++++++++++
 packages/netlink/netlink.c      | 163 ++++++++++++++++++++++++++++++++++++++++
 packages/netlink/package.xml    |  14 ++++
 11 files changed, 346 insertions(+)
 create mode 100644 packages/netlink/ChangeLog
 create mode 100644 packages/netlink/Extensions.st
 create mode 100644 packages/netlink/Makefile.am
 create mode 100644 packages/netlink/Makefile.frag
 create mode 100644 packages/netlink/Netlink.st
 create mode 100644 packages/netlink/NetlinkTest.st
 create mode 100644 packages/netlink/netlink.c
 create mode 100644 packages/netlink/package.xml

diff --git a/.gitignore b/.gitignore
index b36d450..b94bc20 100644
--- a/.gitignore
+++ b/.gitignore
@@ -65,6 +65,7 @@ packages/gtk/structs
 packages/i18n/ref-add.sed
 packages/i18n/ref-del.sed
 packages/net/gnutls-wrapper
+packages/netlink/stamp-classes
 packages/object-dumper/stamp-classes
 packages/sttools/stamp-classes
 snprintfv/snprintfv/compat.stamp
diff --git a/NEWS b/NEWS
index bb33a80..d66e099 100644
--- a/NEWS
+++ b/NEWS
@@ -26,6 +26,8 @@ o   VisualGST now understands the CTRL + . shortcut. This 
will flush the
 o   gst-sunit now understands the -d/--debug parameter. In case of an
     unhandled exception or a test failure VisualGST will be spawned.
 
+o   The Netlink module has been added for Linux.
+
 -----------------------------------------------------------------------------
 
 NEWS FROM 3.2.4 to 3.2.5
diff --git a/configure.ac b/configure.ac
index dbc75a6..bfd09a4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -585,6 +585,10 @@ GST_PACKAGE_ENABLE([LibSDL_ttf], [sdl/libsdl_ttf],
   [ac_cv_lib_SDL_ttf_TTF_Init])
 
 GST_PACKAGE_ENABLE([Compiler], [stinst/compiler])
+GST_PACKAGE_ENABLE([Netlink], [netlink],
+   [AC_CHECK_HEADERS([linux/netlink.h linux/rtnetlink.h])],
+   [ac_cv_header_linux_netlink_h ac_cv_header_linux_rtnetlink_h],
+   [Makefile], [netlink.la])
 GST_PACKAGE_ENABLE([Parser], [stinst/parser])
 GST_PACKAGE_ENABLE([ClassPublisher], [stinst/doc])
 GST_PACKAGE_ENABLE([ProfileTools], [profile])
diff --git a/packages/netlink/ChangeLog b/packages/netlink/ChangeLog
new file mode 100644
index 0000000..16128cb
--- /dev/null
+++ b/packages/netlink/ChangeLog
@@ -0,0 +1,6 @@
+2014-03-25  Holger Hans Peter Freyther  <address@hidden>
+
+       * Extensions.st: Add file.
+       * Netlink.st: Add file.
+       * netlink.c: Add file.
+       * package.xml: Add file.        
diff --git a/packages/netlink/Extensions.st b/packages/netlink/Extensions.st
new file mode 100644
index 0000000..2e456f1
--- /dev/null
+++ b/packages/netlink/Extensions.st
@@ -0,0 +1,55 @@
+"======================================================================
+|
+|   Netlink module declarations
+|
+|
+ ======================================================================"
+
+"======================================================================
+|
+| Copyright 2014 Free Software Foundation, Inc.
+| Written by Holger Hans Peter Freyther
+|
+| This file is part of the GNU Smalltalk class library.
+|
+| The GNU Smalltalk class library is free software; you can redistribute it
+| and/or modify it under the terms of the GNU Lesser General Public License
+| as published by the Free Software Foundation; either version 2.1, or (at
+| your option) any later version.
+|
+| The GNU Smalltalk class library is distributed in the hope that it will be
+| useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
+| General Public License for more details.
+|
+| You should have received a copy of the GNU Lesser General Public License
+| along with the GNU Smalltalk class library; see the file COPYING.LIB.
+| If not, write to the Free Software Foundation, 59 Temple Place - Suite
+| 330, Boston, MA 02110-1301, USA.
+|
+ ======================================================================"
+
+
+
+Sockets.IPAddress extend [
+    determineSourceAddress  [
+        | sourceAddr res |
+        <category: '*Netlink'>
+        "Assuming that self is the destination address determine the
+        source address that will be used."
+        sourceAddr := ByteArray new: 4.
+        res := Netlink fromDestIPv4: address toLocal: sourceAddr.
+        res = 0
+            ifFalse: [^self error: 'Failed to determine source address'].
+        ^self class fromBytes: sourceAddr.
+    ]
+
+    fromDest: destAddress toLocal: localAddress [
+        <category: '*Netlink'>
+        "Given a destination IPv4 Address this function will
+        determine the local source address that would be used.
+        The addresses need to be a ByteArray with four entries."
+        <cCall: 'nl_route_source_ipv4' returning: #int args: #(#byteArray 
#cObject)>
+    ]
+
+]
diff --git a/packages/netlink/Makefile.am b/packages/netlink/Makefile.am
new file mode 100644
index 0000000..f5c1c0a
--- /dev/null
+++ b/packages/netlink/Makefile.am
@@ -0,0 +1,9 @@
+gst_module_ldflags = -rpath $(moduleexecdir) -release $(VERSION) -module \
+        -no-undefined -export-symbols-regex gst_initModule
+
+moduleexec_LTLIBRARIES = netlink.la
+netlink_la_SOURCES = netlink.c
+netlink_la_LDFLAGS = $(gst_module_ldflags)
+
+AM_CPPFLAGS = -I$(top_srcdir)/libgst -I$(top_srcdir)/lib-src
+
diff --git a/packages/netlink/Makefile.frag b/packages/netlink/Makefile.frag
new file mode 100644
index 0000000..e9cdceb
--- /dev/null
+++ b/packages/netlink/Makefile.frag
@@ -0,0 +1,5 @@
+Netlink_FILES = \
+packages/netlink/Extensions.st packages/netlink/Netlink.st 
+$(Netlink_FILES):
+$(srcdir)/packages/netlink/stamp-classes: $(Netlink_FILES)
+       touch $(srcdir)/packages/netlink/stamp-classes
diff --git a/packages/netlink/Netlink.st b/packages/netlink/Netlink.st
new file mode 100644
index 0000000..f6a2e10
--- /dev/null
+++ b/packages/netlink/Netlink.st
@@ -0,0 +1,46 @@
+"======================================================================
+|
+|   Netlink module declarations
+|
+|
+ ======================================================================"
+
+"======================================================================
+|
+| Copyright 2014 Free Software Foundation, Inc.
+| Written by Holger Hans Peter Freyther
+|
+| This file is part of the GNU Smalltalk class library.
+|
+| The GNU Smalltalk class library is free software; you can redistribute it
+| and/or modify it under the terms of the GNU Lesser General Public License
+| as published by the Free Software Foundation; either version 2.1, or (at
+| your option) any later version.
+|
+| The GNU Smalltalk class library is distributed in the hope that it will be
+| useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
+| General Public License for more details.
+|
+| You should have received a copy of the GNU Lesser General Public License
+| along with the GNU Smalltalk class library; see the file COPYING.LIB.
+| If not, write to the Free Software Foundation, 59 Temple Place - Suite
+| 330, Boston, MA 02110-1301, USA.
+|
+ ======================================================================"
+
+
+
+Object subclass: Netlink [
+    <category: 'Netlink'>
+    <comment: 'I help speaking netlink with the kernel. Currently this
+    only includes the routing sub-system but might be extended.'>
+
+    Netlink class >> fromDestIPv4: destAddress toLocal: localAddress [
+        <category: '*Netlink'>
+        "Given a destination IPv4 Address this function will
+        determine the local source address that would be used.
+        The addresses need to be a ByteArray with four entries."
+        <cCall: 'nl_route_source_ipv4' returning: #int args: #(#byteArray 
#cObject)>
+    ]
+]
diff --git a/packages/netlink/NetlinkTest.st b/packages/netlink/NetlinkTest.st
new file mode 100644
index 0000000..efa1f14
--- /dev/null
+++ b/packages/netlink/NetlinkTest.st
@@ -0,0 +1,41 @@
+"======================================================================
+|
+|   Netlink module declarations
+|
+|
+ ======================================================================"
+
+"======================================================================
+|
+| Copyright 2014 Free Software Foundation, Inc.
+| Written by Holger Hans Peter Freyther
+|
+| This file is part of the GNU Smalltalk class library.
+|
+| The GNU Smalltalk class library is free software; you can redistribute it
+| and/or modify it under the terms of the GNU Lesser General Public License
+| as published by the Free Software Foundation; either version 2.1, or (at
+| your option) any later version.
+|
+| The GNU Smalltalk class library is distributed in the hope that it will be
+| useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
+| General Public License for more details.
+|
+| You should have received a copy of the GNU Lesser General Public License
+| along with the GNU Smalltalk class library; see the file COPYING.LIB.
+| If not, write to the Free Software Foundation, 59 Temple Place - Suite
+| 330, Boston, MA 02110-1301, USA.
+|
+ ======================================================================"
+
+
+TestCase subclass: NetlinkTest [
+    <category: 'Netlink-Test'>
+
+    testIPv4Resolving [
+        | addr |
+        addr := (SocketAddress byName: '127.0.0.10') determineSourceAddress.
+        self assert: addr equals: (IPAddress fromBytes: #[127 0 0 1]).
+    ]
+]
diff --git a/packages/netlink/netlink.c b/packages/netlink/netlink.c
new file mode 100644
index 0000000..1a4ed67
--- /dev/null
+++ b/packages/netlink/netlink.c
@@ -0,0 +1,163 @@
+/***********************************************************************
+ *
+ *     Netlink interface definitions for GNU Smalltalk 
+ *
+ *
+ ***********************************************************************/
+
+/***********************************************************************
+ *
+ * Copyright 2014 Free Software Foundation, Inc.
+ * Written by Holger Hans Peter Freyther.
+ *
+ * This file is part of GNU Smalltalk.
+ *
+ * GNU Smalltalk is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2, or (at your option) any later 
+ * version.
+ * 
+ * Linking GNU Smalltalk statically or dynamically with other modules is
+ * making a combined work based on GNU Smalltalk.  Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * In addition, as a special exception, the Free Software Foundation
+ * give you permission to combine GNU Smalltalk with free software
+ * programs or libraries that are released under the GNU LGPL and with
+ * independent programs running under the GNU Smalltalk virtual machine.
+ *
+ * You may copy and distribute such a system following the terms of the
+ * GNU GPL for GNU Smalltalk and the licenses of the other code
+ * concerned, provided that you include the source code of that other
+ * code when and as the GNU GPL requires distribution of source code.
+ *
+ * Note that people who make modified versions of GNU Smalltalk are not
+ * obligated to grant this special exception for their modified
+ * versions; it is their choice whether to do so.  The GNU General
+ * Public License gives permission to release a modified version without
+ * this exception; this exception also makes it possible to release a
+ * modified version which carries forward this exception.
+ *
+ * GNU Smalltalk is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * GNU Smalltalk; see the file COPYING.  If not, write to the Free Software
+ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  
+ *
+ ***********************************************************************/
+
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+
+#include <netinet/in.h>
+#include <sys/socket.h>
+
+#include <string.h>
+#include <unistd.h>
+
+#include "gstpub.h"
+
+#define NLMSG_TAIL(nmsg) \
+        ((struct rtattr *) (((char*) (nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len)))
+
+static int
+nl_route_source_ipv4(const char *dest, char *source)
+{
+  int fd, rc;
+  struct rtmsg *r;
+  struct rtattr *rta;
+  struct {
+    struct nlmsghdr         n;
+    struct rtmsg            r;
+    char                    buf[1024];
+  } req;
+
+  memset (&req, 0, sizeof (req));
+
+  fd = socket (AF_NETLINK, SOCK_RAW|SOCK_CLOEXEC, NETLINK_ROUTE);
+  if (fd < 0)
+    return -1;
+
+   /* Send a rtmsg and ask for a response */
+  req.n.nlmsg_len = NLMSG_LENGTH (sizeof (struct rtmsg));
+  req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
+  req.n.nlmsg_type = RTM_GETROUTE;
+  req.n.nlmsg_seq = 1;
+
+  /* Prepare the routing request */
+  req.r.rtm_family = AF_INET;
+
+  /* set the dest */
+  rta = NLMSG_TAIL (&req.n);
+  rta->rta_type = RTA_DST;
+  rta->rta_len = RTA_LENGTH (sizeof (struct in_addr));
+  memcpy (RTA_DATA (rta), dest, sizeof (struct in_addr));
+
+  /* update sizes for dest */
+  req.r.rtm_dst_len = sizeof (struct in_addr) * 8;
+  req.n.nlmsg_len = NLMSG_ALIGN (req.n.nlmsg_len) + RTA_ALIGN (rta->rta_len);
+
+  rc = send(fd, &req, req.n.nlmsg_len, 0);
+  if (rc != req.n.nlmsg_len)
+    {
+      close (fd);
+      return -2;
+    }
+
+  /* now receive a response and parse it */
+  rc = recv( fd, &req, sizeof(req), 0);
+  if (rc <= 0)
+    {
+      close (fd);
+      return -3;
+    }
+
+  if (!NLMSG_OK (&req.n, rc) || req.n.nlmsg_type != RTM_NEWROUTE)
+    {
+      close (fd);
+      return -4;
+    }
+
+  r = NLMSG_DATA (&req.n);
+  rc -= NLMSG_LENGTH (sizeof (*r));
+  rta = RTM_RTA (r);
+  while (RTA_OK (rta, rc))
+    {
+      if (rta->rta_type != RTA_PREFSRC)
+        {
+          rta = RTA_NEXT (rta, rc);
+          continue;
+        }
+
+      /* Check if there are enough bytes */
+      if (RTA_PAYLOAD (rta) != sizeof (struct in_addr))
+        continue;
+
+      /* we are done */
+      memcpy(source, RTA_DATA (rta), RTA_PAYLOAD (rta));
+      close (fd);
+      return 0;
+    }
+
+  close (fd);
+  return -5;
+}
+
+
+/* Module initialization function.  */
+
+void
+gst_initModule (VMProxy * proxy)
+{
+  proxy->defineCFunc ("nl_route_source_ipv4", nl_route_source_ipv4);
+}
diff --git a/packages/netlink/package.xml b/packages/netlink/package.xml
new file mode 100644
index 0000000..a58d787
--- /dev/null
+++ b/packages/netlink/package.xml
@@ -0,0 +1,14 @@
+<package>
+    <name>Netlink</name>
+    <namespace>Sockets</namespace>
+    <prereq>Sockets</prereq>
+    <module>netlink</module>
+
+    <filein>Extensions.st</filein>
+    <filein>Netlink.st</filein>
+
+    <test>
+        <sunit>Sockets.NetlinkTest</sunit>
+        <filein>NetlinkTest.st</filein>
+    </test>
+</package>
-- 
1.9.0




reply via email to

[Prev in Thread] Current Thread [Next in Thread]