mn_reg.c File Reference

#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
tmtmptr
time_t tm
char timestr [60]
mobile mobile_array [20]
int cur_mobile = 0
int mobiles = 0


Typedef Documentation

typedef struct device DEVICE

Definition at line 56 of file mn_reg.c.

typedef struct rowdata ROWDATA

Definition at line 57 of file mn_reg.c.


Function Documentation

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.

References devices, and rows.

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:


Variable Documentation

struct mn_config config

Definition at line 45 of file mn.c.

int cur_mobile = 0

Definition at line 102 of file mn_reg.c.

DEVICE devices[5000]

Definition at line 81 of file mn_reg.c.

Referenced by create_mobile(), parse_rows(), and send_messages().

int intervals[5000]

Definition at line 52 of file mn_reg.c.

struct mn_data mn

Definition at line 44 of file mn.c.

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

Definition at line 103 of file mn_reg.c.

Referenced by create_mobile(), and send_messages().

int rownumber = 0

Definition at line 55 of file mn_reg.c.

Referenced by create_mobile(), main(), and readfile().

ROWDATA rows[5000]

Definition at line 82 of file mn_reg.c.

Referenced by parse_rows(), and readfile().

int sent_deregs

Definition at line 85 of file mn_reg.c.

Referenced by main(), and send_messages().

int sent_regs

Definition at line 84 of file mn_reg.c.

Referenced by main(), and send_messages().

struct timeval timers[TIMER_COUNT]

Definition at line 47 of file mn.c.

char timestr[60]

Definition at line 89 of file mn_reg.c.

Referenced by send_messages().

time_t tm

Definition at line 88 of file mn_reg.c.

Referenced by send_messages().

struct tm* tmptr

Definition at line 87 of file mn_reg.c.

Referenced by send_messages().


Generated on Tue Jan 15 08:50:52 2008 for Virtual foreign agent generator version 0.1 by  doxygen 1.5.1