[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