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

📄 quagga.c

📁 wifi 无线网络路由协议OLSR linux下C代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*************************************************************************** projekt              : olsrd-quagga file                 : quagga.c   usage                : communication with the zebra-daemon  copyright            : (C) 2006 by Immo 'FaUl' Wehrenberg e-mail               : immo@chaostreff-dortmund.de ***************************************************************************//*************************************************************************** *                                                                         * *   This program is free software; you can redistribute it and/or modify  * *   it under the terms of the GNU General Public License version 2 as     * *   published by the Free Software Foundation.                            * *                                                                         * ***************************************************************************/#ifdef MY_DEBUG#include <stdio.h>#endif#define HAVE_SOCKLEN_T#include <stdint.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <quagga/zebra.h>#include "quagga.h"#include "olsr.h"#include "log.h"#include "defs.h"#include "local_hna_set.h"#include "routing_table.h"#ifdef USE_UNIX_DOMAIN_SOCKET#include <sys/un.h>#define ZEBRA_SOCKET "/var/run/quagga/zserv.api"#endif#define ZAPI_MESSAGE_NEXTHOP  0x01#define ZAPI_MESSAGE_IFINDEX  0x02#define ZAPI_MESSAGE_DISTANCE 0x04#define ZAPI_MESSAGE_METRIC   0x08#define BUFSIZE 1024#define STATUS_CONNECTED 1#define OPTION_EXPORT 1static struct {  char status; // internal status  char options; // internal options  int sock; // Socket to zebra...  char redistribute[ZEBRA_ROUTE_MAX];  char distance;  char flags;  struct ipv4_route *v4_rt; // routes currently exportet to zebra} zebra;/* prototypes intern */static unsigned char *try_read (ssize_t *);static unsigned char* zebra_route_packet (struct ipv4_route r, ssize_t *);static int parse_interface_add (unsigned char *, size_t);static int parse_interface_delete (unsigned char *, size_t);static int parse_interface_up (unsigned char *, size_t);static int parse_interface_down (unsigned char *, size_t);static int parse_interface_address_add (unsigned char *, size_t);static int parse_interface_address_delete (unsigned char *, size_t);static int parse_ipv4_route (unsigned char *, size_t, struct ipv4_route *);static int ipv4_route_add (unsigned char *, size_t);static int ipv4_route_delete (unsigned char *, size_t);static int parse_ipv6_route_add (unsigned char*, size_t);static void zebra_reconnect (void);static void zebra_connect (void);static uint32_t prefixlentomask (uint8_t);static void free_ipv4_route (struct ipv4_route);/* static void update_olsr_zebra_routes (struct ipv4_route*, struct ipv4_route*);static struct ipv4_route *zebra_create_ipv4_route_table_entry (uint32_t,							       uint32_t,							       uint32_t);static struct ipv4_route *zebra_create_ipv4_route_table (void);static void zebra_free_ipv4_route_table (struct ipv4_route*);*//*static uint8_t masktoprefixlen (uint32_t);*/#ifdef MY_DEBUGstatic void dump_ipv4_route (struct ipv4_route r, char *c) {  int i = 0, x = 0;  puts (c);  printf("type: %d\n", r.type);  puts("flags:");  printf("  Internal: %s\n",r.flags&ZEBRA_FLAG_INTERNAL?"yes":"no");  printf("  Selfroute %s\n",r.flags&ZEBRA_FLAG_SELFROUTE?"yes":"no");  printf("  Blackhole %s\n",r.flags&ZEBRA_FLAG_BLACKHOLE?"yes":"no");  printf("  IBGP: %s\n",r.flags&ZEBRA_FLAG_IBGP?"yes":"no");  printf("  Selected: %s\n",r.flags&ZEBRA_FLAG_SELECTED?"yes":"no");  printf("  Changed: %s\n",r.flags&ZEBRA_FLAG_CHANGED?"yes":"no");  printf("  static: %s\n",r.flags&ZEBRA_FLAG_STATIC?"yes":"no");  printf("  reject: %s\n",r.flags&ZEBRA_FLAG_REJECT?"yes":"no");  puts("message:");  printf("  nexthop: %s\n",r.message&ZAPI_MESSAGE_NEXTHOP?"yes":"no");  printf("  ifindex: %s\n",r.message&ZAPI_MESSAGE_IFINDEX?"yes":"no");  printf("  distance: %s\n",r.message&ZAPI_MESSAGE_DISTANCE?"yes":"no");  printf("  metric: %s\n",r.message&ZAPI_MESSAGE_METRIC?"yes":"no");  printf("Prefixlen: %d\n", r.prefixlen);  printf("Prefix: %d", (unsigned char)r.prefix);  c = (char*) &r.prefix;  while (++i < (r.prefixlen/8 + (r.prefixlen % 8 ? 1 : 0)))    printf(".%d",(unsigned char)*(c + i));  while (i++ < 4)    printf(".0");  puts("");  i=0;  if (r.message&ZAPI_MESSAGE_NEXTHOP) {    printf("nexthop-count: %d\n", r.nh_count);    while (i++ < r.nh_count) {      if (r.nexthops[i].type == ZEBRA_NEXTHOP_IPV4) {	c = (unsigned char*) &r.nexthops[i].payload.v4;	printf ("Nexthop %d: %d", i, (unsigned char) *c);	while (++x < 4) {	  printf (".%d", (unsigned char) c[x]);	}	puts("");      }    }    i=0;  }  if (r.message&ZAPI_MESSAGE_IFINDEX) {        printf("index-number: %d\n", r.ind_num);    while (i++ < r.ind_num)      printf("Index: %d: %d\n", i, r.index[i]);    i=0;    if (r.message&ZAPI_MESSAGE_DISTANCE)      printf("Distance: %d\n",r.distance);    if (r.message&ZAPI_MESSAGE_METRIC)      printf("Metric: %d\n",r.metric);    puts("\n");  }}#endifvoid *my_realloc (void *buf, size_t s, const char *c) {  buf = realloc (buf, s);  if (!buf) {    OLSR_PRINTF (1, "(QUAGGA) OUT OF MEMORY: %s\n", strerror(errno));    olsr_syslog(OLSR_LOG_ERR, "olsrd: out of memory!: %m\n");    olsr_exit(c, EXIT_FAILURE);  }  return buf;}void init_zebra (void) {  zebra_connect();  if (!zebra.status&STATUS_CONNECTED)    olsr_exit ("(QUAGGA) AIIIII, could not connect to zebra! is zebra running?", 	       EXIT_FAILURE);}void zebra_cleanup (void) {  int i;  struct rt_entry *tmp;    if (zebra.options & OPTION_EXPORT) {    OLSR_FOR_ALL_RT_ENTRIES(tmp) {      zebra_del_olsr_v4_route(tmp);    } OLSR_FOR_ALL_RT_ENTRIES_END(tmp);  }  for (i = 0; i < ZEBRA_ROUTE_MAX; i++)    if (zebra.redistribute[i]) zebra_disable_redistribute(i + 1);}static void zebra_reconnect (void) {  struct rt_entry *tmp;  int i;  zebra_connect();  if (!zebra.status & STATUS_CONNECTED) return; // try again next time  if (zebra.options & OPTION_EXPORT) {    OLSR_FOR_ALL_RT_ENTRIES(tmp) {      zebra_add_olsr_v4_route (tmp);    } OLSR_FOR_ALL_RT_ENTRIES_END(tmp);  }    for (i = 0; i < ZEBRA_ROUTE_MAX; i++)    if (zebra.redistribute[i]) zebra_redistribute(i + 1);  /* Zebra sends us all routes of type it knows after      zebra_redistribute(type) */}/* Connect to the zebra-daemon, returns a socket */static void zebra_connect (void) {    int ret;#ifndef USE_UNIX_DOMAIN_SOCKET  struct sockaddr_in i;  if (close (zebra.sock) < 0) olsr_exit ("(QUAGGA) Could not close socket!", EXIT_FAILURE);    zebra.sock = socket (AF_INET,SOCK_STREAM, 0);#else  struct sockaddr_un i;  if (close (zebra.sock) < 0) olsr_exit ("(QUAGGA) Could not close socket!", EXIT_FAILURE);  zebra.sock = socket (AF_UNIX,SOCK_STREAM, 0);#endif  if (zebra.sock <0 )    olsr_exit("(QUAGGA) Could not create socket!", EXIT_FAILURE);    memset (&i, 0, sizeof i);#ifndef USE_UNIX_DOMAIN_SOCKET  i.sin_family = AF_INET;  i.sin_port = htons (ZEBRA_PORT);  i.sin_addr.s_addr = htonl (INADDR_LOOPBACK);#else  i.sun_family = AF_UNIX;  strcpy (i.sun_path, ZEBRA_SOCKET);#endif  ret = connect (zebra.sock, (struct sockaddr *)&i, sizeof i);  if  (ret < 0) zebra.status &= ~STATUS_CONNECTED;  else zebra.status |= STATUS_CONNECTED;}    /* Sends a command to zebra, command is    the command defined in zebra.h, options is the packet-payload,    optlen the length, of the payload */unsigned char zebra_send_command (unsigned char command,                                   unsigned char *options, int optlen) {#ifdef ZEBRA_HEADER_MARKER  char *p = olsr_malloc (optlen + 6, "zebra_send_command");  uint16_t length = optlen + 6; /* length of option + command + packet_length +				   marker + zserv-version */  uint16_t cmd;#else  char *p = olsr_malloc (optlen + 3, "zebra_send_command");  uint16_t length = optlen + 3;  // length of option + command + packet_length#endif  char *pnt = p;  int ret;    uint16_t len = htons(length);  memcpy (p, &len, 2);#ifdef ZEBRA_HEADER_MARKER  p[2] = ZEBRA_HEADER_MARKER;  p[3] = ZSERV_VERSION;  cmd = htons (command);  memcpy (p + 4, &cmd, 2);  memcpy (p + 6, options, optlen);#else  p[2] = command;  memcpy (p + 3, options, optlen);#endif  errno = 0;  do {    ret = write (zebra.sock, p, length);    if (ret < 0) {      if (errno == EINTR) {	errno = 0;	continue;      }      else {	olsr_printf (1, "(QUAGGA) Disconnected from zebra\n");	zebra.status &= ~STATUS_CONNECTED;	free (pnt);	return -1;      }    }    p = p+ret;  } while ((length -= ret));  free (pnt);  return 0;}/* Creates a Route-Packet-Payload, needs address, netmask, nexthop,    distance, and a pointer of an size_t */static unsigned char* zebra_route_packet (struct ipv4_route r,                                           ssize_t *optlen) {  int count;  unsigned char *cmdopt, *t;  *optlen = 4; // first: type, flags, message, prefixlen  *optlen += r.prefixlen / 8 + (r.prefixlen % 8 ? 1 : 0); // + prefix  if (r.message & ZAPI_MESSAGE_NEXTHOP) {    if (r.nexthops->type == ZEBRA_NEXTHOP_IPV4 	|| r.nexthops->type == ZEBRA_NEXTHOP_IPV4_IFINDEX){      *optlen += (sizeof r.nexthops->payload.v4 		  + sizeof r.nexthops->type) * r.nh_count + 1;    }    else if (r.nexthops->type == 0)       *optlen += 5;  }  if (r.message & ZAPI_MESSAGE_IFINDEX)    *optlen += r.ind_num * sizeof *r.index + 1;  if (r.message & ZAPI_MESSAGE_DISTANCE)    (*optlen)++;  if (r.message & ZAPI_MESSAGE_METRIC)    *optlen += sizeof r.metric;  cmdopt = olsr_malloc (*optlen, "zebra add_v4_route");  t = cmdopt;  *t++ = r.type;   *t++ = r.flags;   *t++ = r.message;  *t++ = r.prefixlen;  for (count = 0; count < r.prefixlen/8 + (r.prefixlen % 8 ? 1 : 0); count++) {    *t++ = *((char*)&r.prefix + count); /* this is so sick!! */  }  if (r.message & ZAPI_MESSAGE_NEXTHOP) {    *t++ = r.nh_count;    *t++ = r.nexthops->type;    if (r.nexthops->type == ZEBRA_NEXTHOP_IPV4 || 	r.nexthops->type == ZEBRA_NEXTHOP_IPV4_IFINDEX) {      for (count = 0; count != r.nh_count; count++) {	memcpy (t, &r.nexthops[count].payload.v4, 		sizeof r.nexthops->payload.v4);	t += sizeof r.nexthops->payload.v4;      }    }    else if (r.nexthops->type == 0) {      *t++ = 0;      *t++ = 0;      *t++ = 0;    }  }  if (r.message & ZAPI_MESSAGE_IFINDEX) {    *t++ = r.ind_num;    memcpy (t, r.index, sizeof *r.index * r.ind_num);    t += sizeof r.index * r.ind_num;  }  if (r.message & ZAPI_MESSAGE_DISTANCE)    *t++ = r.distance;  if (r.message & ZAPI_MESSAGE_METRIC) {    memcpy (t, &r.metric, sizeof r.metric);    t += sizeof r.metric;  }  return cmdopt;}/* adds a route to zebra-daemon */int zebra_add_v4_route (struct ipv4_route r) {    unsigned char *cmdopt;  ssize_t optlen;  int retval;  cmdopt = zebra_route_packet (r, &optlen);  retval = zebra_send_command (ZEBRA_IPV4_ROUTE_ADD, cmdopt, optlen);  free (cmdopt);  return retval;  }/* deletes a route from the zebra-daemon */int zebra_delete_v4_route (struct ipv4_route r) {    unsigned char *cmdopt;  ssize_t optlen;  int retval;  cmdopt = zebra_route_packet (r, &optlen);    retval = zebra_send_command (ZEBRA_IPV4_ROUTE_DELETE, cmdopt, optlen);  free (cmdopt);  return retval;  }/* Check wether there is data from zebra aviable */void zebra_check (void* foo __attribute__((unused))) {  unsigned char *data, *f;  ssize_t len, ret;  if (!(zebra.status & STATUS_CONNECTED)) {    zebra_reconnect();    return;  }  data = try_read (&len);  if (data) {    f = data;    do {      ret = zebra_parse_packet (f, len);      if (!ret) // something wired happened	olsr_exit ("(QUAGGA) Zero message length??? ", EXIT_FAILURE);      f += ret;    } while ((f - data) < len);    free (data);  }}// tries to read a packet from zebra_socket// if there is something to read - make sure to read whole packagesstatic unsigned char *try_read (ssize_t *len) {

⌨️ 快捷键说明

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