Statistics
| Branch: | Revision:

iof-bird-daemon / proto / ospf / packet.c @ 48e5f32d

History | View | Annotate | Download (13.9 KB)

1 4364b47e Ondrej Filip
/*
2
 *        BIRD -- OSPF
3
 *
4 e6ea2e37 Ondrej Filip
 *        (c) 1999--2005 Ondrej Filip <feela@network.cz>
5 4364b47e Ondrej Filip
 *
6
 *        Can be freely distributed and used under the terms of the GNU GPL.
7
 */
8
9
#include "ospf.h"
10 3e2bd0f1 Ondrej Filip
#include "nest/password.h"
11
#include "lib/md5.h"
12 4364b47e Ondrej Filip
13
void
14 3e2bd0f1 Ondrej Filip
ospf_pkt_fill_hdr(struct ospf_iface *ifa, void *buf, u8 h_type)
15 4364b47e Ondrej Filip
{
16 8a70a13e Ondrej Zajicek
  struct proto_ospf *po = ifa->oa->po;
17 4364b47e Ondrej Filip
  struct ospf_packet *pkt;
18
19 00bd27a1 Ondrej Filip
  pkt = (struct ospf_packet *) buf;
20 4364b47e Ondrej Filip
21 00bd27a1 Ondrej Filip
  pkt->version = OSPF_VERSION;
22 4364b47e Ondrej Filip
23 00bd27a1 Ondrej Filip
  pkt->type = h_type;
24
25 8a70a13e Ondrej Zajicek
  pkt->routerid = htonl(po->router_id);
26 3b16080c Ondrej Filip
  pkt->areaid = htonl(ifa->oa->areaid);
27 c3226991 Ondrej Zajicek
28
#ifdef OSPFv3
29
  pkt->instance_id = ifa->instance_id;
30
#endif
31
32
#ifdef OSPFv2
33 2e10a170 Ondrej Filip
  pkt->autype = htons(ifa->autype);
34 c3226991 Ondrej Zajicek
#endif
35
36 00bd27a1 Ondrej Filip
  pkt->checksum = 0;
37 4364b47e Ondrej Filip
}
38
39 3e2bd0f1 Ondrej Filip
unsigned
40
ospf_pkt_maxsize(struct ospf_iface *ifa)
41
{
42 d5356072 Ondrej Zajicek
  unsigned headers = SIZE_OF_IP_HEADER;
43 c3226991 Ondrej Zajicek
44
#ifdef OSPFv2
45 d5356072 Ondrej Zajicek
  if (ifa->autype == OSPF_AUTH_CRYPT)
46
    headers += OSPF_AUTH_CRYPT_SIZE;
47 c3226991 Ondrej Zajicek
#endif
48
49 48e5f32d Ondrej Zajicek
  return ifa->tx_length - headers;
50 3e2bd0f1 Ondrej Filip
}
51
52 c3226991 Ondrej Zajicek
#ifdef OSPFv2
53
54
static void
55 3e2bd0f1 Ondrej Filip
ospf_pkt_finalize(struct ospf_iface *ifa, struct ospf_packet *pkt)
56 4364b47e Ondrej Filip
{
57 b21f68b4 Ondrej Zajicek
  struct password_item *passwd = NULL;
58 3e2bd0f1 Ondrej Filip
  void *tail;
59
  struct MD5Context ctxt;
60
  char password[OSPF_AUTH_CRYPT_SIZE];
61
62 1155c792 Ondrej Zajicek
  pkt->checksum = 0;
63 2e10a170 Ondrej Filip
  pkt->autype = htons(ifa->autype);
64 1155c792 Ondrej Zajicek
  bzero(&pkt->u, sizeof(union ospf_auth));
65
66
  /* Compatibility note: pkt->u may contain anything if autype is
67
     none, but nonzero values do not work with Mikrotik OSPF */
68 3e2bd0f1 Ondrej Filip
69
  switch(ifa->autype)
70
  {
71
    case OSPF_AUTH_SIMPLE:
72 b21f68b4 Ondrej Zajicek
      passwd = password_find(ifa->passwords, 1);
73 32d3228d Ondrej Filip
      if (!passwd)
74
      {
75
        log( L_ERR "No suitable password found for authentication" );
76
        return;
77
      }
78
      password_cpy(pkt->u.password, passwd->password, sizeof(union ospf_auth));
79 69b27ed6 Ondrej Filip
    case OSPF_AUTH_NONE:
80 32d3228d Ondrej Filip
      pkt->checksum = ipsum_calculate(pkt, sizeof(struct ospf_packet) -
81
                                  sizeof(union ospf_auth), (pkt + 1),
82 3e2bd0f1 Ondrej Filip
                                  ntohs(pkt->length) -
83
                                  sizeof(struct ospf_packet), NULL);
84
      break;
85
    case OSPF_AUTH_CRYPT:
86 b21f68b4 Ondrej Zajicek
      passwd = password_find(ifa->passwords, 0);
87 3e2bd0f1 Ondrej Filip
      if (!passwd)
88
      {
89
        log( L_ERR "No suitable password found for authentication" );
90
        return;
91
      }
92
93 024c310b Ondrej Zajicek
      /* Perhaps use random value to prevent replay attacks after
94
         reboot when system does not have independent RTC? */
95 3e2bd0f1 Ondrej Filip
      if (!ifa->csn)
96 024c310b Ondrej Zajicek
        {
97
          ifa->csn = (u32) now;
98
          ifa->csn_use = now;
99
        }
100
101
      /* We must have sufficient delay between sending a packet and increasing 
102
         CSN to prevent reordering of packets (in a network) with different CSNs */
103
      if ((now - ifa->csn_use) > 1)
104
        ifa->csn++;
105
106
      ifa->csn_use = now;
107 3e2bd0f1 Ondrej Filip
108
      pkt->u.md5.keyid = passwd->id;
109
      pkt->u.md5.len = OSPF_AUTH_CRYPT_SIZE;
110
      pkt->u.md5.zero = 0;
111 024c310b Ondrej Zajicek
      pkt->u.md5.csn = htonl(ifa->csn);
112 3e2bd0f1 Ondrej Filip
      tail = ((void *)pkt) + ntohs(pkt->length);
113
      MD5Init(&ctxt);
114
      MD5Update(&ctxt, (char *) pkt, ntohs(pkt->length));
115
      password_cpy(password, passwd->password, OSPF_AUTH_CRYPT_SIZE);
116
      MD5Update(&ctxt, password, OSPF_AUTH_CRYPT_SIZE);
117
      MD5Final(tail, &ctxt);
118
      break;
119
    default:
120
      bug("Unknown authentication type");
121
  }
122 4364b47e Ondrej Filip
}
123
124 9831e591 Martin Mares
static int
125 69b27ed6 Ondrej Filip
ospf_pkt_checkauth(struct ospf_neighbor *n, struct ospf_iface *ifa, struct ospf_packet *pkt, int size)
126 c1824c4d Ondrej Filip
{
127 86c84d76 Ondrej Filip
  struct proto_ospf *po = ifa->oa->po;
128 3e2bd0f1 Ondrej Filip
  struct proto *p = &po->proto;
129
  struct password_item *pass = NULL, *ptmp;
130
  void *tail;
131
  char md5sum[OSPF_AUTH_CRYPT_SIZE];
132
  char password[OSPF_AUTH_CRYPT_SIZE];
133
  struct MD5Context ctxt;
134
135
136 2e10a170 Ondrej Filip
  if (pkt->autype != htons(ifa->autype))
137
  {
138 3e2bd0f1 Ondrej Filip
    OSPF_TRACE(D_PACKETS, "OSPF_auth: Method differs (%d)", ntohs(pkt->autype));
139
    return 0;
140 2e10a170 Ondrej Filip
  }
141 c1824c4d Ondrej Filip
142 3e2bd0f1 Ondrej Filip
  switch(ifa->autype)
143
  {
144
    case OSPF_AUTH_NONE:
145
      return 1;
146
      break;
147
    case OSPF_AUTH_SIMPLE:
148 b21f68b4 Ondrej Zajicek
      pass = password_find(ifa->passwords, 1);
149 3b108f18 Ondrej Zajicek
      if (!pass)
150 3e2bd0f1 Ondrej Filip
      {
151
        OSPF_TRACE(D_PACKETS, "OSPF_auth: no password found");
152
        return 0;
153
      }
154 32d3228d Ondrej Filip
      password_cpy(password, pass->password, sizeof(union ospf_auth));
155 4364b47e Ondrej Filip
156 32d3228d Ondrej Filip
      if (memcmp(pkt->u.password, password, sizeof(union ospf_auth)))
157 3e2bd0f1 Ondrej Filip
      {
158 32d3228d Ondrej Filip
        char ppass[sizeof(union ospf_auth) + 1];
159
        bzero(ppass, (sizeof(union ospf_auth) + 1));
160
        memcpy(ppass, pkt->u.password, sizeof(union ospf_auth));
161
        OSPF_TRACE(D_PACKETS, "OSPF_auth: different passwords (%s)", ppass);
162 3e2bd0f1 Ondrej Filip
        return 0;
163
      }
164 32d3228d Ondrej Filip
      return 1;
165 3e2bd0f1 Ondrej Filip
      break;
166
    case OSPF_AUTH_CRYPT:
167
      if (pkt->u.md5.len != OSPF_AUTH_CRYPT_SIZE)
168
      {
169
        OSPF_TRACE(D_PACKETS, "OSPF_auth: wrong size of md5 digest");
170
        return 0;
171
      }
172 3b108f18 Ondrej Zajicek
173 885b3d61 Ondrej Zajicek
      if (ntohs(pkt->length) + OSPF_AUTH_CRYPT_SIZE > size)
174 3e2bd0f1 Ondrej Filip
      {
175 f39e3bfd Ondrej Filip
        OSPF_TRACE(D_PACKETS, "OSPF_auth: size mismatch (%d vs %d)",
176 5d3f5552 Ondrej Filip
          ntohs(pkt->length) + OSPF_AUTH_CRYPT_SIZE, size);
177 3e2bd0f1 Ondrej Filip
        return 0;
178
      }
179
180
      tail = ((void *)pkt) + ntohs(pkt->length);
181
182 3b108f18 Ondrej Zajicek
      if (ifa->passwords)
183 3e2bd0f1 Ondrej Filip
      {
184 3b108f18 Ondrej Zajicek
        WALK_LIST(ptmp, *(ifa->passwords))
185
        {
186
          if (pkt->u.md5.keyid != ptmp->id) continue;
187
          if ((ptmp->accfrom > now_real) || (ptmp->accto < now_real)) continue;
188
          pass = ptmp;
189
          break;
190
        }
191 3e2bd0f1 Ondrej Filip
      }
192
193 3b108f18 Ondrej Zajicek
      if (!pass)
194 3e2bd0f1 Ondrej Filip
      {
195
        OSPF_TRACE(D_PACKETS, "OSPF_auth: no suitable md5 password found");
196
        return 0;
197
      }
198
199 3b108f18 Ondrej Zajicek
      if (n)
200 3e2bd0f1 Ondrej Filip
      {
201 024c310b Ondrej Zajicek
        u32 rcv_csn = ntohl(pkt->u.md5.csn);
202
        if(rcv_csn < n->csn)
203
        {
204
          OSPF_TRACE(D_PACKETS, "OSPF_auth: lower sequence number (rcv %d, old %d)", rcv_csn, n->csn);
205
          return 0;
206
        }
207
208
        n->csn = rcv_csn;
209 3e2bd0f1 Ondrej Filip
      }
210
211
      MD5Init(&ctxt);
212
      MD5Update(&ctxt, (char *) pkt, ntohs(pkt->length));
213
      password_cpy(password, pass->password, OSPF_AUTH_CRYPT_SIZE);
214
      MD5Update(&ctxt, password, OSPF_AUTH_CRYPT_SIZE);
215
      MD5Final(md5sum, &ctxt);
216 bc956fca Ondrej Filip
      if (memcmp(md5sum, tail, OSPF_AUTH_CRYPT_SIZE))
217 3e2bd0f1 Ondrej Filip
      {
218
        OSPF_TRACE(D_PACKETS, "OSPF_auth: wrong md5 digest");
219
        return 0;
220
      }
221
      return 1;
222
      break;
223
    default:
224
      OSPF_TRACE(D_PACKETS, "OSPF_auth: unknown auth type");
225
      return 0;
226
  }
227 4364b47e Ondrej Filip
}
228
229 c3226991 Ondrej Zajicek
#else
230
231
/* OSPFv3 authentication not yet supported */
232
233
static inline void
234
ospf_pkt_finalize(struct ospf_iface *ifa, struct ospf_packet *pkt)
235
{ }
236
237
static int
238
ospf_pkt_checkauth(struct ospf_neighbor *n, struct ospf_iface *ifa, struct ospf_packet *pkt, int size)
239
{ return 1; }
240 353729f5 Ondrej Zajicek
 
