Revision bce8a34b

View differences:

bird.conf
58 58
	garbagetime 30;
59 59
	interface "*";
60 60
	export filter testf;
61
	honour neighbour;
61 62
	passwords { password "ahoj" from 0 to 10;
62 63
		password "nazdar" from 10 to 20;
63 64
	}
proto/rip/auth.c
31 31
rip_incoming_authentication( struct proto *p, struct rip_block_auth *block, struct rip_packet *packet, int num )
32 32
{
33 33
  DBG( "Incoming authentication: " );
34

  
35 34
  switch (block->authtype) {	/* Authentication type */
36 35
  case AT_PLAINTEXT:
37 36
    DBG( "Plaintext passwd" );
......
50 49
      struct password_item *head;
51 50
      struct rip_md5_tail *tail;
52 51

  
52
      /* FIXME: check that block->packetlen looks valid */
53

  
53 54
      tail = (struct rip_md5_tail *) ((char *) packet + (block->packetlen - sizeof(struct rip_block_auth)));
54 55

  
55 56
      head = P_CF->passwords;
56
      while (head) {
57
      while (head) {	/* FIXME: should not we check that password is not expired? */
58
	/* FIXME: should check serial numbers, somehow */
57 59
	if (head->id == block->keyid) {
58 60
	  struct MD5Context ctxt;
59 61
	  char md5sum_packet[16];
......
81 83
void
82 84
rip_outgoing_authentication( struct proto *p, struct rip_block_auth *block, struct rip_packet *packet, int num )
83 85
{
86
  struct password_item *passwd = get_best_password( P_CF->passwords, 0 );
84 87
  DBG( "Outgoing authentication: " );
85 88

  
89
  if (!passwd) {
90
    log( L_ERR "no suitable password found for authentication\n" );
91
    return;
92
  }
93

  
86 94
  block->authtype = P_CF->authtype;
95
  block->mustbeFFFF = 0xffff;
87 96
  switch (P_CF->authtype) {
88 97
  case AT_PLAINTEXT:
89
    if (!P_CF->passwords) {
90
      log( L_ERR "no passwords set and password authentication requested\n" );
98
    password_strncpy( (char *) (&block->packetlen), passwd->password, 16);
99
    return;
100
  case AT_MD5:
101
    {
102
      struct rip_md5_tail *tail;
103
      struct MD5Context ctxt;
104
      static int sequence = 0;
105

  
106
      if (num > PACKET_MD5_MAX)
107
	bug(  "we can not add MD5 authentication to this long packet\n" );
108

  
109
      block->keyid = passwd->id;
110
      block->authlen = 20;
111
      block->seq = sequence++;
112
      block->zero0 = 0;
113
      block->zero1 = 1;
114
      block->packetlen = 0 /* FIXME */;
115

  
116
      tail = (struct rip_md5_tail *) ((char *) packet + (block->packetlen - sizeof(struct rip_block_auth)));
117
      tail->mustbeFFFF = 0xffff;
118
      tail->mustbe0001 = 0x0001;
119
      password_strncpy( (char *) (&tail->md5), passwd->password, 16 );
120

  
121
      MD5Init(&ctxt);
122
      MD5Update(&ctxt, (char *) packet, block->packetlen );
123
      MD5Final((char *) (&tail->md5), &ctxt);
91 124
      return;
92 125
    }
93
    password_strncpy( (char *) (&block->packetlen), P_CF->passwords->password, 16);
94
    return;
95 126
  }
96 127
}
proto/rip/config.Y
24 24

  
25 25
CF_KEYWORDS(RIP, INFINITY, METRIC, PORT, PERIOD, GARBAGETIME, PASSWORDS,
26 26
	    MODE, BROADCAST, QUIET, NOLISTEN, VERSION1, 
27
	    AUTHENTICATION, NONE, PLAINTEXT, MD5)
27
	    AUTHENTICATION, NONE, PLAINTEXT, MD5,
28
	    HONOUR, NEVER, NEIGHBOUR, ALWAYS)
28 29

  
29 30
%type <i> rip_mode rip_auth
30 31

  
......
47 48
 | RIP_CFG GARBAGETIME expr ';' { RIP_CFG->garbage_time = $3; }
48 49
 | RIP_CFG AUTHENTICATION rip_auth ';' {RIP_CFG->authtype = $3; }
49 50
 | RIP_CFG PASSWORDS '{' password_list '}' {RIP_CFG->passwords = $4; }
51
 | RIP_CFG HONOUR ALWAYS ';'    { RIP_CFG->honour = HO_ALWAYS; }
52
 | RIP_CFG HONOUR NEIGHBOUR ';'    { RIP_CFG->honour = HO_NEIGHBOUR; }
53
 | RIP_CFG HONOUR NEVER ';'    { RIP_CFG->honour = HO_NEVER; }
50 54
 | RIP_CFG rip_iface_list ';'
51 55
 ;
52 56

  
proto/rip/rip.c
96 96
      ipa_hton( packet->block[i].netmask );
97 97
      ipa_hton( packet->block[i].nexthop );
98 98

  
99
      if (i++ == 25) {
99
      if (i++ == ((P_CF->authtype == AT_MD5) ? PACKET_MD5_MAX : PACKET_MAX)) {
100 100
	FIB_ITERATE_PUT(&c->iter, z);
101 101
	goto break_loop;
102 102
      }
......
263 263

  
264 264
  switch( packet->heading.command ) {
265 265
  case RIPCMD_REQUEST: DBG( "Asked to send my routing table\n" ); 
266
    /* FIXME: should have configurable: ignore always, honour to neighbours, honour always. FIXME: use one global socket for these. FIXME: synchronization - if two ask me at same time */
267
    	  rip_sendto( p, whotoldme, port, NULL ); /* no broadcast */
266
	  if (P_CF->honour == HO_NEVER) {
267
	    log( L_WARN "They asked me to send routing table, but I was told not to do it\n" );
268
	    return 0;
269
	  }
270
	  if ((P_CF->honour == HO_NEIGHBOUR) && (!neigh_find( p, &whotoldme, 0 ))) {
271
	    log( L_WARN "They asked me to send routing table, but he is not my neighbour\n" );
272
	    return 0;
273
	  }
274
    	  rip_sendto( p, whotoldme, port, HEAD(P->interfaces) ); /* no broadcast */
268 275
          break;
269 276
  case RIPCMD_RESPONSE: DBG( "*** Rtable from %I\n", whotoldme ); 
270 277
          if (port != P_CF->port) {
......
281 288
	    return 0;
282 289
	  }
283 290

  
284
	  /* FIXME: Should check if it is not my own packet */
285

  
286 291
          for (i=0; i<num; i++) {
287 292
	    struct rip_block *block = &packet->block[i];
288 293
	    if (block->family == 0xffff)
......
487 492
  rif->sock->err_hook = rip_tx_err;
488 493
  rif->sock->daddr = IPA_NONE;
489 494
  rif->sock->dport = P_CF->port;
490
  rif->sock->ttl = 1; /* FIXME: care must be taken not to send requested responses from this socket */
495
  if (new)
496
    rif->sock->ttl = 1;
497
  else
498
    rif->sock->ttl = 30;
491 499
  rif->sock->tos = IP_PREC_INTERNET_CONTROL;
492 500

  
493 501
  if (flags & IF_BROADCAST)
......
504 512
  } else
505 513
    if (!(rif->patt->mode & IM_NOLISTEN))
506 514
      if (sk_open(rif->sock)<0) {
507
	log( L_WARN "RIP/%s: could not listen on %s", P_NAME, rif->iface ? rif->iface->name : "(dummy)" );
508
	/* FIXME: Don't try to transmit into this one */
515
	log( L_ERR "RIP/%s: could not listen on %s", P_NAME, rif->iface ? rif->iface->name : "(dummy)" );
516
	/* Don't try to transmit into this one? Well, why not? This should not happen, anyway :-) */
509 517
      }
510 518

  
511 519
  log( L_DEBUG "RIP/%s: listening on %s, port %d, mode %s", P_NAME, rif->iface ? rif->iface->name : "(dummy)", P_CF->port, want_multicast ? "multicast" : "broadcast" );
proto/rip/rip.h
8 8
#define EA_RIP_TAG	EA_CODE(EAP_RIP, 0)
9 9
#define EA_RIP_METRIC	EA_CODE(EAP_RIP, 1)
10 10

  
11
#define PACKET_MAX 25
12
#define PACKET_MD5_MAX 18	/* FIXME */
13

  
11 14
struct rip_connection {
12 15
  node n;
13 16

  
......
115 118
#define AT_NONE 0
116 119
#define AT_PLAINTEXT 2
117 120
#define AT_MD5 3
121
  int honour;
122
#define HO_NEVER 0
123
#define HO_NEIGHBOUR 1
124
#define HO_ALWAYS 2
118 125
};
119 126

  
120 127
struct rip_proto {

Also available in: Unified diff