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

📄 quagga.try1.c

📁 wifi 无线网络路由协议OLSR linux下C代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*  *  (C) 2006 by Immo 'FaUl' Wehrenberg <immo@chaostreff-dortmund.de> *   *  This code is covered by the GPLv2 *    */#include <stdint.h>#ifdef MY_DEBUG#include <stdio.h>#endif#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#define HAVE_SOCKLEN_T#include <quagga/zebra.h>#include "quagga.h"#ifdef OLSR_PLUGIN#include "olsr.h"#include "log.h"#include "defs.h"#include "local_hna_set.h"#endif#define ZAPI_MESSAGE_NEXTHOP  0x01#define ZAPI_MESSAGE_IFINDEX  0x02#define ZAPI_MESSAGE_DISTANCE 0x04#define ZAPI_MESSAGE_METRIC   0x08#define STATUS_CONNECTED 1#define BUFSIZE 1024static char status = 0;static int zsock; // Socket to zebra...struct ipv4_route *quagga_routes = 0; // routes currently exportet to zebra/* prototypes ntern */static char *try_read (ssize_t *);static char* zebra_route_packet (struct ipv4_route r, ssize_t *);static int parse_interface_add (char *, size_t);static int parse_interface_delete (char *, size_t);static int parse_interface_up (char *, size_t);static int parse_interface_down (char *, size_t);static int parse_interface_address_add (char *, size_t);static int parse_interface_address_delete (char *, size_t);static int parse_ipv4_route (char *, size_t, struct ipv4_route *);static int ipv4_route_add (char *, size_t);static int ipv4_route_delete (char *, size_t);static int parse_ipv6_route_add (char*, size_t);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) {      c = (unsigned char*) &r.nexthops[i];      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) {#ifdef OLSR_PLUGIN    OLSR_PRINTF (1, "OUT OF MEMORY: %s\n", strerror(errno));    olsr_syslog(OLSR_LOG_ERR, "olsrd: out of memory!: %m\n");    olsr_exit(c, EXIT_FAILURE);#else    exit (EXIT_FAILURE);#endif  }  return buf;}#ifndef OLSR_PLUGIN void *olsr_malloc (size_t f, const char *c) {  void* v = malloc (f);  return v;}#endif/* Connect to the zebra-daemon, returns a socket */int init_zebra () {  struct sockaddr_in i;  int ret;  zsock = socket (AF_INET,SOCK_STREAM, 0);  if (zsock <0 ) // TODO: Could not create socket    return -1;  memset (&i, 0, sizeof i);  i.sin_family = AF_INET;  i.sin_port = htons (ZEBRA_PORT);  //  i.sin_len = sizeof i;  i.sin_addr.s_addr = htonl (INADDR_LOOPBACK);    ret = connect (zsock, (struct sockaddr *)&i, sizeof i);  if  (ret < 0) {    close (zsock);    return -1;  }  status |= STATUS_CONNECTED;  return zsock;}    /* Sends a command to zebra, command is    the command defined in zebra.h, options is the packet-payload,    optlen the length, of the payload */char zebra_send_command (unsigned char command, char * options, int optlen) {  char *p = olsr_malloc (optlen+3, "zebra send_command");  uint16_t length = optlen + 3;  // length of option + command + packet_length    int ret;    uint16_t len = htons(length);  memcpy (p, &len, 2);  p[2] = command;  memcpy (p + 3, options, optlen);    do {    ret = write (zsock, p, length);    if (ret < 0) {      if (errno == EINTR) continue;    }    else return -1;    p = p+ret;  } while ((length =- ret));  return 0;}/* Creates a Route-Packet-Payload, needs address, netmask, nexthop,    distance, and a pointer of an size_t */static char* zebra_route_packet (struct ipv4_route r, ssize_t *optlen) {  char *cmdopt, *t;  *optlen = 9; // first: type, flags, message, prefixlen, nexthop number, nexthop)  *optlen += r.prefixlen / 8 + (r.prefixlen % 8 ? 1 : 0);    cmdopt = olsr_malloc (*optlen, "zebra add_v4_route");  t = cmdopt;  *t++ = 10; // Type: olsr  *t++ = r.flags; // flags  *t++ = r.message; // message: contains nexthop  *t++ = r.prefixlen;  memcpy (t, &r.prefix, r.prefixlen/8 + (r.prefixlen % 8 ? 1 : 0));  *t += r.prefixlen/8 + (r.prefixlen % 8 ? 1 : 0);  *t++ = r.nh_count;  memcpy (t, r.nexthops, r.nh_count * sizeof *r.nexthops);  return cmdopt;}/* adds a route to zebra-daemon (needs socket from zebra,   address = prefix of the route   mask = netmask of the route   nexthop = nexthop of the route   distance = distance-value of the route*/int zebra_add_v4_route (struct ipv4_route r) {    char *cmdopt;  ssize_t optlen;  cmdopt = zebra_route_packet (r, &optlen);  puts ("DEBUG: zebra_route_packet returned");      return zebra_send_command (ZEBRA_IPV4_ROUTE_ADD, cmdopt, optlen);}/* deletes a route from the zebra-daemon (   needs socket from zebra,   address = prefix of the route   mask = netmask of the route   nexthop = nexthop of the route   distance = distance-value of the route*/int zebra_delete_v4_route (struct ipv4_route r) {    char *cmdopt;  ssize_t optlen;    cmdopt = zebra_route_packet (r, &optlen);    return zebra_send_command (ZEBRA_IPV4_ROUTE_DELETE, cmdopt, optlen);}/* Check wether there is data from zebra aviable */void zebra_check (void* foo) {  char *data, *f;  ssize_t len, ret;  if (!status & STATUS_CONNECTED) {  }  data = try_read (&len);  if (data) {    f = data;    do {      ret = zebra_parse_packet (f, len);      if (!ret) {//something wired happened	puts ("DEBUG: IIIIIIIIIIRGS");	exit (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 char *try_read (ssize_t *len) {  char *buf = NULL;  ssize_t ret = 0, bsize = 0;  uint16_t length = 0, l = 0;  int sockstate;  *len = 0;  sockstate = fcntl (zsock, F_GETFL, 0);  fcntl (zsock, F_SETFL, sockstate|O_NONBLOCK);  do {     if (*len == bsize) {      bsize += BUFSIZE;      buf = my_realloc (buf, bsize, "Zebra try_read");    }    ret = read (zsock, buf + l, bsize - l);    if (ret <= 0) {      if (errno == EAGAIN) {	errno = 0;      }      else {	// TODO: errorhandling	;      }      free (buf);      return NULL;    }    *len += ret;    while ((*len - l) > length) {      //      printf ("DEBUG: *len -l > length - %d - %d > %d\n", *len, l, length);      l += length;      memcpy (&length, buf + l, 2);      length = ntohs (length);    }    //    printf ("DEBUG: *len, l, length: %d,%d,%d\n", *len, l, length);    if (((*len) - l) == length) break; // GOT FULL PACKAGE!!    if (*len < l) {      //      printf ("DEBUG: *len, l, length: %d,%d,%d\n", *len, l, length);      fcntl (zsock, F_SETFL, sockstate);      continue;    }  } while (1);  fcntl (zsock, F_SETFL, sockstate);  return buf;}/* Parse a packet recived from zebra */int zebra_parse_packet (char *packet, ssize_t maxlen) {  /* Array of functions */  int (*foo[ZEBRA_MESSAGE_MAX]) (char *, size_t) = {    parse_interface_add,    parse_interface_delete,    parse_interface_address_add,    parse_interface_address_delete,    parse_interface_up,    parse_interface_down,    ipv4_route_add,    ipv4_route_delete,    parse_ipv6_route_add  };    puts ("DEBUG: zebra_parse_packet");  uint16_t length;    int ret;  memcpy (&length, packet, 2);  length = ntohs (length);    if (maxlen < length) {

⌨️ 快捷键说明

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