00001
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include <string.h>
00036 #include <sys/socket.h>
00037 #include <sys/ioctl.h>
00038 #include <netinet/in.h>
00039 #include <net/route.h>
00040 #include <arpa/inet.h>
00041 #include <syslog.h>
00042
00043 #include "mesh_link.h"
00044
00045
00046 void link_entry_to_rtentry(link_entry_t *entry, struct rtentry *rt)
00047 {
00048 #ifdef DEBUG_LINKS
00049 char rt_dest[NET_ADDR_LEN], rt_next[NET_ADDR_LEN], rt_mask[NET_ADDR_LEN];
00050 char link_string[MESH_LINK_STRLEN];
00051 link_to_string(&entry->link, link_string);
00052 #endif
00053
00054 ((struct sockaddr_in*)&rt->rt_dst)->sin_family = AF_INET;
00055 memcpy(&((struct sockaddr_in*)&rt->rt_dst)->sin_addr, &entry->link.node,
00056 sizeof(((struct sockaddr_in*)&rt->rt_dst)->sin_addr));
00057 memset(&(((struct sockaddr_in*)&rt->rt_dst)->sin_zero), 0,
00058 sizeof(((struct sockaddr_in*)&rt->rt_dst)->sin_zero));
00059
00060 ((struct sockaddr_in*)&rt->rt_gateway)->sin_family = AF_INET;
00061 memcpy(&((struct sockaddr_in*)&rt->rt_gateway)->sin_addr,
00062 &entry->link.next_hop,
00063 sizeof(((struct sockaddr_in*)&rt->rt_gateway)->sin_addr));
00064 memset(&((struct sockaddr_in*)&rt->rt_gateway)->sin_zero, 0,
00065 sizeof(((struct sockaddr_in*)&rt->rt_gateway)->sin_zero));
00066
00067 ((struct sockaddr_in*)&rt->rt_genmask)->sin_family = AF_INET;
00068 inet_aton(entry->nmask, &((struct sockaddr_in*)&rt->rt_genmask)->sin_addr);
00069 memset(&(((struct sockaddr_in*)&rt->rt_genmask)->sin_zero), 0,
00070 sizeof(((struct sockaddr_in*)&rt->rt_genmask)->sin_zero));
00071
00072 #ifdef DEBUG_LINKS
00073 strcpy(rt_dest, inet_ntoa(((struct sockaddr_in*)&rt->rt_dst)->sin_addr));
00074 strcpy(rt_next, inet_ntoa(((struct sockaddr_in*)&rt->rt_gateway)->sin_addr));
00075 strcpy(rt_mask, inet_ntoa(((struct sockaddr_in*)&rt->rt_genmask)->sin_addr));
00076 syslog(LOG_INFO, "link_entry: %s", link_string);
00077 syslog(LOG_INFO, "rtentry: dest:%s gateway:%s mask:%s",
00078 rt_dest, rt_next, rt_mask);
00079 #endif
00080
00081 rt->rt_flags = RTF_UP | RTF_HOST | RTF_GATEWAY;
00082 rt->rt_metric = 0;
00083 rt->rt_dev = entry->iface;
00084 }
00085
00086
00087 int add_kernel_route(link_entry_t *entry)
00088 {
00089 int nl_sd, error = 0;
00090 struct rtentry rt;
00091
00092 link_entry_to_rtentry(entry, &rt);
00093 if ((nl_sd = socket(PF_INET, SOCK_DGRAM, 0)) < 0) {
00094 syslog(LOG_ERR, "add_kernel_route: socket %m");
00095 return nl_sd;
00096 }
00097 if ((error = ioctl(nl_sd, SIOCADDRT, &rt)) < 0)
00098 syslog(LOG_ERR, "add_kernel_route: %m");
00099 return error;
00100 }
00101
00102
00103 int remove_kernel_route(link_entry_t *entry)
00104 {
00105 int nl_sd, error = 0;
00106 struct rtentry rt;
00107
00108 link_entry_to_rtentry(entry, &rt);
00109 if ((nl_sd = socket(PF_INET, SOCK_DGRAM, 0)) < 0) {
00110 syslog(LOG_ERR, "remove_kernel_route: socket %m");
00111 return nl_sd;
00112 }
00113 if ((error = ioctl(nl_sd, SIOCDELRT, &rt)) < 0)
00114 syslog(LOG_ERR, "remove_kernel_route: %m");
00115 return error;
00116 }