NETWORK ATTACKS FRAMEWORK
1.0.0
A NETwork Attacks framework. Making network attacks impact evaluation easier!
|
00001 /***************************************************************************** 00002 * 00003 * Copyright (C) 2001 Uppsala University and Ericsson AB. 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License as published by 00007 * the Free Software Foundation; either version 2 of the License, or 00008 * (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License 00016 * along with this program; if not, write to the Free Software 00017 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00018 * 00019 * Author: Erik Nordström, <erik.nordstrom@it.uu.se> 00020 * 00021 *****************************************************************************/ 00022 #include <stdlib.h> 00023 #include <stdio.h> 00024 #include <string.h> 00025 #include <sys/time.h> 00026 #include <unistd.h> 00027 #include <errno.h> 00028 #include <sys/types.h> 00029 #include <sys/socket.h> 00030 #include <asm/types.h> 00031 #include <linux/netlink.h> 00032 #include <sys/select.h> 00033 #include <netinet/in.h> 00034 #include <arpa/inet.h> 00035 #include <linux/rtnetlink.h> 00036 00037 #include "defs.h" 00038 #include "lnx/kaodv-netlink.h" 00039 #include "debug.h" 00040 #include "NA_aodv_rreq.h" 00041 #include "NA_aodv_timeout.h" 00042 #include "NA_routing_table.h" 00043 #include "NA_aodv_hello.h" 00044 #include "NA_params.h" 00045 #include "NA_aodv_socket.h" 00046 #include "NA_aodv_rerr.h" 00047 00048 /* Implements a Netlink socket communication channel to the kernel. Route 00049 * information and refresh messages are passed. */ 00050 00051 struct nlsock { 00052 int sock; 00053 int seq; 00054 struct sockaddr_nl local; 00055 }; 00056 00057 struct sockaddr_nl peer = { AF_NETLINK, 0, 0, 0 }; 00058 00059 struct nlsock aodvnl; 00060 struct nlsock rtnl; 00061 00062 static void nl_kaodv_callback(int sock); 00063 static void nl_rt_callback(int sock); 00064 00065 extern int llfeedback, active_route_timeout, qual_threshold, internet_gw_mode, 00066 wait_on_reboot; 00067 extern struct timer worb_timer; 00068 00069 #define BUFLEN 256 00070 00071 /* #define DEBUG_NETLINK */ 00072 00073 void nl_init(void) 00074 { 00075 int status; 00076 unsigned int addrlen; 00077 00078 memset(&peer, 0, sizeof(struct sockaddr_nl)); 00079 peer.nl_family = AF_NETLINK; 00080 peer.nl_pid = 0; 00081 peer.nl_groups = 0; 00082 00083 memset(&aodvnl, 0, sizeof(struct nlsock)); 00084 aodvnl.seq = 0; 00085 aodvnl.local.nl_family = AF_NETLINK; 00086 aodvnl.local.nl_groups = AODVGRP_NOTIFY; 00087 aodvnl.local.nl_pid = getpid(); 00088 00089 /* This is the AODV specific socket to communicate with the 00090 AODV kernel module */ 00091 aodvnl.sock = socket(PF_NETLINK, SOCK_RAW, NETLINK_AODV); 00092 00093 if (aodvnl.sock < 0) { 00094 perror("Unable to create AODV netlink socket"); 00095 exit(-1); 00096 } 00097 00098 00099 status = bind(aodvnl.sock, (struct sockaddr *) &aodvnl.local, 00100 sizeof(aodvnl.local)); 00101 00102 if (status == -1) { 00103 perror("Bind for AODV netlink socket failed"); 00104 exit(-1); 00105 } 00106 00107 addrlen = sizeof(aodvnl.local); 00108 00109 if (getsockname 00110 (aodvnl.sock, (struct sockaddr *) &aodvnl.local, &addrlen) < 0) { 00111 perror("Getsockname failed "); 00112 exit(-1); 00113 } 00114 00115 if (attach_callback_func(aodvnl.sock, nl_kaodv_callback) < 0) { 00116 alog(LOG_ERR, 0, __FUNCTION__, "Could not attach callback."); 00117 } 00118 /* This socket is the generic routing socket for adding and 00119 removing kernel routing table entries */ 00120 00121 memset(&rtnl, 0, sizeof(struct nlsock)); 00122 rtnl.seq = 0; 00123 rtnl.local.nl_family = AF_NETLINK; 00124 rtnl.local.nl_groups = 00125 RTMGRP_NOTIFY | RTMGRP_IPV4_IFADDR | RTMGRP_IPV4_ROUTE; 00126 rtnl.local.nl_pid = getpid(); 00127 00128 rtnl.sock = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE); 00129 00130 if (rtnl.sock < 0) { 00131 perror("Unable to create RT netlink socket"); 00132 exit(-1); 00133 } 00134 00135 addrlen = sizeof(rtnl.local); 00136 00137 status = bind(rtnl.sock, (struct sockaddr *) &rtnl.local, addrlen); 00138 00139 if (status == -1) { 00140 perror("Bind for RT netlink socket failed"); 00141 exit(-1); 00142 } 00143 00144 if (getsockname(rtnl.sock, (struct sockaddr *) &rtnl.local, &addrlen) < 00145 0) { 00146 perror("Getsockname failed "); 00147 exit(-1); 00148 } 00149 00150 if (attach_callback_func(rtnl.sock, nl_rt_callback) < 0) { 00151 alog(LOG_ERR, 0, __FUNCTION__, "Could not attach callback."); 00152 } 00153 } 00154 00155 void nl_cleanup(void) 00156 { 00157 close(aodvnl.sock); 00158 close(rtnl.sock); 00159 } 00160 00161 00162 static void nl_kaodv_callback(int sock) 00163 { 00164 int len; 00165 socklen_t addrlen; 00166 struct nlmsghdr *nlm; 00167 struct nlmsgerr *nlmerr; 00168 char buf[BUFLEN]; 00169 struct in_addr dest_addr, src_addr; 00170 kaodv_rt_msg_t *m; 00171 rt_table_t *rt, *fwd_rt, *rev_rt = NULL; 00172 00173 addrlen = sizeof(struct sockaddr_nl); 00174 00175 00176 len = 00177 recvfrom(sock, buf, BUFLEN, 0, (struct sockaddr *) &peer, &addrlen); 00178 00179 if (len <= 0) 00180 return; 00181 00182 nlm = (struct nlmsghdr *) buf; 00183 00184 switch (nlm->nlmsg_type) { 00185 case NLMSG_ERROR: 00186 nlmerr = NLMSG_DATA(nlm); 00187 if (nlmerr->error == 0) { 00188 /* DEBUG(LOG_DEBUG, 0, "NLMSG_ACK"); */ 00189 } else { 00190 DEBUG(LOG_DEBUG, 0, "NLMSG_ERROR, error=%d type=%s", 00191 nlmerr->error, 00192 kaodv_msg_type_to_str(nlmerr->msg.nlmsg_type)); 00193 } 00194 break; 00195 00196 case KAODVM_DEBUG: 00197 DEBUG(LOG_DEBUG, 0, "kaodv: %s", NLMSG_DATA(nlm)); 00198 break; 00199 case KAODVM_TIMEOUT: 00200 m = NLMSG_DATA(nlm); 00201 dest_addr.s_addr = m->dst; 00202 00203 DEBUG(LOG_DEBUG, 0, 00204 "Got TIMEOUT msg from kernel for %s", 00205 ip_to_str(dest_addr)); 00206 00207 rt = rt_table_find(dest_addr); 00208 00209 if (rt && rt->state == VALID) 00210 route_expire_timeout(rt); 00211 else 00212 DEBUG(LOG_DEBUG, 0, 00213 "Got rt timeoute event but there is no route"); 00214 break; 00215 case KAODVM_ROUTE_REQ: 00216 m = NLMSG_DATA(nlm); 00217 dest_addr.s_addr = m->dst; 00218 00219 DEBUG(LOG_DEBUG, 0, "Got ROUTE_REQ: %s from kernel", 00220 ip_to_str(dest_addr)); 00221 00222 rreq_route_discovery(dest_addr, 0, NULL); 00223 break; 00224 case KAODVM_REPAIR: 00225 m = NLMSG_DATA(nlm); 00226 dest_addr.s_addr = m->dst; 00227 src_addr.s_addr = m->src; 00228 00229 DEBUG(LOG_DEBUG, 0, "Got REPAIR from kernel for %s", 00230 ip_to_str(dest_addr)); 00231 00232 fwd_rt = rt_table_find(dest_addr); 00233 00234 if (fwd_rt) 00235 rreq_local_repair(fwd_rt, src_addr, NULL); 00236 00237 break; 00238 case KAODVM_ROUTE_UPDATE: 00239 m = NLMSG_DATA(nlm); 00240 00241 00242 dest_addr.s_addr = m->dst; 00243 src_addr.s_addr = m->src; 00244 00245 // DEBUG(LOG_DEBUG, 0, "ROute update s=%s d=%s", ip_to_str(src_addr), ip_to_str(dest_addr)); 00246 if (dest_addr.s_addr == AODV_BROADCAST || 00247 dest_addr.s_addr == 00248 DEV_IFINDEX(m->ifindex).broadcast.s_addr) 00249 return; 00250 00251 fwd_rt = rt_table_find(dest_addr); 00252 rev_rt = rt_table_find(src_addr); 00253 00254 rt_table_update_route_timeouts(fwd_rt, rev_rt); 00255 00256 break; 00257 case KAODVM_SEND_RERR: 00258 m = NLMSG_DATA(nlm); 00259 dest_addr.s_addr = m->dst; 00260 src_addr.s_addr = m->src; 00261 00262 if (dest_addr.s_addr == AODV_BROADCAST || 00263 dest_addr.s_addr == 00264 DEV_IFINDEX(m->ifindex).broadcast.s_addr) 00265 return; 00266 00267 fwd_rt = rt_table_find(dest_addr); 00268 rev_rt = rt_table_find(src_addr); 00269 00270 do { 00271 struct in_addr rerr_dest; 00272 RERR *rerr; 00273 00274 DEBUG(LOG_DEBUG, 0, 00275 "Sending RERR for unsolicited message from %s to dest %s", 00276 ip_to_str(src_addr), ip_to_str(dest_addr)); 00277 00278 if (fwd_rt) { 00279 rerr = rerr_create(0, fwd_rt->dest_addr, 00280 fwd_rt->dest_seqno); 00281 00282 rt_table_update_timeout(fwd_rt, DELETE_PERIOD); 00283 } else 00284 rerr = rerr_create(0, dest_addr, 0); 00285 00286 /* Unicast the RERR to the source of the data transmission 00287 * if possible, otherwise we broadcast it. */ 00288 00289 if (rev_rt && rev_rt->state == VALID) 00290 rerr_dest = rev_rt->next_hop; 00291 else 00292 rerr_dest.s_addr = AODV_BROADCAST; 00293 00294 aodv_socket_send((AODV_msg *) rerr, rerr_dest, 00295 RERR_CALC_SIZE(rerr), 1, 00296 &DEV_IFINDEX(m->ifindex)); 00297 00298 if (wait_on_reboot) { 00299 DEBUG(LOG_DEBUG, 0, 00300 "Wait on reboot timer reset."); 00301 timer_set_timeout(&worb_timer, DELETE_PERIOD); 00302 } 00303 } while (0); 00304 break; 00305 default: 00306 DEBUG(LOG_DEBUG, 0, "Got mesg type=%d\n", nlm->nlmsg_type); 00307 } 00308 00309 } 00310 static void nl_rt_callback(int sock) 00311 { 00312 int len, attrlen; 00313 socklen_t addrlen; 00314 struct nlmsghdr *nlm; 00315 struct nlmsgerr *nlmerr; 00316 char buf[BUFLEN]; 00317 struct ifaddrmsg *ifm; 00318 struct rtattr *rta; 00319 00320 addrlen = sizeof(struct sockaddr_nl); 00321 00322 len = 00323 recvfrom(sock, buf, BUFLEN, 0, (struct sockaddr *) &peer, &addrlen); 00324 00325 if (len <= 0) 00326 return; 00327 00328 nlm = (struct nlmsghdr *) buf; 00329 00330 switch (nlm->nlmsg_type) { 00331 case NLMSG_ERROR: 00332 nlmerr = NLMSG_DATA(nlm); 00333 if (nlmerr->error == 0) { 00334 /* DEBUG(LOG_DEBUG, 0, "NLMSG_ACK"); */ 00335 } else { 00336 DEBUG(LOG_DEBUG, 0, "NLMSG_ERROR, error=%d type=%d", 00337 nlmerr->error, nlmerr->msg.nlmsg_type); 00338 } 00339 break; 00340 case RTM_NEWLINK: 00341 DEBUG(LOG_DEBUG, 0, "RTM_NEWADDR"); 00342 break; 00343 case RTM_NEWADDR: 00344 ifm = NLMSG_DATA(nlm); 00345 00346 rta = (struct rtattr *) ((char *) ifm + sizeof(ifm)); 00347 00348 attrlen = nlm->nlmsg_len - 00349 sizeof(struct nlmsghdr) - sizeof(struct ifaddrmsg); 00350 00351 for (; RTA_OK(rta, attrlen); rta = RTA_NEXT(rta, attrlen)) { 00352 00353 if (rta->rta_type == IFA_ADDRESS) { 00354 struct in_addr ifaddr; 00355 00356 memcpy(&ifaddr, RTA_DATA(rta), 00357 RTA_PAYLOAD(rta)); 00358 00359 DEBUG(LOG_DEBUG, 0, 00360 "Interface index %d changed address to %s", 00361 ifm->ifa_index, ip_to_str(ifaddr)); 00362 } 00363 } 00364 break; 00365 case RTM_NEWROUTE: 00366 /* DEBUG(LOG_DEBUG, 0, "RTM_NEWROUTE"); */ 00367 break; 00368 } 00369 return; 00370 } 00371 00372 int prefix_length(int family, void *nm) 00373 { 00374 int prefix = 0; 00375 00376 if (family == AF_INET) { 00377 unsigned int tmp; 00378 memcpy(&tmp, nm, sizeof(unsigned int)); 00379 00380 while (tmp) { 00381 tmp = tmp << 1; 00382 prefix++; 00383 } 00384 return prefix; 00385 00386 } else { 00387 DEBUG(LOG_DEBUG, 0, "Unsupported address family"); 00388 } 00389 00390 return 0; 00391 } 00392 00393 /* Utility function comes from IPv4Route2. 00394 Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> */ 00395 int addattr(struct nlmsghdr *n, int type, void *data, int alen) 00396 { 00397 struct rtattr *attr; 00398 int len = RTA_LENGTH(alen); 00399 00400 attr = (struct rtattr *) (((char *) n) + NLMSG_ALIGN(n->nlmsg_len)); 00401 attr->rta_type = type; 00402 attr->rta_len = len; 00403 memcpy(RTA_DATA(attr), data, alen); 00404 n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + len; 00405 00406 return 0; 00407 } 00408 00409 00410 #define ATTR_BUFLEN 512 00411 00412 int nl_send(struct nlsock *nl, struct nlmsghdr *n) 00413 { 00414 int res; 00415 struct iovec iov = { (void *) n, n->nlmsg_len }; 00416 struct msghdr msg = 00417 { (void *) &peer, sizeof(peer), &iov, 1, NULL, 0, 0 }; 00418 // int flags = 0; 00419 00420 if (!nl) 00421 return -1; 00422 00423 n->nlmsg_seq = ++nl->seq; 00424 n->nlmsg_pid = nl->local.nl_pid; 00425 00426 /* Request an acknowledgement by setting NLM_F_ACK */ 00427 n->nlmsg_flags |= NLM_F_ACK; 00428 00429 /* Send message to netlink interface. */ 00430 res = sendmsg(nl->sock, &msg, 0); 00431 00432 if (res < 0) { 00433 fprintf(stderr, "error: %s\n", strerror(errno)); 00434 return -1; 00435 } 00436 return 0; 00437 } 00438 00439 /* Function to add, remove and update entries in the kernel routing 00440 * table */ 00441 int nl_kern_route(int action, int flags, int family, 00442 int index, struct in_addr *dst, struct in_addr *gw, 00443 struct in_addr *nm, int metric) 00444 { 00445 struct { 00446 struct nlmsghdr nlh; 00447 struct rtmsg rtm; 00448 char attrbuf[1024]; 00449 } req; 00450 00451 if (!dst || !gw) 00452 return -1; 00453 00454 req.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)); 00455 req.nlh.nlmsg_type = action; 00456 req.nlh.nlmsg_flags = NLM_F_REQUEST | flags; 00457 req.nlh.nlmsg_pid = 0; 00458 00459 req.rtm.rtm_family = family; 00460 00461 if (!nm) 00462 req.rtm.rtm_dst_len = sizeof(struct in_addr) * 8; 00463 else 00464 req.rtm.rtm_dst_len = prefix_length(AF_INET, nm); 00465 00466 req.rtm.rtm_src_len = 0; 00467 req.rtm.rtm_tos = 0; 00468 req.rtm.rtm_table = RT_TABLE_MAIN; 00469 req.rtm.rtm_protocol = 100; 00470 req.rtm.rtm_scope = RT_SCOPE_LINK; 00471 req.rtm.rtm_type = RTN_UNICAST; 00472 req.rtm.rtm_flags = 0; 00473 00474 addattr(&req.nlh, RTA_DST, dst, sizeof(struct in_addr)); 00475 00476 if (memcmp(dst, gw, sizeof(struct in_addr)) != 0) { 00477 req.rtm.rtm_scope = RT_SCOPE_UNIVERSE; 00478 addattr(&req.nlh, RTA_GATEWAY, gw, sizeof(struct in_addr)); 00479 } 00480 00481 if (index > 0) 00482 addattr(&req.nlh, RTA_OIF, &index, sizeof(index)); 00483 00484 addattr(&req.nlh, RTA_PRIORITY, &metric, sizeof(metric)); 00485 00486 return nl_send(&rtnl, &req.nlh); 00487 } 00488 00489 int nl_send_add_route_msg(struct in_addr dest, struct in_addr next_hop, 00490 int metric, u_int32_t lifetime, int rt_flags, 00491 int ifindex) 00492 { 00493 struct { 00494 struct nlmsghdr n; 00495 struct kaodv_rt_msg m; 00496 } areq; 00497 00498 DEBUG(LOG_DEBUG, 0, "ADD/UPDATE: %s:%s ifindex=%d", 00499 ip_to_str(dest), ip_to_str(next_hop), ifindex); 00500 00501 memset(&areq, 0, sizeof(areq)); 00502 00503 areq.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct kaodv_rt_msg)); 00504 areq.n.nlmsg_type = KAODVM_ADDROUTE; 00505 areq.n.nlmsg_flags = NLM_F_REQUEST; 00506 00507 areq.m.dst = dest.s_addr; 00508 areq.m.nhop = next_hop.s_addr; 00509 areq.m.time = lifetime; 00510 areq.m.ifindex = ifindex; 00511 00512 if (rt_flags & RT_INET_DEST) { 00513 areq.m.flags |= KAODV_RT_GW_ENCAP; 00514 } 00515 00516 if (rt_flags & RT_REPAIR) 00517 areq.m.flags |= KAODV_RT_REPAIR; 00518 00519 if (nl_send(&aodvnl, &areq.n) < 0) { 00520 DEBUG(LOG_DEBUG, 0, "Failed to send netlink message"); 00521 return -1; 00522 } 00523 #ifdef DEBUG_NETLINK 00524 DEBUG(LOG_DEBUG, 0, "Sending add route"); 00525 #endif 00526 return nl_kern_route(RTM_NEWROUTE, NLM_F_CREATE, 00527 AF_INET, ifindex, &dest, &next_hop, NULL, metric); 00528 } 00529 00530 int nl_send_no_route_found_msg(struct in_addr dest) 00531 { 00532 struct { 00533 struct nlmsghdr n; 00534 kaodv_rt_msg_t m; 00535 } areq; 00536 00537 memset(&areq, 0, sizeof(areq)); 00538 00539 areq.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct kaodv_rt_msg)); 00540 areq.n.nlmsg_type = KAODVM_NOROUTE_FOUND; 00541 areq.n.nlmsg_flags = NLM_F_REQUEST; 00542 00543 areq.m.dst = dest.s_addr; 00544 00545 DEBUG(LOG_DEBUG, 0, "Send NOROUTE_FOUND to kernel: %s", 00546 ip_to_str(dest)); 00547 00548 return nl_send(&aodvnl, &areq.n); 00549 } 00550 00551 int nl_send_del_route_msg(struct in_addr dest, struct in_addr next_hop, int metric) 00552 { 00553 int index = -1; 00554 struct { 00555 struct nlmsghdr n; 00556 struct kaodv_rt_msg m; 00557 } areq; 00558 00559 DEBUG(LOG_DEBUG, 0, "Send DEL_ROUTE to kernel: %s", ip_to_str(dest)); 00560 00561 memset(&areq, 0, sizeof(areq)); 00562 00563 areq.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct kaodv_rt_msg)); 00564 areq.n.nlmsg_type = KAODVM_DELROUTE; 00565 areq.n.nlmsg_flags = NLM_F_REQUEST; 00566 00567 areq.m.dst = dest.s_addr; 00568 areq.m.nhop = next_hop.s_addr; 00569 areq.m.time = 0; 00570 areq.m.flags = 0; 00571 00572 if (nl_send(&aodvnl, &areq.n) < 0) { 00573 DEBUG(LOG_DEBUG, 0, "Failed to send netlink message"); 00574 return -1; 00575 } 00576 #ifdef DEBUG_NETLINK 00577 DEBUG(LOG_DEBUG, 0, "Sending del route"); 00578 #endif 00579 return nl_kern_route(RTM_DELROUTE, 0, AF_INET, index, &dest, &next_hop, 00580 NULL, metric); 00581 } 00582 00583 int nl_send_conf_msg(void) 00584 { 00585 struct { 00586 struct nlmsghdr n; 00587 kaodv_conf_msg_t cm; 00588 } areq; 00589 00590 memset(&areq, 0, sizeof(areq)); 00591 00592 areq.n.nlmsg_len = NLMSG_LENGTH(sizeof(kaodv_conf_msg_t)); 00593 areq.n.nlmsg_type = KAODVM_CONFIG; 00594 areq.n.nlmsg_flags = NLM_F_REQUEST; 00595 00596 areq.cm.qual_th = qual_threshold; 00597 areq.cm.active_route_timeout = active_route_timeout; 00598 areq.cm.is_gateway = internet_gw_mode; 00599 00600 #ifdef DEBUG_NETLINK 00601 DEBUG(LOG_DEBUG, 0, "Sending aodv conf msg"); 00602 #endif 00603 return nl_send(&aodvnl, &areq.n); 00604 }