summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNiklas2011-10-12 17:05:12 +0200
committerNiklas2011-10-12 17:05:12 +0200
commit91f8c9826f7c67c4e8e92d6f6460aa58622f2ee5 (patch)
tree7e6f8eb2df81f80c0eb34d8a18460b59d977d13a
parentadded new files (diff)
downloadfbgui-91f8c9826f7c67c4e8e92d6f6460aa58622f2ee5.tar.gz
fbgui-91f8c9826f7c67c4e8e92d6f6460aa58622f2ee5.tar.xz
fbgui-91f8c9826f7c67c4e8e92d6f6460aa58622f2ee5.zip
small changes in the networkmanager. added some ipv6 methods for adding a route and a address to an interface
-rw-r--r--NetworkDiscovery/networkmanager.cpp179
-rw-r--r--NetworkDiscovery/networkmanager.h11
2 files changed, 190 insertions, 0 deletions
diff --git a/NetworkDiscovery/networkmanager.cpp b/NetworkDiscovery/networkmanager.cpp
index da5f045..c40c83d 100644
--- a/NetworkDiscovery/networkmanager.cpp
+++ b/NetworkDiscovery/networkmanager.cpp
@@ -94,6 +94,108 @@ int NetworkManager::replaceDefaultRoute(QString ifname, QString gateway,
+/**/
+int NetworkManager::ip6_addRoute(const char *iface,
+ const struct in6_addr *ip6_dest, int ip6_prefix,
+ const struct in6_addr *ip6_gateway, int metric, int mss) {
+ struct nl_cache *cache;
+ struct nl_handle *nlh;
+ struct rtnl_route *route;
+ struct nl_addr *dest_addr;
+ struct nl_addr *gw_addr = NULL;
+ int err, iface_idx;
+
+ nlh = nl_handle_alloc();
+ nl_connect(nlh, NETLINK_ROUTE);
+
+ if ((cache = rtnl_link_alloc_cache(nlh)) == NULL) {
+ //qDebug() << _tag << "error with link cache alloc \n";
+ printf("error with link cache alloc \n");
+ }
+
+ iface_idx = rtnl_link_name2i(cache, iface);
+
+ route = rtnl_route_alloc();
+
+ /* Destination */
+ dest_addr = nl_addr_build(AF_INET6, (struct in6_addr *) ip6_dest,
+ sizeof(*ip6_dest));
+ nl_addr_set_prefixlen(dest_addr, (int) ip6_prefix);
+
+ rtnl_route_set_dst(route, dest_addr);
+ nl_addr_put(dest_addr);
+
+ /* Gateway */
+ if (ip6_gateway && !IN6_IS_ADDR_UNSPECIFIED (ip6_gateway)) {
+ gw_addr = nl_addr_build(AF_INET6, (struct in6_addr *) ip6_gateway,
+ sizeof(*ip6_gateway));
+ if (gw_addr) {
+ rtnl_route_set_gateway(route, gw_addr);
+ rtnl_route_set_scope(route, RT_SCOPE_UNIVERSE);
+ } else {
+ rtnl_route_put(route);
+ return -1;
+ }
+ }
+
+ /* Metric */
+ if (metric)
+ rtnl_route_set_prio(route, metric);
+
+ /* Add the route */
+ err = rtnl_route_add(nlh, route, 0);
+ if (err == -ESRCH && ip6_gateway) {
+ /* Gateway might be over a bridge; try adding a route to gateway first */
+ struct rtnl_route *route2;
+
+ route2 = create_route(iface_idx, mss);
+ if (route2) {
+ /* Add route to gateway over bridge */
+ rtnl_route_set_dst(route2, gw_addr);
+ err = rtnl_route_add(nlh, route2, 0);
+ if (!err) {
+ /* Try adding the route again */
+ err = rtnl_route_add(nlh, route, 0);
+ if (err)
+ rtnl_route_del(nlh, route2, 0);
+ }
+ rtnl_route_put(route2);
+ }
+ }
+
+ if (gw_addr)
+ nl_addr_put(gw_addr);
+
+ if (err) {
+ //nm_warning ("Failed to set IPv6 route on '%s': %s", iface, nl_geterror ());
+ rtnl_route_put(route);
+ route = NULL;
+ }
+
+ return 0;
+}
+
+
+
+struct rtnl_route * NetworkManager::create_route (int iface_idx, int mss)
+{
+ struct rtnl_route *route;
+
+ route = rtnl_route_alloc ();
+ if (route) {
+ rtnl_route_set_oif (route, iface_idx);
+
+ if (mss && rtnl_route_set_metric (route, RTAX_ADVMSS, mss) < 0) {
+ //nm_warning ("Could not set mss");
+ }
+ } else
+ //nm_warning ("Could not allocate route");
+
+ return route;
+}
+
+
+
/**
* The method brings an interface up.
*
@@ -327,6 +429,83 @@ int NetworkManager::ip4_netmaskToPrefix(QString ipAddr, QString netmask) {
+int NetworkManager::ip6_addAddress(struct ip6_addr* ip6Addr, const char *iface) {
+ int num_addrs, i, iface_idx;
+ struct rtnl_addr* addr = NULL;
+ struct nl_cache *cache;
+ struct nl_handle* rtsock;
+
+ rtsock = nl_handle_alloc();
+ nl_connect(rtsock, NETLINK_ROUTE);
+
+ if ((cache = rtnl_link_alloc_cache(rtsock)) == NULL) {
+ qDebug() << _tag << "error with link cache alloc";
+ return -1;
+ }
+
+ iface_idx = rtnl_link_name2i(cache, iface);
+
+ addr = ip6AddrToRtnlAddr(ip6Addr);
+ if (!addr) {
+ //nm_warning("couldn't create rtnl address!\n");
+ return -1;
+ }
+ rtnl_addr_set_ifindex(addr, iface_idx);
+
+ return sync_address(iface, iface_idx, AF_INET6, addr);
+}
+
+
+
+/**/
+struct rtnl_addr* NetworkManager::ip6AddrToRtnlAddr(struct ip6_addr* ip6Addr) {
+ struct rtnl_addr *addr;
+ bool success = true;
+
+ if (!(addr = rtnl_addr_alloc()))
+ return NULL;
+
+ success = (nlAddrToRtnlAddr(ip6Addr, addr) >= 0);
+
+ if (!success) {
+ rtnl_addr_put(addr);
+ addr = NULL;
+ }
+
+ return addr;
+}
+
+
+
+/**/
+struct nl_addr* NetworkManager::ip6AddrToNlAddr(const struct ip6_addr *ip6Addr) {
+ struct nl_addr * nla = NULL;
+
+ if (!(nla = nl_addr_alloc(sizeof(struct in6_addr))))
+ return NULL;
+ nl_addr_set_family(nla, AF_INET6);
+ nl_addr_set_binary_addr(nla, (struct in6_addr *) ip6Addr, sizeof(struct in6_addr));
+
+ return nla;
+}
+
+
+
+/**/
+int NetworkManager::nlAddrToRtnlAddr(
+ const struct ip6_addr* ip6Addr, struct rtnl_addr* addr) {
+ struct nl_addr * local = NULL;
+ int err = 0;
+
+ local = ip6AddrToNlAddr(ip6Addr);
+ err = rtnl_addr_set_local(addr, local);
+ nl_addr_put(local);
+
+ return -err;
+}
+
+
+
/**
* delete all addresses of this interface but not the one we just set
*
diff --git a/NetworkDiscovery/networkmanager.h b/NetworkDiscovery/networkmanager.h
index 3fb1587..f332f9e 100644
--- a/NetworkDiscovery/networkmanager.h
+++ b/NetworkDiscovery/networkmanager.h
@@ -38,6 +38,12 @@ public:
QString broadcast, QString gateway, int metric, int af, QString pathToResolvConf, QList<QString> nameServer);
int ip4_configureInterface(QString ifname, QString ipAddress,
QString broadcast, QString netmask, int af);
+
+ int ip6_addRoute(const char *iface,
+ const struct in6_addr *ip6_dest, int ip6_prefix,
+ const struct in6_addr *ip6_gateway, int metric, int mss);
+ int ip6_addAddress(struct ip6_addr* ip6Addr, const char *iface);
+
int writeResolvConf(QString path, QString ifname, QList<QString> nameServer);
private:
@@ -48,6 +54,11 @@ private:
int sync_address(const char *iface, int ifindex, int family,
struct rtnl_addr *addr);
+ struct rtnl_route* create_route (int iface_idx, int mss);
+ struct nl_addr* ip6AddrToNlAddr (const struct ip6_addr* ip6Addr);
+ int nlAddrToRtnlAddr (const struct ip6_addr* ip6Addr, struct rtnl_addr* addr);
+ struct rtnl_addr* ip6AddrToRtnlAddr(struct ip6_addr* ip6Addr);
+
};