Statistics
| Branch: | Revision:

iof-bird-daemon / proto / ospf / packet.c @ 1155c792

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