241
#endif
242
243 c3226991 Ondrej Zajicek
244 351feeb5 Ondrej Filip
/**
245
 * ospf_rx_hook
246 353729f5 Ondrej Zajicek
 * @sk: socket we received the packet.
247 351feeb5 Ondrej Filip
 * @size: size of the packet
248
 *
249 baa5dd6c Ondrej Filip
 * This is the entry point for messages from neighbors. Many checks (like
250
 * authentication, checksums, size) are done before the packet is passed to
251 351feeb5 Ondrej Filip
 * non generic functions.
252
 */
253 4364b47e Ondrej Filip
int
254 353729f5 Ondrej Zajicek
ospf_rx_hook(sock *sk, int size)
255 4364b47e Ondrej Filip
{
256 353729f5 Ondrej Zajicek
  char *mesg = "OSPF: Bad packet from ";
257 4364b47e Ondrej Filip
258 e7b76b97 Ondrej Zajicek
  /* We want just packets from sk->iface. Unfortunately, on BSD we
259
     cannot filter out other packets at kernel level and we receive
260
     all packets on all sockets */
261
  if (sk->lifindex != sk->iface->index)
262
    return 1;
263
264
  DBG("OSPF: RX hook called (iface %s, src %I, dst %I)\n",
265 48e5f32d Ondrej Zajicek
      sk->ifname, sk->faddr, sk->laddr);
266 e7b76b97 Ondrej Zajicek
267
  /* Initially, the packet is associated with the 'master' iface */
268
  struct ospf_iface *ifa = sk->data;
269
  struct proto_ospf *po = ifa->oa->po;
270 54305181 Ondrej Zajicek
  // struct proto *p = &po->proto;
271 e7b76b97 Ondrej Zajicek
272 ab164971 Ondrej Zajicek
  int src_local, dst_local UNUSED, dst_mcast; 
273
  src_local = ipa_in_net(sk->faddr, ifa->addr->prefix, ifa->addr->pxlen);
274
  dst_local = ipa_equal(sk->laddr, ifa->addr->ip);
275 95127cbb Ondrej Zajicek
  dst_mcast = ipa_equal(sk->laddr, ifa->all_routers) || ipa_equal(sk->laddr, AllDRouters);
276 e7b76b97 Ondrej Zajicek
277
#ifdef OSPFv2
278
  /* First, we eliminate packets with strange address combinations.
279
   * In OSPFv2, they might be for other ospf_ifaces (with different IP
280
   * prefix) on the same real iface, so we don't log it. We enforce
281
   * that (src_local || dst_local), therefore we are eliminating all
282
   * such cases. 
283
   */
284
  if (dst_mcast && !src_local)
285
    return 1;
286
  if (!dst_mcast && !dst_local)
287
    return 1;
288 00bd27a1 Ondrej Filip
289 95127cbb Ondrej Zajicek
  /* Ignore my own broadcast packets */
290
  if (ifa->cf->real_bcast && ipa_equal(sk->faddr, ifa->addr->ip))
291
    return 1;
292 e7b76b97 Ondrej Zajicek
#else /* OSPFv3 */
293
294
  /* In OSPFv3, src_local and dst_local mean link-local. 
295
   * RFC 5340 says that local (non-vlink) packets use
296
   * link-local src address, but does not enforce it. Strange.
297
   */
298
  if (dst_mcast && !src_local)
299
    log(L_WARN "OSPF: Received multicast packet from %I (not link-local)", sk->faddr);
300
#endif
301
302
  /* Second, we check packet size, checksum, and the protocol version */
303 353729f5 Ondrej Zajicek
  struct ospf_packet *ps = (struct ospf_packet *) ip_skip_header(sk->rbuf, &size);
304 3b16080c Ondrej Filip
305 0e9617e4 Ondrej Zajicek
  if (ps == NULL)
306
  {
307
    log(L_ERR "%s%I - bad IP header", mesg, sk->faddr);
308
    return 1;
309
  }
310
311 70e212f9 Ondrej Zajicek
  if (ifa->check_ttl && (sk->ttl < 255))
312
  {
313
    log(L_ERR "%s%I - TTL %d (< 255)", mesg, sk->faddr, sk->ttl);
314
    return 1;
315
  }
316
317 2e10a170 Ondrej Filip
  if ((unsigned) size < sizeof(struct ospf_packet))
318
  {
319 5e3436d2 Ondrej Filip
    log(L_ERR "%s%I - too short (%u bytes)", mesg, sk->faddr, size);
320
    return 1;
321 2e10a170 Ondrej Filip
  }
322 00bd27a1 Ondrej Filip
323 48e5f32d Ondrej Zajicek
  uint plen = ntohs(ps->length);
324
  if ((plen < sizeof(struct ospf_packet)) || ((plen % 4) != 0))
325 d600909d Ondrej Filip
  {
326 48e5f32d Ondrej Zajicek
    log(L_ERR "%s%I - invalid length (%u)", mesg, sk->faddr, plen);
327 d600909d Ondrej Filip
    return 1;
328
  }
329
330 48e5f32d Ondrej Zajicek
  if (sk->flags & SKF_TRUNCATED)
331 2e10a170 Ondrej Filip
  {
332 48e5f32d Ondrej Zajicek
    log(L_WARN "%s%I - too large (%d/%d)", mesg, sk->faddr, plen, size);
333
334
    /* If we have dynamic buffers and received truncated message, we expand RX buffer */
335
336
    uint bs = plen + 256;
337
    bs = BIRD_ALIGN(bs, 1024);
338
339
    if (!ifa->cf->rx_buffer && (bs > sk->rbsize))
340
      sk_set_rbsize(sk, bs);
341
342 5e3436d2 Ondrej Filip
    return 1;
343 2e10a170 Ondrej Filip
  }
344 00bd27a1 Ondrej Filip
345 48e5f32d Ondrej Zajicek
  if (plen > size)
346 353729f5 Ondrej Zajicek
  {
347 48e5f32d Ondrej Zajicek
    log(L_ERR "%s%I - size field does not match (%d/%d)", mesg, sk->faddr, plen, size);
348 353729f5 Ondrej Zajicek
    return 1;
349
  }
350
351 00bd27a1 Ondrej Filip
  if (ps->version != OSPF_VERSION)
352 2e10a170 Ondrej Filip
  {
353 5e3436d2 Ondrej Filip
    log(L_ERR "%s%I - version %u", mesg, sk->faddr, ps->version);
354
    return 1;
355 2e10a170 Ondrej Filip
  }
356 00bd27a1 Ondrej Filip
357 c3226991 Ondrej Zajicek
#ifdef OSPFv2
358 bc956fca Ondrej Filip
  if ((ps->autype != htons(OSPF_AUTH_CRYPT)) &&
359
      (!ipsum_verify(ps, 16, (void *) ps + sizeof(struct ospf_packet),
360 48e5f32d Ondrej Zajicek
                     plen - sizeof(struct ospf_packet), NULL)))
361 2e10a170 Ondrej Filip
  {
362 5e3436d2 Ondrej Filip
    log(L_ERR "%s%I - bad checksum", mesg, sk->faddr);
363
    return 1;
364 2e10a170 Ondrej Filip
  }
365 c3226991 Ondrej Zajicek
#endif
366 00bd27a1 Ondrej Filip
367 353729f5 Ondrej Zajicek
368 e7b76b97 Ondrej Zajicek
  /* Third, we resolve associated iface and handle vlinks. */
369
370
  u32 areaid = ntohl(ps->areaid);
371
  u32 rid = ntohl(ps->routerid);
372
373
  if ((areaid == ifa->oa->areaid)
374
#ifdef OSPFv3
375 bed41728 Ondrej Zajicek
      && (ps->instance_id == ifa->instance_id)
376 e7b76b97 Ondrej Zajicek
#endif
377
      )
378
  {
379
    /* It is real iface, source should be local (in OSPFv2) */
380
#ifdef OSPFv2
381
    if (!src_local)
382
      return 1;
383
#endif
384
  }
385
  else if (dst_mcast || (areaid != 0))
386
  {
387
    /* Obvious mismatch */
388
389
#ifdef OSPFv2
390
    /* We ignore mismatch in OSPFv3, because there might be
391
       other instance with different instance ID */
392
    log(L_ERR "%s%I - area does not match (%R vs %R)",
393
        mesg, sk->faddr, areaid, ifa->oa->areaid);
394
#endif
395
    return 1;
396
  }
397
  else
398 2e10a170 Ondrej Filip
  {
399 e7b76b97 Ondrej Zajicek
    /* Some vlink? */
400
    struct ospf_iface *iff = NULL;
401
402
    WALK_LIST(iff, po->iface_list)
403 353729f5 Ondrej Zajicek
    {
404 e7b76b97 Ondrej Zajicek
      if ((iff->type == OSPF_IT_VLINK) && 
405
          (iff->voa == ifa->oa) &&
406
#ifdef OSPFv3
407
          (iff->instance_id == ps->instance_id) &&
408
#endif
409
          (iff->vid == rid))
410
        {
411
          /* Vlink should be UP */
412
          if (iff->state != OSPF_IS_PTP)
413
            return 1;
414
          
415
          ifa = iff;
416
          goto found;
417
        }
418 353729f5 Ondrej Zajicek
    }
419
420 e7b76b97 Ondrej Zajicek
#ifdef OSPFv2
421 ed76033c Ondrej Zajicek
    log(L_WARN "OSPF: Received packet for unknown vlink (ID %R, IP %I)", rid, sk->faddr);
422 e7b76b97 Ondrej Zajicek
#endif
423 5e3436d2 Ondrej Filip
    return 1;
424 2e10a170 Ondrej Filip
  }
425 00bd27a1 Ondrej Filip
426 e7b76b97 Ondrej Zajicek
 found:
427 353729f5 Ondrej Zajicek
  if (ifa->stub)            /* This shouldn't happen */
428
    return 1;
429
430
  if (ipa_equal(sk->laddr, AllDRouters) && (ifa->sk_dr == 0))
431 c3226991 Ondrej Zajicek
    return 1;
432
433 e7b76b97 Ondrej Zajicek
  if (rid == po->router_id)
434 2e10a170 Ondrej Filip
  {
435 5e3436d2 Ondrej Filip
    log(L_ERR "%s%I - received my own router ID!", mesg, sk->faddr);
436
    return 1;
437 2e10a170 Ondrej Filip
  }
438 00bd27a1 Ondrej Filip
439 e7b76b97 Ondrej Zajicek
  if (rid == 0)
440 2e10a170 Ondrej Filip
  {
441 5e3436d2 Ondrej Filip
    log(L_ERR "%s%I - router id = 0.0.0.0", mesg, sk->faddr);
442
    return 1;
443
  }
444
445 9d1ee138 Ondrej Zajicek
#ifdef OSPFv2
446
  /* In OSPFv2, neighbors are identified by either IP or Router ID, base on network type */
447
  struct ospf_neighbor *n;
448 919f5411 Ondrej Zajicek
  if ((ifa->type == OSPF_IT_BCAST) || (ifa->type == OSPF_IT_NBMA) || (ifa->type == OSPF_IT_PTMP))
449 9d1ee138 Ondrej Zajicek
    n = find_neigh_by_ip(ifa, sk->faddr);
450
  else
451
    n = find_neigh(ifa, rid);
452
#else
453 e7b76b97 Ondrej Zajicek
  struct ospf_neighbor *n = find_neigh(ifa, rid);
454 9d1ee138 Ondrej Zajicek
#endif
455 5e3436d2 Ondrej Filip
456
  if(!n && (ps->type != HELLO_P))
457
  {
458 ed76033c Ondrej Zajicek
    log(L_WARN "OSPF: Received non-hello packet from unknown neighbor (src %I, iface %s)",
459 48e5f32d Ondrej Zajicek
        sk->faddr, ifa->ifname);
460 5e3436d2 Ondrej Filip
    return 1;
461 2e10a170 Ondrej Filip
  }
462 00bd27a1 Ondrej Filip
463 69b27ed6 Ondrej Filip
  if (!ospf_pkt_checkauth(n, ifa, ps, size))
464 3e2bd0f1 Ondrej Filip
  {
465 ed76033c Ondrej Zajicek
    log(L_ERR "%s%I - authentication failed", mesg, sk->faddr);
466 3e2bd0f1 Ondrej Filip
    return 1;
467
  }
468
469 351feeb5 Ondrej Filip
  /* Dump packet 
470 00bd27a1 Ondrej Filip
     pu8=(u8 *)(sk->rbuf+5*4);
471
     for(i=0;i<ntohs(ps->length);i+=4)
472
     DBG("%s: received %u,%u,%u,%u\n",p->name, pu8[i+0], pu8[i+1], pu8[i+2],
473
     pu8[i+3]);
474
     DBG("%s: received size: %u\n",p->name,size);
475
   */
476
477
  switch (ps->type)
478 2e10a170 Ondrej Filip
  {
479
  case HELLO_P:
480
    DBG("%s: Hello received.\n", p->name);
481 c3226991 Ondrej Zajicek
    ospf_hello_receive(ps, ifa, n, sk->faddr);
482 2e10a170 Ondrej Filip
    break;
483
  case DBDES_P:
484
    DBG("%s: Database description received.\n", p->name);
485 c3226991 Ondrej Zajicek
    ospf_dbdes_receive(ps, ifa, n);
486 2e10a170 Ondrej Filip
    break;
487
  case LSREQ_P:
488
    DBG("%s: Link state request received.\n", p->name);
489 c3226991 Ondrej Zajicek
    ospf_lsreq_receive(ps, ifa, n);
490 2e10a170 Ondrej Filip
    break;
491
  case LSUPD_P:
492
    DBG("%s: Link state update received.\n", p->name);
493 c3226991 Ondrej Zajicek
    ospf_lsupd_receive(ps, ifa, n);
494 2e10a170 Ondrej Filip
    break;
495
  case LSACK_P:
496
    DBG("%s: Link state ack received.\n", p->name);
497 c3226991 Ondrej Zajicek
    ospf_lsack_receive(ps, ifa, n);
498 2e10a170 Ondrej Filip
    break;
499
  default:
500 5e3436d2 Ondrej Filip
    log(L_ERR "%s%I - wrong type %u", mesg, sk->faddr, ps->type);
501
    return 1;
502 2e10a170 Ondrej Filip
  };
503 5e3436d2 Ondrej Filip
  return 1;
504 4364b47e Ondrej Filip
}
505
506 48e5f32d Ondrej Zajicek
/*
507 4364b47e Ondrej Filip
void
508 2e10a170 Ondrej Filip
ospf_tx_hook(sock * sk)
509 4364b47e Ondrej Filip
{
510 5c78e0e3 Ondrej Zajicek
  struct ospf_iface *ifa= (struct ospf_iface *) (sk->data);
511 353729f5 Ondrej Zajicek
//  struct proto *p = (struct proto *) (ifa->oa->po);
512 48e5f32d Ondrej Zajicek
  log(L_ERR "OSPF: TX hook called on %s", ifa->ifname);
513 4364b47e Ondrej Filip
}
514 48e5f32d Ondrej Zajicek
*/
515 4364b47e Ondrej Filip
516
void
517 2eef9e88 Ondrej Filip
ospf_err_hook(sock * sk, int err)
518 4364b47e Ondrej Filip
{
519 5c78e0e3 Ondrej Zajicek
  struct ospf_iface *ifa= (struct ospf_iface *) (sk->data);
520 48e5f32d Ondrej Zajicek
  struct proto *p = &(ifa->oa->po->proto);
521
  log(L_ERR "%s: Socket error on %s: %M", p->name, ifa->ifname, err);
522
}
523
524
void
525
ospf_verr_hook(sock *sk, int err)
526
{
527
  struct proto_ospf *po = (struct proto_ospf *) (sk->data);
528
  struct proto *p =  &po->proto;
529
  log(L_ERR "%s: Vlink socket error: %M", p->name, err);
530 4364b47e Ondrej Filip
}
531
532 67315ef6 Ondrej Filip
void
533 f9c799a0 Ondrej Zajicek
ospf_send_to_agt(struct ospf_iface *ifa, u8 state)
534 67315ef6 Ondrej Filip
{
535
  struct ospf_neighbor *n;
536
537 353729f5 Ondrej Zajicek
  WALK_LIST(n, ifa->neigh_list)
538
    if (n->state >= state)
539
      ospf_send_to(ifa, n->ip);
540 00bd27a1 Ondrej Filip
}
541 eb436e16 Ondrej Filip
542
void
543 f9c799a0 Ondrej Zajicek
ospf_send_to_bdr(struct ospf_iface *ifa)
544 eb436e16 Ondrej Filip
{
545 3b16080c Ondrej Filip
  if (!ipa_equal(ifa->drip, IPA_NONE))
546 f9c799a0 Ondrej Zajicek
    ospf_send_to(ifa, ifa->drip);
547 3b16080c Ondrej Filip
  if (!ipa_equal(ifa->bdrip, IPA_NONE))
548 f9c799a0 Ondrej Zajicek
    ospf_send_to(ifa, ifa->bdrip);
549 eb436e16 Ondrej Filip
}
550 98ac6176 Ondrej Filip
551
void
552 353729f5 Ondrej Zajicek
ospf_send_to(struct ospf_iface *ifa, ip_addr dst)
553 98ac6176 Ondrej Filip
{
554 f9c799a0 Ondrej Zajicek
  sock *sk = ifa->sk;
555 3e2bd0f1 Ondrej Filip
  struct ospf_packet *pkt = (struct ospf_packet *) sk->tbuf;
556 c3226991 Ondrej Zajicek
  int len = ntohs(pkt->length);
557 3e2bd0f1 Ondrej Filip
558 c3226991 Ondrej Zajicek
#ifdef OSPFv2
559
  if (ifa->autype == OSPF_AUTH_CRYPT)
560
    len += OSPF_AUTH_CRYPT_SIZE;
561
#endif
562
563
  ospf_pkt_finalize(ifa, pkt);
564 f15cb99c Ondrej Zajicek
565 48e5f32d Ondrej Zajicek
  int done = sk_send_to(sk, len, dst, 0);
566
  if (!done)
567
    log(L_WARN "OSPF: TX queue full on %s", ifa->ifname);
568 98ac6176 Ondrej Filip
}