#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <string.h>
#include <time.h>
#include "agentapi.h"
#include "auth.h"
#include "debug.h"
#include "msgparser.h"
#include "proxyarp.h"
#include "util.h"
#include "mn.h"
#include "fileio.h"
Include dependency graph for mn_reg.c:
Go to the source code of this file.
Data Structures | |
struct | rowdata |
struct | device |
struct | mobile |
Typedefs | |
typedef device | DEVICE |
typedef rowdata | ROWDATA |
Functions | |
int | send_registration (int request_type) |
int | handle_registration (int s) |
int | send_messages (int interval) |
DYNAMO - seconds between messages Returns 1 on success. | |
int | create_mobile () |
DYNAMO. | |
int | readfile (char file[]) |
int | parse_rows (int i) |
DYNAMO parse_rows: - Rows to parse. | |
int | main (int argc, char *argv[]) |
Variables | |
mn_data | mn |
mn_config | config |
timeval | timers [TIMER_COUNT] |
int | intervals [5000] |
int | rownumber = 0 |
DEVICE | devices [5000] |
ROWDATA | rows [5000] |
int | sent_regs |
int | sent_deregs |
tm * | tmptr |
time_t | tm |
char | timestr [60] |
mobile | mobile_array [20] |
int | cur_mobile = 0 |
int | mobiles = 0 |
int create_mobile | ( | ) |
DYNAMO.
Returns 1 on success
Creates virtual mobile nodes in mobile_array from devices array which is read from mobiles.txt
Definition at line 1528 of file mn_reg.c.
References mn_data::co_addr, mobile::config, devices, mn_config::ha_ip_addr_orig, mn, mobile::mn, mn_config::mn_home_ip_addr_orig, mn_config::mn_nai, mn_config::mn_nai_len, mobile_array, mobiles, device::nai, rownumber, and mobile::state.
Referenced by main().
01529 { 01530 int i =0; 01531 01532 for(i=0;i<rownumber-1;i++) 01533 { 01534 if(devices[i].ip_home==NULL) return -1;//file read but it was empty, quit! 01535 mobile_array[i].mn=mn; 01536 mobile_array[i].config=config; 01537 mobile_array[i].config.mn_home_ip_addr.s_addr=inet_addr(devices[i].ip_home); 01538 mobile_array[i].config.mn_home_ip_addr_orig.s_addr=inet_addr(devices[i].ip_home); 01539 mobile_array[i].config.ha_ip_addr.s_addr=inet_addr(devices[i].ip_homeagent); 01540 mobile_array[i].config.ha_ip_addr_orig.s_addr=inet_addr(devices[i].ip_homeagent); 01541 mobile_array[i].config.mn_nai_len=sizeof(devices[i].nai); 01542 memcpy(mobile_array[i].config.mn_nai, devices[i].nai,sizeof(devices[i].nai)); 01543 mobile_array[i].mn.co_addr.s_addr=inet_addr(devices[i].ip_careoff); 01544 mobile_array[i].state=atoi(devices[i].state); 01545 mobiles=mobiles+1; 01546 } 01547 01548 }
int handle_registration | ( | int | s | ) |
Definition at line 1402 of file mn_reg.c.
References DEBUG(), DEBUG_INFO, DEBUG_MESSAGES, mn_data::discarded_msgs, mn_data::last_challenge_ext, mn_data::last_challenge_time, mn_data::last_nonce, mn_data::last_reply_code, mn_data::last_reply_rcvd, LOG2, MAXMSG, mn, mobile::mn, mobile_array, mn_data::prev_req_replied, and mn_data::try_to_fix_sec_assoc.
Referenced by main_vanha().
01403 { 01404 char msg[MAXMSG]; 01405 unsigned int len; 01406 struct sockaddr_in addr; 01407 int n, res; 01408 struct msg_extensions ext; 01409 01410 len = sizeof(addr); 01411 01412 n = recvfrom(s, msg, MAXMSG, 0, (struct sockaddr*) &addr, &len); 01413 if (n < 0) { 01414 LOG2(LOG_ERR, "registration recv: %s\n", strerror(errno)); 01415 return 0; 01416 } 01417 DEBUG(DEBUG_MESSAGES, "Received %d bytes from %s:%d\n", n, 01418 inet_ntoa(addr.sin_addr), ntohs(addr.sin_port)); 01419 01420 res = parse_msg(msg, n, &ext); 01421 if (res != 0 || ext.double_auth_ext != 0) { 01422 char *reason = "N/A"; 01423 DEBUG(DEBUG_MESSAGES, "Dropping invalid message\n"); 01424 mobile_array[cur_mobile].mn.discarded_msgs++; 01425 if (res == -1) 01426 reason = "unknown extension"; 01427 else if (res == -2) 01428 reason = "malformed message"; 01429 else if (res == -3 || res == -4 || res == -5) 01430 reason = "unknown vendor extension"; 01431 else if (ext.double_auth_ext != 0) 01432 reason = "double authentication extension"; 01433 report_discarded_msg(msg, n, &addr, reason); 01434 return 0; 01435 } 01436 01437 mobile_array[cur_mobile].mn.try_to_fix_sec_assoc = 0; 01438 if (is_valid_reply(&ext, addr)) { 01439 mobile_array[cur_mobile].mn.prev_req_replied = 1; 01440 time(&mobile_array[cur_mobile].mn.last_reply_rcvd); 01441 mobile_array[cur_mobile].mn.last_reply_code = ext.rep->code; 01442 mobile_array[cur_mobile].mn.last_nonce = ext.rep->id[0]; 01443 if (ext.challenge != NULL) { 01444 int len; 01445 gettimeofday(&mobile_array[cur_mobile].mn.last_challenge_time, NULL); 01446 len = GET_CHALLENGE_EXT_LEN(ext.challenge); 01447 if (mobile_array[cur_mobile].mn.last_challenge_ext == NULL || 01448 GET_CHALLENGE_EXT_LEN(mobile_array[cur_mobile].mn.last_challenge_ext) != 01449 len) { 01450 if (mobile_array[cur_mobile].mn.last_challenge_ext != NULL) 01451 free(mobile_array[cur_mobile].mn.last_challenge_ext); 01452 mobile_array[cur_mobile].mn.last_challenge_ext = 01453 (struct challenge_ext *) malloc(len); 01454 } 01455 01456 if (mobile_array[cur_mobile].mn.last_challenge_ext != NULL) 01457 memcpy(mobile_array[cur_mobile].mn.last_challenge_ext, ext.challenge, 01458 len); 01459 else 01460 DEBUG(DEBUG_INFO, "Could not malloc() memory " 01461 "for challenge extension\n"); 01462 } 01463 if (IS_REGREP_ACCEPTED(ext.rep->code)) 01464 handle_reg_accept(&ext); 01465 else 01466 return handle_reg_denied(&ext); 01467 } else { 01468 report_discarded_msg(msg, n, &addr, "invalid reply"); 01469 mobile_array[cur_mobile].mn.discarded_msgs++; 01470 } 01471 01472 return 0; 01473 }
Here is the call graph for this function:
int main | ( | int | argc, | |
char * | argv[] | |||
) |
Definition at line 1607 of file mn_reg.c.
References create_mobile(), mn_init(), parse_rows(), readfile(), rownumber, send_messages(), sent_deregs, and sent_regs.
01609 { 01610 printf("Virtual foreign agent v0.1. \n Sending registeration messages with interval: %i \n", 3); 01611 mn_init(); //read dynmnd.conf to make "meta mobile node" 01612 if(argc==2) readfile(argv[1]); 01613 else 01614 { 01615 printf("No filename given - using default /home/dynamo/mobiles.txt \n"); 01616 readfile("/home/dynamo/mobiles.txt"); //read cfg 01617 } 01618 01619 parse_rows(rownumber); //parse lines 01620 create_mobile(); //creates virtual mobile nodes into array 01621 send_messages(3); //sends register messages with given interval 01622 printf("Sent %i REGISTER messages and %i DEREGISTER messages \n", sent_regs, sent_deregs); 01623 01624 return EXIT_SUCCESS; 01625 }
Here is the call graph for this function:
int parse_rows | ( | int | i | ) |
DYNAMO parse_rows: - Rows to parse.
Parse rows
Definition at line 1592 of file mn_reg.c.
Referenced by main().
01592 { 01593 01594 int j; 01595 01596 for (j=0; j<i; j++) 01597 { 01598 sscanf (rows[j].row,"%s %s %s %s %s %s ",devices[j].timestart,devices[j].state,devices[j].ip_home,devices[j].ip_homeagent,devices[j].ip_careoff,devices[j].nai,); 01599 01600 } 01601 01602 return 1; 01603 }
int readfile | ( | char | file[] | ) |
Definition at line 1560 of file mn_reg.c.
References rownumber, and rows.
Referenced by main().
01560 { 01561 01562 FILE *fileo; 01563 01564 fileo = fopen(file,"r"); 01565 01566 if(file==NULL) { 01567 printf("Do not Open.\n"); 01568 return 1; 01569 } 01570 01571 int i=0; 01572 01573 while (!feof(fileo)) 01574 { 01575 fgets(rows[i].row, sizeof(rows[i].row), fileo); 01576 i=i+1; 01577 rownumber=rownumber+1; 01578 } 01579 01580 01581 return 1; 01582 }
int send_messages | ( | int | interval | ) |
DYNAMO - seconds between messages Returns 1 on success.
Sends registeration and deregesteration messages
Definition at line 1483 of file mn_reg.c.
References mobile::config, devices, mobile::mn, mn_config::mn_nai, mobile_array, mobiles, REG_CONNECT, REG_DISC, mn_data::req_lifetime, send_registration(), sent_deregs, sent_regs, timestr, tm, and tmptr.
Referenced by main().
01484 { 01485 int i=0; 01486 for(i;i<mobiles-1;i++){ 01487 tm=time(NULL); 01488 tmptr =localtime(&tm); 01489 strftime(timestr,100, " %X",tmptr); //get time 01490 if((i+1)<mobiles) //check that we're not trying to go out of array 01491 { 01492 if(interval=atoi(devices[i+1].timestart)-atoi(devices[i].timestart)<0) interval=3; //timeline fuxxored, no negative times->use default 3 seconds TODO: read from given interval 01493 else interval=atoi(devices[i+1].timestart)-atoi(devices[i].timestart); //given wait ok 01494 } 01495 else interval=3; //wait 3 seconds after quit TODO read from given interval 01496 01497 01498 if(mobile_array[cur_mobile].state==0) //joint 01499 { 01500 mobile_array[cur_mobile].mn.req_lifetime = 600; 01501 printf("%s REGISTERATION message with home address: %s , NAI: %s and interval: %i \n" , timestr, inet_ntoa(mobile_array[cur_mobile].config.mn_home_ip_addr),mobile_array[cur_mobile].config.mn_nai, interval); 01502 send_registration(REG_CONNECT); //send reg 01503 sent_regs++; 01504 } 01505 else //leave TODO if state==1 and if state==2 !! 01506 { 01507 printf("%s DEREGISTERATION message with home address: %s and NAI: %s and interval %i \n", timestr, inet_ntoa(mobile_array[cur_mobile].config.mn_home_ip_addr), mobile_array[cur_mobile].config.mn_nai, interval); 01508 mobile_array[cur_mobile].mn.req_lifetime = 0; 01509 send_registration(REG_DISC); //send dereg 01510 sent_deregs++; 01511 } 01512 cur_mobile=cur_mobile+1; //next mobile 01513 01514 sleep(interval); 01515 } 01516 cur_mobile=0; //back to start, just in case 01517 01518 return 1; 01519 }
Here is the call graph for this function:
int send_registration | ( | int | request_type | ) |
Definition at line 580 of file mn_reg.c.
References add_fa_host_route(), agentadv_data::addr, agentadv_data::adv, agentadv_data::adv_type, mn_data::agentadv, agentadv_data::arpentry, mobile::config, mn_data::current_adv, DEBUG(), DEBUG_INFO, DEBUG_MESSAGES, DEBUG_TIMERS, mn_config::enable_fa_decapsulation, mn_data::fa_addr, agentadv_data::ifindex, agentadv_data::ifname, agentadv_data::in_use, mn_data::last_reg_send_time, mn_data::last_request_sent, LOG2, MAXMSG, mobile::mn, mn, MN_ADV_TYPE_FA, mobile_array, REG_DISC, agentadv_data::reg_failed, mn_data::registration_id, mn_data::registration_socket, agentadv_data::routeentry, TIMER_REQUEST, timers, TUNMODE_AUTO_REVERSE, TUNMODE_AUTO_TRIANGLE, TUNMODE_REVERSE, TUNMODE_TRIANGLE, mn_config::tunneling_mode, and mn_config::udp_port.
Referenced by clean_up(), close_for_home(), disconnect(), request_tunnel(), and send_messages().
00581 { 00582 char sendbuf[MAXMSG]; 00583 char *pos; /* pointer to next byte to write in sendbuf */ 00584 int n, len; 00585 struct sockaddr_in addr; 00586 int use_reverse; 00587 struct msg_extensions ext; 00588 00589 if (MAXMSG < (sizeof(struct reg_req) + 00590 2 * (sizeof(struct msg_auth) + 16))) { 00591 DEBUG(DEBUG_INFO, "MN: send_reg: too small send buffer!"); 00592 00593 return -1; 00594 } 00595 00596 use_reverse = mobile_array[cur_mobile].config.tunneling_mode == TUNMODE_AUTO_REVERSE || 00597 mobile_array[cur_mobile].config.tunneling_mode == TUNMODE_REVERSE; 00598 00599 if (mobile_array[cur_mobile].mn.current_adv != NULL) { 00600 if (mobile_array[cur_mobile].mn.current_adv->addr.s_addr != mobile_array[cur_mobile].mn.fa_addr.s_addr) { 00601 DEBUG(DEBUG_INFO, "fa_addr=%s != ", 00602 inet_ntoa(mobile_array[cur_mobile].mn.fa_addr)); 00603 DEBUG(DEBUG_INFO, "current_adv->addr=%s\n", 00604 inet_ntoa(mobile_array[cur_mobile].mn.current_adv->addr)); 00605 } 00606 00607 DEBUG(DEBUG_INFO, "Setting in_use=%i for FA %s (send reg)\n", 00608 request_type == REG_DISC ? 0 : 1, 00609 inet_ntoa(mobile_array[cur_mobile].mn.current_adv->addr)); 00610 mobile_array[cur_mobile].mn.current_adv->in_use = request_type == REG_DISC ? 0 : 1; 00611 if (mobile_array[cur_mobile].config.tunneling_mode == TUNMODE_AUTO_REVERSE && 00612 (ntohs(mobile_array[cur_mobile].mn.current_adv->adv.ext->opts) & 00613 AGENT_ADV_BIDIR_TUNNELING) == 0) 00614 use_reverse = 0; 00615 if (mobile_array[cur_mobile].config.tunneling_mode == TUNMODE_AUTO_TRIANGLE && 00616 mobile_array[cur_mobile].mn.current_adv->adv.own_ext != NULL && 00617 (mobile_array[cur_mobile].mn.current_adv->adv.own_ext->opts & 00618 AGENT_ADV_OWN_TRIANGLE_TUNNELING) == 0) 00619 use_reverse = 1; 00620 } else { 00621 DEBUG(DEBUG_INFO, 00622 "send_registration: current_adv == NULL!?\n"); 00623 } 00624 00625 if ((use_reverse && mobile_array[cur_mobile].config.tunneling_mode == TUNMODE_TRIANGLE) || 00626 (!use_reverse && mobile_array[cur_mobile].config.tunneling_mode == TUNMODE_REVERSE)) { 00627 DEBUG(DEBUG_INFO, "FA does not support wanted tunneling mode -" 00628 " aborting registration\n"); 00629 if (mobile_array[cur_mobile].mn.current_adv != NULL) 00630 mobile_array[cur_mobile].mn.current_adv->reg_failed = 1; 00631 return -1; 00632 } 00633 00634 if (use_reverse) 00635 DEBUG(DEBUG_MESSAGES, "Requesting reverse tunneling\n"); 00636 00637 pos = sendbuf; 00638 00639 DEBUG(DEBUG_MESSAGES, "Sending registration message:\n * header\n"); 00640 n = fill_req_header(pos, request_type, use_reverse); 00641 if (n < 0) return -1; 00642 pos += n; 00643 00644 n = add_req_extensions(pos, MAXMSG - n, sendbuf, request_type, 00645 use_reverse); 00646 if (n < 0) { 00647 LOG2(LOG_ERR, "Registration request buffer overflow - unable" 00648 " to send the request\n"); 00649 return -1; 00650 } 00651 pos += n; 00652 00653 len = (int) (pos - sendbuf); 00654 assert(len <= MAXMSG); 00655 00656 /* call parse_msg() to parse the message in order to get the details 00657 * of the sent message into debug output; in addition, this validates 00658 * the format of the request */ 00659 if (parse_msg(sendbuf, len, &ext) != 0) { 00660 DEBUG(DEBUG_INFO, "WARNING! Own registration request was not " 00661 "valid!\n"); 00662 } 00663 00664 /* add ARP entry, if not already added */ 00665 if (mobile_array[cur_mobile].mn.current_adv != NULL && 00666 mobile_array[cur_mobile].mn.current_adv->adv_type == MN_ADV_TYPE_FA && 00667 !mobile_array[cur_mobile].mn.current_adv->arpentry) { 00668 struct sockaddr hwaddr; 00669 DEBUG(DEBUG_INFO, "Adding ARP entry for FA\n"); 00670 memset(&hwaddr, 0, sizeof(hwaddr)); 00671 hwaddr.sa_family = ARPHRD_ETHER; 00672 #ifdef DYN_TARGET_LINUX 00673 memcpy(hwaddr.sa_data, mobile_array[cur_mobile].mn.current_adv->adv.from.sll_addr, 00674 mobile_array[cur_mobile].mn.current_adv->adv.from.sll_halen); 00675 #else 00676 memcpy(hwaddr.sa_data, mobile_array[cur_mobile].mn.current_adv->adv.eth->h_source, 00677 ETH_ALEN); 00678 #endif 00679 if (arp_add_permanent_item(mobile_array[cur_mobile].mn.current_adv->addr, 00680 mobile_array[cur_mobile].mn.current_adv->ifname, 00681 &hwaddr) < 0) { 00682 LOG2(LOG_WARNING, "arp_add_permanent_item(%s, %s, %s) " 00683 "failed\n", inet_ntoa(mobile_array[cur_mobile].mn.current_adv->addr), 00684 mobile_array[cur_mobile].mn.current_adv->ifname, 00685 ether_hwtoa((unsigned char *)hwaddr.sa_data)); 00686 } 00687 mobile_array[cur_mobile].mn.current_adv->arpentry = 1; 00688 } 00689 00690 /* add host route to FA, if not already added */ 00691 if (mobile_array[cur_mobile].config.enable_fa_decapsulation && 00692 mobile_array[cur_mobile].mn.current_adv != NULL && 00693 mobile_array[cur_mobile].mn.current_adv->adv_type == MN_ADV_TYPE_FA && 00694 !mobile_array[cur_mobile].mn.current_adv->routeentry) { 00695 DEBUG(DEBUG_INFO, "Adding routing entry for FA\n"); 00696 add_fa_host_route(mobile_array[cur_mobile].mn.current_adv->ifname, mobile_array[cur_mobile].mn.agentadv, 00697 mobile_array[cur_mobile].mn.current_adv->ifindex, mobile_array[cur_mobile].mn.fa_addr); 00698 } 00699 00700 /* send the message */ 00701 memset(&addr, 0, sizeof(addr)); 00702 addr.sin_family = AF_INET; 00703 // addr.sin_addr.s_addr = mobile_array[cur_mobile].mn.fa_addr.s_addr; 00704 //addr.sin_addr.s_addr = inet_addr("172.16.0.2"); 00705 addr.sin_addr.s_addr=mobile_array[cur_mobile].config.ha_ip_addr.s_addr; 00706 addr.sin_port = htons(mobile_array[cur_mobile].config.udp_port); 00707 DEBUG(DEBUG_MESSAGES, "sending registration request to %s:%i, " 00708 "type=%i\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port), 00709 request_type); 00710 00711 gettimeofday(&mobile_array[cur_mobile].mn.last_reg_send_time, NULL); 00712 DEBUG(DEBUG_TIMERS, "last_reg_send_time=%li.%06li (FA=%s)\n", 00713 mobile_array[cur_mobile].mn.last_reg_send_time.tv_sec, 00714 mobile_array[cur_mobile].mn.last_reg_send_time.tv_usec, 00715 inet_ntoa(addr.sin_addr)); 00716 00717 00718 00719 00720 n = sendto(mobile_array[cur_mobile].mn.registration_socket, sendbuf, len, 0, 00721 (struct sockaddr *) &addr, sizeof(addr)); 00722 if (n == len) { 00723 /* store id for reply */ 00724 mobile_array[cur_mobile].mn.registration_id[0] = 00725 ntohl(((struct reg_req *)sendbuf)->id[0]); 00726 mobile_array[cur_mobile].mn.registration_id[1] = 00727 ntohl(((struct reg_req *)sendbuf)->id[1]); 00728 /* set registration time */ 00729 gettimeofday(&timers[TIMER_REQUEST], NULL); 00730 mobile_array[cur_mobile].mn.last_request_sent = timers[TIMER_REQUEST].tv_sec; 00731 return 0; 00732 } else { 00733 LOG2(LOG_ERR, "send_reg - sendto: %s\n", strerror(errno)); 00734 return -1; 00735 } 00736 }
Here is the call graph for this function:
int cur_mobile = 0 |
Definition at line 81 of file mn_reg.c.
Referenced by create_mobile(), parse_rows(), and send_messages().
struct mobile mobile_array[20] |
Definition at line 101 of file mn_reg.c.
Referenced by create_mobile(), handle_registration(), send_messages(), and send_registration().
int mobiles = 0 |
int rownumber = 0 |
int sent_deregs |
int sent_regs |
char timestr[60] |
time_t tm |