Statistics
| Branch: | Revision:

iof-bird-daemon / proto / ospf / packet.c @ 351feeb5

History | View | Annotate | Download (5.64 KB)

1
/*
2
 *        BIRD -- OSPF
3
 *
4
 *        (c) 1999 - 2000 Ondrej Filip <feela@network.cz>
5
 *
6
 *        Can be freely distributed and used under the terms of the GNU GPL.
7
 */
8

    
9
#include "ospf.h"
10

    
11
void
12
fill_ospf_pkt_hdr(struct ospf_iface *ifa, void *buf, u8 h_type)
13
{
14
  struct ospf_packet *pkt;
15
  struct proto *p;
16
  
17
  p=(struct proto *)(ifa->proto);
18

    
19
  pkt=(struct ospf_packet *)buf;
20

    
21
  pkt->version=OSPF_VERSION;
22

    
23
  pkt->type=h_type;
24

    
25
  pkt->routerid=htonl(p->cf->global->router_id);
26
  pkt->areaid=htonl(ifa->an);
27
  pkt->autype=htons(ifa->autype);
28
  pkt->checksum=0;
29
}
30

    
31
void
32
ospf_tx_authenticate(struct ospf_iface *ifa, struct ospf_packet *pkt)
33
{
34
  int i;
35
  pkt->autype=ifa->autype;
36
  memcpy(pkt->authetication, ifa->aukey, 8);
37
  return;
38
}
39

    
40
int
41
ospf_rx_authenticate(struct ospf_iface *ifa, struct ospf_packet *pkt)
42
{
43
  int i;
44
  if(pkt->autype!=ifa->autype) return 0;
45
  if(ifa->autype==AU_NONE) return 1;
46
  if(ifa->autype==AU_SIMPLE)
47
  {
48
    for(i=0;i<8;i++)
49
    {
50
      if(pkt->authetication[i]!=ifa->aukey[i]) return 0;
51
    }
52
    return 1;
53
  }
54
  return 0;
55
}
56

    
57
void
58
ospf_pkt_finalize(struct ospf_iface *ifa, struct ospf_packet *pkt)
59
{
60

    
61
  ospf_tx_authenticate(ifa, pkt);
62

    
63
  /* Count checksum */
64
  pkt->checksum=ipsum_calculate(pkt,sizeof(struct ospf_packet)-8,
65
    (pkt+1),ntohs(pkt->length)-sizeof(struct ospf_packet),NULL);
66
}
67

    
68
/**
69
 * ospf_rx_hook
70
 * @sk: socket we recived the packet. Its ignored.
71
 * @size: size of the packet
72
 *
73
 * This in entry point for messages from neighbors. Many checks (like
74
 * autnetication, checksums, size) are done before packet is passed to
75
 * non generic functions.
76
 */
