7a99cab16a6af8a44c1923febe121abaaea33cad
[olsrd.git] / lib / quagga / src / packet.c
1 /*
2  * OLSRd Quagga plugin
3  *
4  * Copyright (C) 2006-2008 Immo 'FaUl' Wehrenberg <immo@chaostreff-dortmund.de>
5  * Copyright (C) 2007-2010 Vasilis Tsiligiannis <acinonyxs@yahoo.gr>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License version 2 as
9  * published by the Free Software Foundation or - at your option - under
10  * the terms of the GNU General Public Licence version 2 but can be
11  * linked to any BSD-Licenced Software with public available sourcecode
12  *
13  */
14
15 /* -------------------------------------------------------------------------
16  * File               : packet.c
17  * Description        : zebra packet creation functions
18  * ------------------------------------------------------------------------- */
19
20 #include "defs.h"
21 #include "olsr.h"
22
23 #include "common.h"
24 #include "packet.h"
25
26 unsigned char
27 *zpacket_route(uint16_t cmd, struct zroute *r)
28 {
29   int count;
30   uint8_t len;
31   uint16_t size;
32   uint32_t ind, metric;
33   unsigned char *cmdopt, *t;
34
35   cmdopt = olsr_malloc(ZEBRA_MAX_PACKET_SIZ, "zebra add_v4_route");
36
37   t = &cmdopt[2];
38   if (zebra.version) {
39     *t++ = ZEBRA_HEADER_MARKER;
40     *t++ = zebra.version;
41     cmd = htons(cmd);
42     memcpy(t, &cmd, sizeof cmd);
43     t += sizeof cmd;
44   } else
45       *t++ = (unsigned char) cmd;
46   *t++ = r->type;
47   *t++ = r->flags;
48   *t++ = r->message;
49   *t++ = r->prefixlen;
50   len = (r->prefixlen + 7) / 8;
51   if (olsr_cnf->ip_version == AF_INET)
52     memcpy(t, &r->prefix.v4.s_addr, len);
53   else
54     memcpy(t, r->prefix.v6.s6_addr, len);
55   t = t + len;
56
57   if (r->message & ZAPI_MESSAGE_NEXTHOP) {
58     *t++ = r->nexthop_num + r->ifindex_num;
59
60       for (count = 0; count < r->nexthop_num; count++) {
61         if (olsr_cnf->ip_version == AF_INET) {
62           *t++ = ZEBRA_NEXTHOP_IPV4;
63           memcpy(t, &r->nexthop[count].v4.s_addr, sizeof r->nexthop[count].v4.s_addr);
64           t += sizeof r->nexthop[count].v4.s_addr;
65         } else {
66           *t++ = ZEBRA_NEXTHOP_IPV6;
67           memcpy(t, r->nexthop[count].v6.s6_addr, sizeof r->nexthop[count].v6.s6_addr);
68           t += sizeof r->nexthop[count].v6.s6_addr;
69         }
70       }
71       for (count = 0; count < r->ifindex_num; count++) {
72         *t++ = ZEBRA_NEXTHOP_IFINDEX;
73         ind = htonl(r->ifindex[count]);
74         memcpy(t, &ind, sizeof ind);
75         t += sizeof ind;
76       }
77   }
78   if ((r->message & ZAPI_MESSAGE_DISTANCE) > 0)
79     *t++ = r->distance;
80   if ((r->message & ZAPI_MESSAGE_METRIC) > 0) {
81     metric = htonl(r->metric);
82     memcpy(t, &metric, sizeof metric);
83     t += sizeof metric;
84   }
85   size = htons(t - cmdopt);
86   memcpy(cmdopt, &size, sizeof size);
87
88   return cmdopt;
89 }
90
91 unsigned char
92 *zpacket_redistribute (uint16_t cmd, unsigned char type)
93 {
94   unsigned char *data, *pnt;
95   uint16_t size;
96
97   data = olsr_malloc(ZEBRA_MAX_PACKET_SIZ , "zebra_redistribute_packet");
98
99   pnt = &data[2];
100   if (zebra.version) {
101     *pnt++ = ZEBRA_HEADER_MARKER;
102     *pnt++ = zebra.version;
103     cmd = htons(cmd);
104     memcpy(pnt, &cmd, sizeof cmd);
105     pnt += sizeof cmd;
106   } else
107       *pnt++ = (unsigned char) cmd;
108   *pnt++ = type;
109   size = htons(pnt - data);
110   memcpy(data, &size, sizeof size);
111
112   return data;
113 }
114
115 /*
116  * Local Variables:
117  * c-basic-offset: 2
118  * indent-tabs-mode: nil
119  * End:
120  */