⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 olsrd_dyn_gw.c

📁 wifi 无线网络路由协议OLSR linux下C代码
💻 C
字号:
/* * The olsr.org Optimized Link-State Routing daemon(olsrd) * Copyright (c) 2004, Andreas T鴑nesen(andreto@olsr.org) * All rights reserved. * * Redistribution and use in source and binary forms, with or without  * modification, are permitted provided that the following conditions  * are met: * * * Redistributions of source code must retain the above copyright  *   notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright  *   notice, this list of conditions and the following disclaimer in  *   the documentation and/or other materials provided with the  *   distribution. * * Neither the name of olsr.org, olsrd nor the names of its  *   contributors may be used to endorse or promote products derived  *   from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE  * POSSIBILITY OF SUCH DAMAGE. * * Visit http://www.olsr.org for more information. * * If you find this software useful feel free to make a donation * to the project. For more information see the website or contact * the copyright holders. * * $Id: olsrd_dyn_gw.c,v 1.23 2007/09/17 21:57:05 bernd67 Exp $ *//* * -Threaded ping code added by Jens Nachitgall * -HNA4 checking by bjoern riemer */#include <arpa/inet.h>#include "olsr_types.h"#include "olsrd_dyn_gw.h"#include "scheduler.h"#include "olsr.h"#include "local_hna_set.h"#include "defs.h"#include <stdio.h>#include <string.h>#include <stdlib.h>#include <sys/time.h>#include <net/route.h>#ifdef linux#include <linux/in_route.h>#endif#include <unistd.h>#include <errno.h>#include <time.h>#ifndef WIN32#include <pthread.h>#else#define WIN32_LEAN_AND_MEAN#include <windows.h>#undef interface#define close(x) closesocket(x)typedef HANDLE pthread_mutex_t;typedef HANDLE pthread_t;int pthread_create(HANDLE *Hand, void *Attr, void *(*Func)(void *), void *Arg);int pthread_kill(HANDLE Hand, int Sig);int pthread_mutex_init(HANDLE *Hand, void *Attr);int pthread_mutex_lock(HANDLE *Hand);int pthread_mutex_unlock(HANDLE *Hand);struct ThreadPara{  void *(*Func)(void *);  void *Arg;};#endif/* set default interval, in case none is given in the config file */static int check_interval = 5;/* list to store the Ping IP addresses given in the config file */struct ping_list {  char *ping_address;  struct ping_list *next;};static struct ping_list *add_to_ping_list(const char *, struct ping_list *);struct hna_list {  union olsr_ip_addr hna_net;  union olsr_ip_addr hna_netmask;  struct ping_list *ping_hosts;  int hna_added;  int probe_ok;  struct hna_list *next;};static struct hna_list *	add_to_hna_list(struct hna_list *,				union olsr_ip_addr *hna_net,				union olsr_ip_addr *hna_netmask );struct hna_list *the_hna_list = NULL;static voidlooped_checks(void *) __attribute__((noreturn));static intcheck_gw(union olsr_ip_addr *, union olsr_ip_addr *,struct ping_list *);static intping_is_possible(struct ping_list *);/* Event function to register with the scheduler */static voidolsr_event_doing_hna(void *);/** * read config file parameters */static int set_plugin_double(const char *value, void *data, set_plugin_parameter_addon addon __attribute__((unused))){    char *endptr;    const double d = strtod(value, &endptr);    if (*endptr != '\0' || endptr == value) {        OLSR_PRINTF(0, "Illegal double \"%s\"", value);        return 1;    }    if (data != NULL) {        double *v = data;        *v = d;        OLSR_PRINTF(1, "%s double %lf\n", "Got", d);    } else {        OLSR_PRINTF(0, "%s double %lf\n", "Ignored", d);    }    return 0;}static int set_plugin_ping(const char *value, void *data __attribute__((unused)), set_plugin_parameter_addon addon __attribute__((unused))){    union olsr_ip_addr foo_addr;    if (inet_pton(olsr_cnf->ip_version, value, &foo_addr) <= 0) {        OLSR_PRINTF(0, "Illegal IP address \"%s\"", value);        return 1;    }    /*if first ping without hna then assume inet gateway*/    if (the_hna_list == NULL){        union olsr_ip_addr temp_net;        union olsr_ip_addr temp_netmask;        temp_net.v4 = INET_NET;        temp_netmask.v4 = INET_PREFIX;        the_hna_list = add_to_hna_list(the_hna_list, &temp_net, &temp_netmask);        if (the_hna_list == NULL) {            return 1;        }    }    the_hna_list->ping_hosts = add_to_ping_list(value, the_hna_list->ping_hosts);    return 0;}static int set_plugin_hna(const char *value, void *data __attribute__((unused)), set_plugin_parameter_addon addon __attribute__((unused))){    union olsr_ip_addr temp_net;    union olsr_ip_addr temp_netmask;    char s_netaddr[128];    char s_mask[128];    //192.168.1.0  255.255.255.0    int i = sscanf(value,"%128s %128s", s_netaddr, s_mask);    if (i != 2) {        OLSR_PRINTF(0, "Cannot get IP address and netmask from \"%s\"", value);        return 1;    }    //printf("%s():i:%i; net:%s; mask:%s\n",__func__,i,s_netaddr,s_mask);    if (inet_pton(olsr_cnf->ip_version, s_netaddr, &temp_net) <= 0) {        OLSR_PRINTF(0, "Illegal IP address \"%s\"", s_netaddr);        return 1;    }    //printf("GOT: %s(%08x)",inet_ntoa(foo_addr),foo_addr.s_addr);    if (inet_pton(olsr_cnf->ip_version, s_netaddr, &temp_netmask) <= 0) {        OLSR_PRINTF(0, "Illegal netmask \"%s\"", s_netaddr);        return 1;    }    //printf("/%s(%08x)\n",inet_ntoa(foo_addr),foo_addr.s_addr);    //printf("%s():got->%s/%s\n",__func__,olsr_ip_to_string((union olsr_ip_addr *)&));    the_hna_list = add_to_hna_list(the_hna_list, &temp_net, &temp_netmask);    if (the_hna_list != NULL) {        return 1;    }    return 0;}static const struct olsrd_plugin_parameters plugin_parameters[] = {    { .name = "interval", .set_plugin_parameter = &set_plugin_double, .data = &check_interval },    { .name = "ping",     .set_plugin_parameter = &set_plugin_ping,   .data = NULL },    { .name = "hna",      .set_plugin_parameter = &set_plugin_hna,    .data = NULL },};void olsrd_get_plugin_parameters(const struct olsrd_plugin_parameters **params, int *size){    *params = plugin_parameters;    *size = sizeof(plugin_parameters)/sizeof(*plugin_parameters);}/** *Do initialization here *  * *This function is called by the my_init *function in uolsrd_plugin.c *It is ran _after_ register_olsr_param */intolsrd_plugin_init(void){  pthread_t ping_thread;    //gw_net.v4 = INET_NET;  //gw_netmask.v4 = INET_PREFIX;  //gw_already_added = 0;  //has_available_gw = 0;    /* Remove all local Inet HNA entries */  /*while(remove_local_hna4_entry(&gw_net, &gw_netmask))  {    olsr_printf(1, "HNA Internet gateway deleted\n");  }*/  pthread_create(&ping_thread, NULL, (void *(*)(void *))looped_checks, NULL);    /* Register the GW check */  olsr_register_scheduler_event(&olsr_event_doing_hna, NULL, 3, 4, NULL);  return 1;}/** * Scheduled event to update the hna table, * called from olsrd main thread to keep the hna table thread-safe */static voidolsr_event_doing_hna(void *foo __attribute__((unused))){	struct hna_list *li;	/*  if (has_available_gw == 1 && gw_already_added == 0) {    olsr_printf(1, "Adding OLSR local HNA entry for Internet\n");    add_local_hna4_entry(&gw_net, &gw_netmask);    gw_already_added = 1;  } else if ((has_available_gw == 0) && (gw_already_added == 1)) {    // Remove all local Inet HNA entries /    while(remove_local_hna4_entry(&gw_net, &gw_netmask)) {      olsr_printf(1, "Removing OLSR local HNA entry for Internet\n");    }    gw_already_added = 0;  }	*/	for(li=the_hna_list; li; li=li->next){		if((li->probe_ok==1)&&(li->hna_added==0)){			olsr_printf(1, "Adding OLSR local HNA entry\n");			add_local_hna4_entry(&li->hna_net, &li->hna_netmask);			li->hna_added=1;		}else if((li->probe_ok==0)&&(li->hna_added==1)){			while(remove_local_hna4_entry(&li->hna_net, &li->hna_netmask)) {				olsr_printf(1, "Removing OLSR local HNA entry\n");			}			li->hna_added=0;		}	}}/** * the threaded function which happens within an endless loop, * reiterated every "Interval" sec (as given in the config or  * the default value) */static voidlooped_checks(void *foo __attribute__((unused))){  for(;;) {    struct hna_list *li;    struct timespec remainder_spec;    /* the time to wait in "Interval" sec (see connfig), default=5sec */    struct timespec sleeptime_spec  = { check_interval, 0L };    for(li = the_hna_list; li; li = li->next){      /* check for gw in table entry and if Ping IPs are given also do pings */      li->probe_ok = check_gw(&li->hna_net,&li->hna_netmask,li->ping_hosts);      //has_available_gw = check_gw(&gw_net, &gw_netmask);    }    while(nanosleep(&sleeptime_spec, &remainder_spec) < 0)      sleeptime_spec = remainder_spec;  }  // return NULL;}static intcheck_gw(union olsr_ip_addr *net, union olsr_ip_addr *mask, struct ping_list *the_ping_list){    char buf[1024], iface[16];    olsr_u32_t gate_addr, dest_addr, netmask;    unsigned int iflags;    int metric, refcnt, use;    int retval = 0;    FILE *fp = fopen(PROCENTRY_ROUTE, "r");    if (!fp)       {        perror(PROCENTRY_ROUTE);        olsr_printf(1, "INET (IPv4) not configured in this system.\n");	return -1;      }        /*    olsr_printf(1, "Genmask         Destination     Gateway         "                "Flags Metric Ref    Use Iface\n");    */    while (fgets(buf, sizeof(buf), fp))      {		int num = sscanf(buf, "%15s %128X %128X %X %d %d %d %128X \n",                         iface, &dest_addr, &gate_addr,                         &iflags, &refcnt, &use, &metric, &netmask);	if (num < 8)	    continue;	/*	olsr_printf(1, "%-15s ", olsr_ip_to_string((union olsr_ip_addr *)&netmask));	olsr_printf(1, "%-15s ", olsr_ip_to_string((union olsr_ip_addr *)&dest_addr));	olsr_printf(1, "%-15s %-6d %-2d %7d %s\n",		    olsr_ip_to_string((union olsr_ip_addr *)&gate_addr),		    metric, refcnt, use, iface);	*/        if( (iflags & RTF_UP) &&            (metric == 0) &&            (netmask == mask->v4) &&             (dest_addr == net->v4))          {            if ( ((mask->v4==INET_PREFIX)&&(net->v4==INET_NET))&&(!(iflags & RTF_GATEWAY)))              {                fclose(fp);                  return retval;              }            /* don't ping, if there was no "Ping" IP addr in the config file */            if (the_ping_list != NULL) {                /*validate the found inet gw by pinging*/               if (ping_is_possible(the_ping_list)) {                olsr_printf(1, "HNA[%08x/%08x](ping is possible) VIA %s detected in routing table.\n", dest_addr,netmask,iface);                retval=1;                    }            } else {              olsr_printf(1, "HNA[%08x/%08x] VIA %s detected in routing table.\n", dest_addr,netmask,iface);              retval=1;                  }          }      }    fclose(fp);          if(retval == 0){      olsr_printf(1, "HNA[%08x/%08x] is invalid\n", net->v4,mask->v4);    }      return retval;}static intping_is_possible(struct ping_list *the_ping_list) {  struct ping_list *list;  for(list = the_ping_list; list; list = list->next) {    char ping_command[50];    snprintf(ping_command, sizeof(ping_command), "ping -c 1 -q %s", list->ping_address);    olsr_printf(1, "\nDo ping on %s ...\n", list->ping_address);    if (system(ping_command) == 0) {      olsr_printf(1, "...OK\n\n");      return 1;          }    olsr_printf(1, "...FAILED\n\n");  }  return 0;}/* add the valid IPs to the head of the list */static struct ping_list *add_to_ping_list(const char *ping_address, struct ping_list *the_ping_list){  struct ping_list *new = malloc(sizeof(struct ping_list));  if(!new)  {    fprintf(stderr, "DYN GW: Out of memory!\n");    exit(0);  }  new->ping_address = strdup(ping_address);  new->next = the_ping_list;  return new;}    static struct hna_list *add_to_hna_list(struct hna_list * list_root, union olsr_ip_addr *hna_net, union olsr_ip_addr *hna_netmask ){  struct hna_list *new = malloc(sizeof(struct hna_list));  if(new == NULL)  {    fprintf(stderr, "DYN GW: Out of memory!\n");    exit(0);  }  //memcpy(&new->hna_net,hna_net,sizeof(union hna_net));  //memcpy(&new->hna_netmask,hna_netmask,sizeof(union hna_netmask));  new->hna_net.v4=hna_net->v4;  new->hna_netmask.v4=hna_netmask->v4;  new->hna_added=0;  new->probe_ok=0;  new->ping_hosts=NULL;  new->next=list_root;    return new;}#ifdef WIN32/* * Windows ptread compat stuff */static unsigned long __stdcall ThreadWrapper(void *Para){  struct ThreadPara *Cast;  void *(*Func)(void *);  void *Arg;  Cast = (struct ThreadPara *)Para;  Func = Cast->Func;  Arg = Cast->Arg;    HeapFree(GetProcessHeap(), 0, Para);  Func(Arg);  return 0;}int pthread_create(HANDLE *Hand, void *Attr __attribute__((unused)), void *(*Func)(void *), void *Arg){  struct ThreadPara *Para;  unsigned long ThreadId;  Para = HeapAlloc(GetProcessHeap(), 0, sizeof (struct ThreadPara));  if (Para == NULL)    return -1;  Para->Func = Func;  Para->Arg = Arg;  *Hand = CreateThread(NULL, 0, ThreadWrapper, Para, 0, &ThreadId);  if (*Hand == NULL)    return -1;  return 0;}int pthread_kill(HANDLE Hand, int Sig __attribute__((unused))){  if (!TerminateThread(Hand, 0))    return -1;  return 0;}int pthread_mutex_init(HANDLE *Hand, void *Attr __attribute__((unused))){  *Hand = CreateMutex(NULL, FALSE, NULL);  if (*Hand == NULL)    return -1;  return 0;}int pthread_mutex_lock(HANDLE *Hand){  if (WaitForSingleObject(*Hand, INFINITE) == WAIT_FAILED)    return -1;  return 0;}int pthread_mutex_unlock(HANDLE *Hand){  if (!ReleaseMutex(*Hand))    return -1;  return 0;}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -