+#ifdef CENTRALIZED_ROUTING
+/*
+ * Given a source and destination, send a source-routed route install message
+ * that will install the correct routes.
+ *
+ * NOTE: Make sure that this is the correct way to create a new packet
+ */
+time_t last_install;
+void install_route(struct split_ip_msg *amsg, uint8_t flags) {
+ uint8_t buf[sizeof(struct split_ip_msg) + INET_MTU];
+ struct split_ip_msg *msg = (struct split_ip_msg *)buf;
+ int offset = 0;
+
+
+ struct ip6_ext *ext = (struct ip6_ext *)(msg->next);
+ struct tlv_hdr *tlv = (struct tlv_hdr *)(ext + 1);
+ struct rinstall_header *rih = (struct rinstall_header *)(tlv + 1);
+
+ path_t* path = nw_get_route(ntohs(amsg->hdr.ip6_src.s6_addr16[7]), ntohs(amsg->hdr.ip6_dst.s6_addr16[7]));
+ path_t* i;
+ time_t current_time;
+
+#if 0
+ time(¤t_time);
+
+ if (current_time < last_install + 2) {
+ debug("Not sending install\n");
+ return;
+ }
+ time(&last_install);
+#endif
+
+
+ if (path == NULL || path->isController) return;
+ fprintf(stderr, "install_route for src: 0x%x, dest: 0x%x, flags: %x\n",
+ ntohs(amsg->hdr.ip6_src.s6_addr16[7]), ntohs(amsg->hdr.ip6_dst.s6_addr16[7]), path->length);
+ if (path->length > 10) return;
+
+ memset((uint8_t *)&msg->hdr, 0, sizeof(struct ip6_hdr));
+
+ // Set IP Header options
+ msg->hdr.hlim = 0x64; // CHECK THIS
+ msg->hdr.nxt_hdr = IPV6_DEST;
+ msg->hdr.vlfc[0] = IPV6_VERSION << 4;
+ msg->flow_id = local_seqno++;
+
+ memcpy(&msg->hdr.ip6_src, &__my_address, sizeof(struct in6_addr));
+ memcpy(&msg->hdr.ip6_dst, &amsg->hdr.ip6_src, sizeof(struct in6_addr));
+ msg->headers = NULL;
+
+ ext->nxt_hdr = IPV6_NONEXT;
+ ext->len = sizeof(struct ip6_ext) + sizeof(struct tlv_hdr) + sizeof(struct rinstall_header)
+ + (path->length * sizeof(uint16_t));
+
+ tlv->len = ext->len - sizeof(struct ip6_ext);
+ tlv->type = TLV_TYPE_INSTALL;
+
+ // Setup rinstall_header
+ // Size is longer because we put the src in there
+ rih->flags = flags;
+ rih->match.src = htons(T_INVAL_NEIGH);
+ rih->match.dest = amsg->hdr.ip6_dst.s6_addr16[7];
+ rih->path_len = path->length;
+
+ // Convert to host so add_headers_list works
+ msg->hdr.plen = htons(ext->len);
+
+ info("install_route len: 0x%x\n", rih->path_len);
+
+ fprintf(stderr, "from 0x%x to 0x%x [%i]: ",
+ ntohs(amsg->hdr.ip6_src.s6_addr16[7]), ntohs(amsg->hdr.ip6_dst.s6_addr16[7]), path->length);
+ // rih->path[0] = amsg->hdr.ip6_src.s6_addr16[7]; //htons(l2fromIP(amsg->hdr.ip6_src.s6_addr));
+ for (i = path; i != NULL; i = i->next) {
+ fprintf(stderr, "0x%x ", i->node);
+ rih->path[offset++] = htons(i->node);
+ }
+
+ nw_free_path(path);
+
+ add_header_list(msg);
+ print_ip_packet(msg);
+ loglevel_t old_lvl = log_setlevel(LOGLVL_DEBUG);
+ ip_to_pan(msg);
+ log_setlevel(old_lvl);
+ free_split_msg(msg);
+}
+
+void uninstall_route(uint16_t n1, uint16_t n2) {
+ uint8_t buf[sizeof(struct split_ip_msg) + INET_MTU];
+ struct split_ip_msg *msg = (struct split_ip_msg *)buf;
+ struct ip6_ext *ext = (struct ip6_ext *)(msg->next);
+ struct tlv_hdr *tlv = (struct tlv_hdr *)(ext + 1);
+ struct rinstall_header *rih = (struct rinstall_header *)(tlv + 1);
+
+ // Set IP Header options
+ msg->hdr.hlim = 0x64; // CHECK THIS
+ msg->hdr.nxt_hdr = IPV6_DEST;
+ msg->hdr.vlfc[0] = IPV6_VERSION << 4;
+ msg->flow_id = local_seqno++;
+
+ memcpy(&msg->hdr.ip6_src, &__my_address, sizeof(struct in6_addr));
+ memcpy(&msg->hdr.ip6_dst, &__my_address, sizeof(struct in6_addr));
+ msg->hdr.ip6_dst.s6_addr16[7] = htons(n1);
+ msg->headers = NULL;
+
+ ext->nxt_hdr = IPV6_NONEXT;
+ ext->len = sizeof(struct ip6_ext) + sizeof(struct tlv_hdr) + sizeof(struct rinstall_header);
+
+ tlv->len = ext->len - sizeof(struct ip6_ext);
+ tlv->type = TLV_TYPE_INSTALL;
+
+ // Convert to host so add_headers_list works
+ msg->hdr.plen = htons(ext->len);
+
+ rih->flags = HYDRO_INSTALL_UNINSTALL_MASK | HYDRO_METHOD_SOURCE;
+ rih->match.src = htons(n1);
+ rih->match.dest = htons(n2);
+ rih->path_len = 0;
+
+
+ add_header_list(msg);
+ print_ip_packet(msg);
+ loglevel_t old_lvl = log_setlevel(LOGLVL_DEBUG);
+ ip_to_pan(msg);
+ log_setlevel(old_lvl);
+ free_split_msg(msg);
+}
+
+#endif
+