summaryrefslogtreecommitdiffstats
path: root/python-ethtool/netlink-address.c
diff options
context:
space:
mode:
Diffstat (limited to 'python-ethtool/netlink-address.c')
-rw-r--r--python-ethtool/netlink-address.c222
1 files changed, 94 insertions, 128 deletions
diff --git a/python-ethtool/netlink-address.c b/python-ethtool/netlink-address.c
index 95c1c86..50a96d7 100644
--- a/python-ethtool/netlink-address.c
+++ b/python-ethtool/netlink-address.c
@@ -24,135 +24,60 @@
#include "etherinfo_struct.h"
#include "etherinfo.h"
-/* IPv6 Addresses: */
+
+/* IP Address parsing: */
static PyObject *
-PyNetlinkIPv6Address_from_rtnl_addr(struct rtnl_addr *addr)
+PyNetlinkIPaddress_from_rtnl_addr(struct rtnl_addr *addr)
{
- PyNetlinkIPv6Address *py_obj;
+ PyNetlinkIPaddress *py_obj;
char buf[INET6_ADDRSTRLEN+1];
+ struct nl_addr *peer_addr = NULL, *brdcst = NULL;
- py_obj = PyObject_New(PyNetlinkIPv6Address,
- &ethtool_netlink_ipv6_address_Type);
+ py_obj = PyObject_New(PyNetlinkIPaddress,
+ &ethtool_netlink_ip_address_Type);
if (!py_obj) {
return NULL;
}
- /* Set ipv6_address: */
- memset(&buf, 0, sizeof(buf));
- if (!inet_ntop(AF_INET6, nl_addr_get_binary_addr(rtnl_addr_get_local(addr)),
- buf, sizeof(buf))) {
- PyErr_SetFromErrno(PyExc_RuntimeError);
- goto error;
- }
- py_obj->ipv6_address = PyString_FromString(buf);
- if (!py_obj->ipv6_address) {
+ /* Set IP address family. Only AF_INET and AF_INET6 is supported */
+ py_obj->family = rtnl_addr_get_family(addr);
+ if (py_obj->family != AF_INET && py_obj->family != AF_INET6) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "Only IPv4 (AF_INET) and IPv6 (AF_INET6) address types are supported");
goto error;
}
- /* Set ipv6_netmask: */
- py_obj->ipv6_netmask = rtnl_addr_get_prefixlen(addr);
-
-
- /* Set ipv6_scope: */
+ /* Set local IP address: */
memset(&buf, 0, sizeof(buf));
- rtnl_scope2str(rtnl_addr_get_scope(addr), buf, sizeof(buf));
- py_obj->ipv6_scope = PyString_FromString(buf);
-
- return (PyObject*)py_obj;
-
- error:
- Py_DECREF(py_obj);
- return NULL;
-}
-
-static void
-netlink_ipv6_address_dealloc(PyNetlinkIPv6Address *obj)
-{
- Py_DECREF(obj->ipv6_address);
- Py_DECREF(obj->ipv6_scope);
-
- /* We can call PyObject_Del directly rather than calling through
- tp_free since the type is not subtypable (Py_TPFLAGS_BASETYPE is
- not set): */
- PyObject_Del(obj);
-}
-
-static PyObject*
-netlink_ipv6_address_repr(PyNetlinkIPv6Address *obj)
-{
- PyObject *result = PyString_FromString("ethtool.NetlinkIPv6Address(address='");
- PyString_Concat(&result, obj->ipv6_address);
- PyString_ConcatAndDel(&result,
- PyString_FromFormat("/%d', scope=",
- obj->ipv6_netmask));
- PyString_Concat(&result, obj->ipv6_scope);
- PyString_ConcatAndDel(&result, PyString_FromString(")"));
- return result;
-}
-
-static PyMemberDef _ethtool_netlink_ipv6_address_members[] = {
- {"address",
- T_OBJECT_EX,
- offsetof(PyNetlinkIPv6Address, ipv6_address),
- 0,
- NULL},
- {"netmask",
- T_INT,
- offsetof(PyNetlinkIPv6Address, ipv6_netmask),
- 0,
- NULL},
- {"scope",
- T_OBJECT_EX,
- offsetof(PyNetlinkIPv6Address, ipv6_scope),
- 0,
- NULL},
- {NULL} /* End of member list */
-};
-
-PyTypeObject ethtool_netlink_ipv6_address_Type = {
- PyVarObject_HEAD_INIT(0, 0)
- .tp_name = "ethtool.NetlinkIPv6Address",
- .tp_basicsize = sizeof(PyNetlinkIPv6Address),
- .tp_dealloc = (destructor)netlink_ipv6_address_dealloc,
- .tp_repr = (reprfunc)netlink_ipv6_address_repr,
- .tp_members = _ethtool_netlink_ipv6_address_members,
-};
-
-
-
-/* IPv4 Addresses: */
-static PyObject *
-PyNetlinkIPv4Address_from_rtnl_addr(struct rtnl_addr *addr)
-{
- PyNetlinkIPv4Address *py_obj;
- char buf[INET_ADDRSTRLEN+1];
- struct nl_addr *brdcst;
-
- py_obj = PyObject_New(PyNetlinkIPv4Address,
- &ethtool_netlink_ipv4_address_Type);
- if (!py_obj) {
- return NULL;
- }
-
- /* Set ipv4_address: */
- memset(&buf, 0, sizeof(buf));
- if (!inet_ntop(AF_INET, nl_addr_get_binary_addr(rtnl_addr_get_local(addr)),
+ if (!inet_ntop(py_obj->family, nl_addr_get_binary_addr(rtnl_addr_get_local(addr)),
buf, sizeof(buf))) {
PyErr_SetFromErrno(PyExc_RuntimeError);
goto error;
}
- py_obj->ipv4_address = PyString_FromString(buf);
- if (!py_obj->ipv4_address) {
+ py_obj->local = PyString_FromString(buf);
+ if (!py_obj->local) {
goto error;
}
- /* Set ipv4_netmask: */
- py_obj->ipv4_netmask = rtnl_addr_get_prefixlen(addr);
+ /* Set peer IP address: */
+ memset(&buf, 0, sizeof(buf));
+ if ((peer_addr = rtnl_addr_get_peer(addr))) {
+ nl_addr2str(peer_addr, buf, sizeof(buf));
+ py_obj->peer = PyString_FromString(buf);
+ if (!py_obj->local) {
+ goto error;
+ }
+ } else {
+ py_obj->peer = NULL;
+ }
+
+ /* Set IP address prefix length (netmask): */
+ py_obj->prefixlen = rtnl_addr_get_prefixlen(addr);
/* Set ipv4_broadcast: */
py_obj->ipv4_broadcast = NULL;
brdcst = rtnl_addr_get_broadcast(addr);
- if( brdcst ) {
+ if( py_obj->family == AF_INET && brdcst ) {
memset(&buf, 0, sizeof(buf));
if (!inet_ntop(AF_INET, nl_addr_get_binary_addr(brdcst),
buf, sizeof(buf))) {
@@ -165,6 +90,11 @@ PyNetlinkIPv4Address_from_rtnl_addr(struct rtnl_addr *addr)
}
}
+ /* Set IP address scope: */
+ memset(&buf, 0, sizeof(buf));
+ rtnl_scope2str(rtnl_addr_get_scope(addr), buf, sizeof(buf));
+ py_obj->scope = PyString_FromString(buf);
+
return (PyObject*)py_obj;
error:
@@ -173,10 +103,12 @@ PyNetlinkIPv4Address_from_rtnl_addr(struct rtnl_addr *addr)
}
static void
-netlink_ipv4_address_dealloc(PyNetlinkIPv4Address *obj)
+netlink_ip_address_dealloc(PyNetlinkIPaddress *obj)
{
- Py_DECREF(obj->ipv4_address);
+ Py_DECREF(obj->local);
+ Py_XDECREF(obj->peer);
Py_XDECREF(obj->ipv4_broadcast);
+ Py_XDECREF(obj->scope);
/* We can call PyObject_Del directly rather than calling through
tp_free since the type is not subtypable (Py_TPFLAGS_BASETYPE is
@@ -185,51 +117,87 @@ netlink_ipv4_address_dealloc(PyNetlinkIPv4Address *obj)
}
static PyObject*
-netlink_ipv4_address_repr(PyNetlinkIPv4Address *obj)
+netlink_ip_address_repr(PyNetlinkIPaddress *obj)
{
- PyObject *result = PyString_FromString("ethtool.NetlinkIPv4Address(address='");
- PyString_Concat(&result, obj->ipv4_address);
+ PyObject *result = PyString_FromString("ethtool.NetlinkIPaddress(family=");
+ char buf[256];
+
+ memset(&buf, 0, sizeof(buf));
+ nl_af2str(obj->family, buf, sizeof(buf));
PyString_ConcatAndDel(&result,
- PyString_FromFormat("', netmask=%d",
- obj->ipv4_netmask));
- if (obj->ipv4_broadcast) {
+ PyString_FromFormat("%s, address='", buf));
+ PyString_Concat(&result, obj->local);
+
+ if (obj->family == AF_INET) {
+ PyString_ConcatAndDel(&result,
+ PyString_FromFormat("', netmask=%d",
+ obj->prefixlen));
+ } else if (obj->family == AF_INET6) {
+ PyString_ConcatAndDel(&result,
+ PyString_FromFormat("/%d'",
+ obj->prefixlen));
+ }
+
+ if (obj->peer) {
+ PyString_ConcatAndDel(&result, PyString_FromString(", peer_address='"));
+ PyString_Concat(&result, obj->peer);
+ PyString_ConcatAndDel(&result, PyString_FromString("'"));
+ }
+
+ if (obj->family == AF_INET && obj->ipv4_broadcast) {
PyString_ConcatAndDel(&result, PyString_FromString(", broadcast='"));
PyString_Concat(&result, obj->ipv4_broadcast);
PyString_ConcatAndDel(&result, PyString_FromString("'"));
}
+
+ PyString_ConcatAndDel(&result, PyString_FromString(", scope="));
+ PyString_Concat(&result, obj->scope);
+
PyString_ConcatAndDel(&result, PyString_FromString(")"));
+
return result;
}
-static PyMemberDef _ethtool_netlink_ipv4_address_members[] = {
+
+static PyMemberDef _ethtool_netlink_ip_address_members[] = {
{"address",
T_OBJECT_EX,
- offsetof(PyNetlinkIPv4Address, ipv4_address),
+ offsetof(PyNetlinkIPaddress, local),
+ 0,
+ NULL},
+ {"peer_address",
+ T_OBJECT_EX,
+ offsetof(PyNetlinkIPaddress, peer),
0,
NULL},
{"netmask",
T_INT,
- offsetof(PyNetlinkIPv4Address, ipv4_netmask),
+ offsetof(PyNetlinkIPaddress, prefixlen),
0,
NULL},
{"broadcast",
T_OBJECT, /* can be NULL */
- offsetof(PyNetlinkIPv4Address, ipv4_broadcast),
+ offsetof(PyNetlinkIPaddress, ipv4_broadcast),
+ 0,
+ NULL},
+ {"scope",
+ T_OBJECT_EX,
+ offsetof(PyNetlinkIPaddress, scope),
0,
NULL},
{NULL} /* End of member list */
};
-PyTypeObject ethtool_netlink_ipv4_address_Type = {
+PyTypeObject ethtool_netlink_ip_address_Type = {
PyVarObject_HEAD_INIT(0, 0)
- .tp_name = "ethtool.NetlinkIPv4Address",
- .tp_basicsize = sizeof(PyNetlinkIPv4Address),
- .tp_dealloc = (destructor)netlink_ipv4_address_dealloc,
- .tp_repr = (reprfunc)netlink_ipv4_address_repr,
- .tp_members = _ethtool_netlink_ipv4_address_members,
+ .tp_name = "ethtool.NetlinkIPaddress",
+ .tp_basicsize = sizeof(PyNetlinkIPaddress),
+ .tp_dealloc = (destructor)netlink_ip_address_dealloc,
+ .tp_repr = (reprfunc)netlink_ip_address_repr,
+ .tp_members = _ethtool_netlink_ip_address_members,
};
-/* Factory function, in case we want to generalize this to add IPv6 support */
+
PyObject *
make_python_address_from_rtnl_addr(struct rtnl_addr *addr)
{
@@ -238,10 +206,8 @@ make_python_address_from_rtnl_addr(struct rtnl_addr *addr)
switch( rtnl_addr_get_family(addr) ) {
case AF_INET:
- return PyNetlinkIPv4Address_from_rtnl_addr(addr);
-
case AF_INET6:
- return PyNetlinkIPv6Address_from_rtnl_addr(addr);
+ return PyNetlinkIPaddress_from_rtnl_addr(addr);
default:
return PyErr_SetFromErrno(PyExc_RuntimeError);