00001
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #define _BSD_SOURCE
00036 #include <stdio.h>
00037 #include <stdlib.h>
00038 #include <string.h>
00039 #include <syslog.h>
00040 #include <sys/types.h>
00041 #include <sys/socket.h>
00042 #include <sys/stat.h>
00043 #include <sys/time.h>
00044 #include <sys/ioctl.h>
00045 #include <fcntl.h>
00046 #include <unistd.h>
00047 #include <net/if.h>
00048 #include <netinet/in.h>
00049 #include <netinet/ip.h>
00050 #include <netinet/udp.h>
00051 #include <net/ethernet.h>
00052 #include <net/if_arp.h>
00053 #include <arpa/inet.h>
00054
00057 #include <linux/if_tun.h>
00058 #include <linux/netfilter.h>
00059 #include "libipq.h"
00060 #define MISC_MAJOR 10
00061 #define TUN_MINOR 200
00062
00063
00064 #include "sensor_self.h"
00065 #include "mesh_link.h"
00066 #include "mesh_route.h"
00067 #include "mesh_on_demand.h"
00068
00069
00070 #define DIVERT_DEV_IP "127.0.0.2"
00071 #define DIVERT_DEV_NAME "tun"
00072
00073
00074
00075 int route_discovery_done(u_int32_t daddr, protocol_t *proto,
00076 discovery_result_t reachable)
00077 {
00078 link_entry_t *entry;
00079 msg_queue_t *pkt;
00080
00081 if (proto == NULL) {
00082 errno = EINVAL;
00083 return -1;
00084 }
00085
00086 if ((entry = retrieve_entry(proto, daddr)) == NULL) {
00087 errno = ENOLINK;
00088 return -1;
00089 }
00090 pkt = entry->routing_backlog;
00091 entry->routing_pending = 0;
00092
00093 if (reachable == ROUTE_FOUND) {
00094 while (pkt != NULL) {
00095 msg_queue_t *cur = pkt;
00096 struct sockaddr_in to;
00097 to.sin_family = AF_INET;
00098 to.sin_port = pkt->port;
00099 to.sin_addr = entry->link.node;
00100 mesh_sendmsg(proto->sensor->interface, proto->sensor->mac_addr,
00101 proto->queue_sd, pkt->data, pkt->len, &to);
00102 free(pkt->data);
00103 pkt = pkt->next;
00104 free(cur);
00105 }
00106 } else if (reachable == NO_ROUTE) {
00107
00108 while (pkt != NULL) {
00109 msg_queue_t *cur = pkt;
00110 pkt = pkt->next;
00111 free(pkt->data);
00112 free(cur);
00113 }
00114 }
00115 return 0;
00116 }
00117
00118
00119
00120 static int route_discovery_pending(u_int32_t daddr, protocol_t *proto)
00121 {
00122 link_entry_t *entry;
00123
00124 if (proto == NULL)
00125 return -1;
00126
00127 if ((entry = retrieve_entry(proto, daddr)) == NULL)
00128 return entry->routing_pending;
00129 return 0;
00130 }
00131
00132
00134 static int divert_init(void)
00135 {
00136 struct ifreq ifr;
00137 int fd, error;
00138 char cmd[256];
00139 unsigned char dev[IFNAMSIZ];
00140 char *dev_name = "/dev/net/tun";
00141
00142 umask(0);
00143 mkdir("/dev/net", 0755);
00144 mknod(dev_name, S_IFCHR|S_IREAD|S_IWRITE, makedev(MISC_MAJOR, TUN_MINOR));
00145 system("modprobe tun");
00146
00147 if ((fd = open(dev_name, O_RDWR)) < 0) {
00148 syslog(LOG_ERR, "open %s: %m", dev_name);
00149 return -1;
00150 }
00151
00152 memset(&ifr, 0, sizeof(ifr));
00153 ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
00154 strcpy(ifr.ifr_name, DIVERT_DEV_NAME);
00155
00156 if ((error = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0) {
00157 syslog(LOG_ERR, "ioctl (TUNSETIFF): %m");
00158 close(fd);
00159 return error;
00160 }
00161 strcpy(dev, ifr.ifr_name);
00162 sprintf(cmd, "/sbin/ifconfig %s %s netmask 255.255.255.255 up",
00163 dev, DIVERT_DEV_IP);
00164 system(cmd);
00165
00166
00167 if ((error = ioctl(fd, TUNSETNOCSUM, 1)) < 0) {
00168 syslog(LOG_ERR, "ioctl (TUNSETNOCSUM): %m");
00169 close(fd);
00170 return error;
00171 }
00172
00173 return fd;
00174 }
00175
00176
00177
00178 static int read_route_request(self_t *self, int fd, u_int32_t *dest_addr,
00179 protocol_t *proto)
00180 {
00181 unsigned int buflen = MAX_MTU;
00182 unsigned char buf[buflen], *iphdr;
00183 ssize_t rlen;
00184 link_entry_t *entry;
00185 msg_queue_t *pkt;
00186 u_int32_t src_addr;
00187 struct ether_header eh;
00188 struct ip ip;
00189 struct udphdr udp;
00190 struct mesh_hdr mh;
00191 unsigned int header_size = ETHER_HDR_LEN + sizeof(ip) + sizeof(udp);
00192
00193 if ((rlen = read(fd, buf, buflen)) <= 0) {
00194 if (rlen < 0)
00195 syslog(LOG_ERR, "read: %m");
00196 return rlen;
00197 }
00198
00199 if (header_size > rlen) {
00200 syslog(LOG_ERR, "read_route_request: invalid packet");
00201 return -1;
00202 }
00203 iphdr = buf + ETHER_HDR_LEN;
00204
00205 pkt = malloc(sizeof(msg_queue_t));
00206 pkt->data = malloc(rlen * sizeof(unsigned char));
00207 pkt->len = rlen;
00208 memcpy(pkt->data, buf + header_size, rlen);
00209
00210 memcpy(&eh, buf, ETHER_HDR_LEN);
00211 memcpy(&ip, iphdr, sizeof(ip));
00212 memcpy(&udp, iphdr + sizeof(ip), sizeof(udp));
00213 memcpy(&mh, iphdr + sizeof(ip) + sizeof(udp), sizeof(mh));
00214 *dest_addr = ip.ip_dst.s_addr;
00215 src_addr = ip.ip_src.s_addr;
00216 pkt->port = udp.uh_sport;
00217 proto = protocol_by_id(self, mh.protocol_id);
00218
00219 if ((entry = retrieve_entry(proto, *dest_addr)) == NULL) {
00220 int error = 0;
00221
00222 entry = new_link_entry(proto);
00223 entry->node_id = *dest_addr;
00224 entry->link.node.s_addr = *dest_addr;
00225 entry->requester = src_addr;
00226
00227 if ((error = add_entry(proto, *dest_addr, entry)) < 0)
00228 return error;
00229 entry->routing_backlog = entry->last_packet = pkt;
00230 } else {
00231 if (entry->last_packet == NULL) {
00232 entry->routing_backlog = entry->last_packet = pkt;
00233 } else {
00234 entry->last_packet->next = pkt;
00235 entry->last_packet = pkt;
00236 }
00237 }
00238
00239 if (retrieve_entry(proto, src_addr) == NULL) {
00240 int sd, error = 0;
00241 struct arpreq ar;
00242 link_entry_t *sentry = new_link_entry(proto);
00243 sentry->node_id = src_addr;
00244 sentry->link.node.s_addr = src_addr;
00245 sentry->requester = 0;
00246
00247 ar.arp_ha.sa_family = AF_INET;
00248 strncpy(ar.arp_ha.sa_data, eh.ether_shost, sizeof(ar.arp_ha.sa_data));
00249 strncpy(ar.arp_dev, proto->sensor->interface, sizeof(ar.arp_dev));
00250 if ((sd = socket(PF_INET, SOCK_DGRAM, 0)) < 0) {
00251 syslog(LOG_ERR, "read_route_request: source backtrack socket %m");
00252 return -1;
00253 }
00254 if ((error = ioctl(sd, SIOCGRARP, &ar)) < 0) {
00255 syslog(LOG_ERR, "read_route_request: ioctl SIOCGRARP %m");
00256 return error;
00257 }
00258 sentry->link.next_hop = ((struct sockaddr_in*)(&ar.arp_pa))->sin_addr;
00259
00260 if ((error = add_entry(proto, src_addr, sentry)) < 0)
00261 return error;
00262 }
00263 return 0;
00264 }
00265
00266
00267 int route_idle_time(u_int32_t dest, protocol_t *proto)
00268 {
00269 link_entry_t *entry = retrieve_entry(proto, dest);
00270 if (entry == NULL) {
00271 errno = ENOLINK;
00272 return -1;
00273 }
00274
00275 return (int)(get_current_time() - entry->time_last_used);
00276 }
00277
00278
00279 static int init_on_demand(void)
00280 {
00281 int fd, error = 0;
00282 link_entry_t deflt;
00283
00285 system("sysctl -w net/ipv4/ip_forward=1");
00286 system("sysctl -w net/ipv4/conf/all/accept_redirects=0");
00287 system("sysctl -w net/ipv4/conf/all/send_redirects=0");
00288 system("sysctl -w net/ipv4/route/min_delay=0");
00289
00290 if ((fd = divert_init()) < 0) {
00291 syslog(LOG_ERR, "tun_init");
00292 return fd;
00293 }
00294
00295
00296 inet_aton("0.0.0.0", &deflt.link.node);
00297 inet_aton("0.0.0.0", &deflt.link.next_hop);
00298 deflt.iface = DIVERT_DEV_NAME;
00299 if ((error = add_kernel_route(&deflt)) < 0)
00300 return error;
00301 return fd;
00302 }
00303
00304
00305
00306 int on_demand(self_t *self)
00307 {
00308 int fd;
00309
00310 if (self == NULL) {
00311 errno = EINVAL;
00312 return -1;
00313 }
00314 if ((fd = init_on_demand()) < 0)
00315 return fd;
00316
00317 while (1) {
00318 int error;
00319 u_int32_t dest_addr;
00320 protocol_t *proto = NULL;
00321
00322 if ((error = read_route_request(self, fd, &dest_addr, proto)) <= 0) {
00323 if (error < 0)
00324 syslog(LOG_ERR, "read_route_request: %m");
00325 continue;
00326 }
00327 if ((error = route_discovery_pending(dest_addr, proto)) <= 0) {
00328 if (error < 0)
00329 syslog(LOG_ERR, "route_discovery_pending: %m");
00330 continue;
00331 }
00332 proto->mesh_init_discovery(proto, dest_addr);
00333 }
00334 }
00335
00336
00337
00338 int packet_usage(self_t *self)
00339 {
00340 int error;
00341 struct ipq_handle *qh;
00342
00343 if ((qh = ipq_create_handle(0, PF_INET)) < 0) {
00344 syslog(LOG_ERR, "ipq_create_handle %m");
00345 return -1;
00346 }
00347 if ((error = ipq_set_mode(qh, IPQ_COPY_META, 0)) < 0) {
00348 syslog(LOG_ERR, "ipq_set_mode (IPQ_COPY_META): %m");
00349 return -1;
00350 }
00351
00352 while (1) {
00353 unsigned int bufsize = sizeof(struct ip) + sizeof(struct udphdr);
00354 unsigned char buf[bufsize];
00355
00356 if ((error = ipq_read(qh, buf, bufsize, 0)) < 0) {
00357 syslog(LOG_ERR, "ipq_read %m");
00358 continue;
00359 }
00360
00361 switch (ipq_message_type(buf)) {
00362 case NLMSG_ERROR:
00363 syslog(LOG_ERR, "NLMSG_ERROR: %s", strerror(ipq_get_msgerr(buf)));
00364 break;
00365 case IPQM_PACKET:
00366 {
00367 ipq_packet_msg_t *pkt;
00368 struct iphdr *iph;
00369 link_entry_t *entry;
00370 protocol_t *proto = self->protocols;
00371
00372 if ((pkt = ipq_get_packet(buf)) == NULL) {
00373 syslog(LOG_ERR, "ipq_get_packet %m");
00374 break;
00375 }
00376 iph = (struct iphdr*)pkt->payload;
00377 while (proto != NULL) {
00378 if ((entry = retrieve_entry(proto, iph->daddr)) == NULL) {
00379 syslog(LOG_ERR, "no entry for %s: %m", ip_to_dot(iph->daddr));
00380 continue;
00381 }
00382 entry->time_last_used = get_current_time();
00383
00384 if ((entry = retrieve_entry(proto, iph->saddr)) == NULL) {
00385 syslog(LOG_ERR, "no entry for %s: %m", ip_to_dot(iph->saddr));
00386 continue;
00387 }
00388 entry->time_last_used = get_current_time();
00389
00390 proto = proto->next;
00391 }
00392
00393 if ((error = ipq_set_verdict(qh, pkt->packet_id,
00394 NF_ACCEPT, 0, NULL)) < 0)
00395 syslog(LOG_ERR, "ipq_set_verdict %m");
00396 break;
00397 }
00398 }
00399 }
00400 ipq_destroy_handle(qh);
00401 return 0;
00402 }