77
int
78
ospf_rx_hook(sock *sk, int size)
79
{
80
#ifndef IPV6
81
  struct ospf_packet *ps;
82
  struct ospf_iface *ifa=(struct ospf_iface *)(sk->data);
83
  struct proto *p=(struct proto *)(ifa->proto);
84
  int i;
85
  u8 *pu8;
86

    
87
  DBG("%s: RX_Hook called on interface %s.\n",p->name, sk->iface->name);
88

    
89
  ps = (struct ospf_packet *) ipv4_skip_header(sk->rbuf, &size);
90
  if(ps==NULL)
91
  {
92
    log("%s: Bad OSPF packet received: bad IP header", p->name);
93
    log("%s: Discarding",p->name);
94
    return(1);
95
  }
96
  
97
  if((unsigned)size < sizeof(struct ospf_packet))
98
  {
99
    log("%s: Bad OSPF packet received: too short (%u bytes)", p->name, size);
100
    log("%s: Discarding",p->name);
101
    return(1);
102
  }
103

    
104
  if((ntohs(ps->length)!=size)||(size!=(4*(size/4))))
105
  {
106
    log("%s: Bad OSPF packet received: size field does not match", p->name);
107
    log("%s: Discarding",p->name);
108
    return(1);
109
  }
110

    
111
  if(ps->version!=OSPF_VERSION)
112
  {
113
    log("%s: Bad OSPF packet received: version %u", p->name, ps->version);
114
    log("%s: Discarding",p->name);
115
    return(1);
116
  }
117

    
118
  if(!ipsum_verify(ps, 16,(void *)ps+sizeof(struct ospf_packet),
119
    ntohs(ps->length)-sizeof(struct ospf_packet), NULL))
120
  {
121
    log("%s: Bad OSPF packet received: bad checksum", p->name);
122
    log("%s: Discarding",p->name);
123
    return(1);
124
  }
125

    
126
  if(!ospf_rx_authenticate(ifa,ps))
127
  {
128
    log("%s: Bad OSPF packet received: bad password", p->name);
129
    return(1);
130
  }
131

    
132
  if(ps->areaid!=ifa->an)
133
  {
134
    log("%s: Bad OSPF packet received: other area %ld", p->name, ps->areaid);
135
    log("%s: Discarding",p->name);
136
    return(1);
137
  }
138

    
139
  if(ntohl(ps->routerid)==p->cf->global->router_id)
140
  {
141
    log("%s: Bad OSPF packet received: received my own router ID!", p->name);
142
    log("%s: Discarding",p->name);
143
    return(1);
144
  }
145

    
146
  if(ntohl(ps->routerid)==0)
147
  {
148
    log("%s: Bad OSPF packet received: Id 0.0.0.0 is not allowed.", p->name);
149
    log("%s: Discarding",p->name);
150
    return(1);
151
  }
152
  
153
  /* Dump packet 
154
  pu8=(u8 *)(sk->rbuf+5*4);
155
  for(i=0;i<ntohs(ps->length);i+=4)
156
    DBG("%s: received %u,%u,%u,%u\n",p->name, pu8[i+0], pu8[i+1], pu8[i+2],
157
                    pu8[i+3]);
158
  DBG("%s: received size: %u\n",p->name,size);
159
  */
160

    
161
  switch(ps->type)
162
  {
163
    case HELLO_P:
164
      DBG("%s: Hello received.\n", p->name);
165
      ospf_hello_rx((struct ospf_hello_packet *)ps, p, ifa, size, sk->faddr);
166
      break;
167
    case DBDES_P:
168
      DBG("%s: Database description received.\n", p->name);
169
      ospf_dbdes_rx((struct ospf_dbdes_packet *)ps, p, ifa, size);
170
      break;
171
    case LSREQ_P:
172
      DBG("%s: Link state request received.\n", p->name);
173
      ospf_lsreq_rx((struct ospf_lsreq_packet *)ps, p, ifa, size);
174
      break;
175
    case LSUPD_P:
176
      DBG("%s: Link state update received.\n", p->name);
177
      ospf_lsupd_rx((struct ospf_lsupd_packet *)ps, p, ifa, size);
178
      break;
179
    case LSACK_P:
180
      DBG("%s: Link state ack received.\n", p->name);
181
      ospf_lsack_rx((struct ospf_lsack_packet *)ps, p, ifa, size);
182
      break;
183
    default:
184
      log("%s: Bad packet received: wrong type %u", p->name, ps->type);
185
      log("%s: Discarding\n",p->name);
186
      return(1);
187
  };
188
#else
189
#error RX_Hook does not work for IPv6 now.
190
#endif
191
  return(1);
192
}
193

    
194
void
195
ospf_tx_hook(sock *sk)
196
{
197
  struct ospf_iface *ifa;
198
  struct proto *p;
199

    
200
  ifa=(struct ospf_iface *)(sk->data);
201

    
202
  p=(struct proto *)(ifa->proto);
203
  DBG("%s: TX_Hook called on interface %s\n", p->name,sk->iface->name);
204
}
205

    
206
void
207
ospf_err_hook(sock *sk, int err)
208
{
209
  struct ospf_iface *ifa;
210
  struct proto *p;
211

    
212
  ifa=(struct ospf_iface *)(sk->data);
213

    
214
  p=(struct proto *)(ifa->proto);
215
  DBG("%s: Err_Hook called on interface %s\n", p->name,sk->iface->name);
216
}
217

    
218
void
219
sk_send_to_agt(sock *sk, u16 len, struct ospf_iface *ifa, u8 state)
220
{
221
  struct ospf_neighbor *n;
222

    
223
  WALK_LIST(NODE n,ifa->neigh_list)
224
    if(n->state>=state)
225
      sk_send_to(sk, len, n->ip, OSPF_PROTO);
226
}                                                                       
227

    
228
void
229
sk_send_to_bdr(sock *sk, u16 len, struct ospf_iface *ifa)
230
{
231
  struct ospf_neighbor *n;
232

    
233
  if(ipa_compare(ifa->drip,ipa_from_u32(0))!=0)
234
    sk_send_to(sk, len, ifa->drip, OSPF_PROTO);
235
  if(ipa_compare(ifa->bdrip,ipa_from_u32(0))!=0)
236
    sk_send_to(sk, len, ifa->bdrip, OSPF_PROTO);
237
}
238