]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Few fixme's fixed in rip (will not crash any more on request for
authorPavel Machek <pavel@ucw.cz>
Wed, 18 Aug 1999 13:19:33 +0000 (13:19 +0000)
committerPavel Machek <pavel@ucw.cz>
Wed, 18 Aug 1999 13:19:33 +0000 (13:19 +0000)
sending routing table - hopefully).

Next few steps in md5 authentication (not yet complete).

bird.conf
proto/rip/auth.c
proto/rip/config.Y
proto/rip/rip.c
proto/rip/rip.h

index 466b45ccc32b2f5e92d8a521377575a04c728a13..c322efb2ce2459055a8cfeecca1464a51139734c 100644 (file)
--- a/bird.conf
+++ b/bird.conf
@@ -58,6 +58,7 @@ protocol rip MyRIP_test {
        garbagetime 30;
        interface "*";
        export filter testf;
+       honour neighbour;
        passwords { password "ahoj" from 0 to 10;
                password "nazdar" from 10 to 20;
        }
index 3dbec83db2285f3bc5ea4caa00bb7d189cca87a8..4777eb553b90e4c4eb69a54b406d9407cd92614d 100644 (file)
@@ -31,7 +31,6 @@ int
 rip_incoming_authentication( struct proto *p, struct rip_block_auth *block, struct rip_packet *packet, int num )
 {
   DBG( "Incoming authentication: " );
-
   switch (block->authtype) {   /* Authentication type */
   case AT_PLAINTEXT:
     DBG( "Plaintext passwd" );
@@ -50,10 +49,13 @@ rip_incoming_authentication( struct proto *p, struct rip_block_auth *block, stru
       struct password_item *head;
       struct rip_md5_tail *tail;
 
+      /* FIXME: check that block->packetlen looks valid */
+
       tail = (struct rip_md5_tail *) ((char *) packet + (block->packetlen - sizeof(struct rip_block_auth)));
 
       head = P_CF->passwords;
-      while (head) {
+      while (head) {   /* FIXME: should not we check that password is not expired? */
+       /* FIXME: should check serial numbers, somehow */
        if (head->id == block->keyid) {
          struct MD5Context ctxt;
          char md5sum_packet[16];
@@ -81,16 +83,45 @@ rip_incoming_authentication( struct proto *p, struct rip_block_auth *block, stru
 void
 rip_outgoing_authentication( struct proto *p, struct rip_block_auth *block, struct rip_packet *packet, int num )
 {
+  struct password_item *passwd = get_best_password( P_CF->passwords, 0 );
   DBG( "Outgoing authentication: " );
 
+  if (!passwd) {
+    log( L_ERR "no suitable password found for authentication\n" );
+    return;
+  }
+
   block->authtype = P_CF->authtype;
+  block->mustbeFFFF = 0xffff;
   switch (P_CF->authtype) {
   case AT_PLAINTEXT:
-    if (!P_CF->passwords) {
-      log( L_ERR "no passwords set and password authentication requested\n" );
+    password_strncpy( (char *) (&block->packetlen), passwd->password, 16);
+    return;
+  case AT_MD5:
+    {
+      struct rip_md5_tail *tail;
+      struct MD5Context ctxt;
+      static int sequence = 0;
+
+      if (num > PACKET_MD5_MAX)
+       bug(  "we can not add MD5 authentication to this long packet\n" );
+
+      block->keyid = passwd->id;
+      block->authlen = 20;
+      block->seq = sequence++;
+      block->zero0 = 0;
+      block->zero1 = 1;
+      block->packetlen = 0 /* FIXME */;
+
+      tail = (struct rip_md5_tail *) ((char *) packet + (block->packetlen - sizeof(struct rip_block_auth)));
+      tail->mustbeFFFF = 0xffff;
+      tail->mustbe0001 = 0x0001;
+      password_strncpy( (char *) (&tail->md5), passwd->password, 16 );
+
+      MD5Init(&ctxt);
+      MD5Update(&ctxt, (char *) packet, block->packetlen );
+      MD5Final((char *) (&tail->md5), &ctxt);
       return;
     }
-    password_strncpy( (char *) (&block->packetlen), P_CF->passwords->password, 16);
-    return;
   }
 }
index 8590e57f9a623f4192cafd2607f41934508bc197..1bc67207719578f679fa43ca8316da93975995a2 100644 (file)
@@ -24,7 +24,8 @@ CF_DECLS
 
 CF_KEYWORDS(RIP, INFINITY, METRIC, PORT, PERIOD, GARBAGETIME, PASSWORDS,
            MODE, BROADCAST, QUIET, NOLISTEN, VERSION1, 
-           AUTHENTICATION, NONE, PLAINTEXT, MD5)
+           AUTHENTICATION, NONE, PLAINTEXT, MD5,
+           HONOUR, NEVER, NEIGHBOUR, ALWAYS)
 
 %type <i> rip_mode rip_auth
 
@@ -47,6 +48,9 @@ RIP_CFG:
  | RIP_CFG GARBAGETIME expr ';' { RIP_CFG->garbage_time = $3; }
  | RIP_CFG AUTHENTICATION rip_auth ';' {RIP_CFG->authtype = $3; }
  | RIP_CFG PASSWORDS '{' password_list '}' {RIP_CFG->passwords = $4; }
+ | RIP_CFG HONOUR ALWAYS ';'    { RIP_CFG->honour = HO_ALWAYS; }
+ | RIP_CFG HONOUR NEIGHBOUR ';'    { RIP_CFG->honour = HO_NEIGHBOUR; }
+ | RIP_CFG HONOUR NEVER ';'    { RIP_CFG->honour = HO_NEVER; }
  | RIP_CFG rip_iface_list ';'
  ;
 
index a2457b79be84af5638d20472d68873f48417b348..ef98a78a9e034e3b4a82e2fd59b4608b5f6f244a 100644 (file)
@@ -96,7 +96,7 @@ rip_tx( sock *s )
       ipa_hton( packet->block[i].netmask );
       ipa_hton( packet->block[i].nexthop );
 
-      if (i++ == 25) {
+      if (i++ == ((P_CF->authtype == AT_MD5) ? PACKET_MD5_MAX : PACKET_MAX)) {
        FIB_ITERATE_PUT(&c->iter, z);
        goto break_loop;
       }
@@ -263,8 +263,15 @@ rip_process_packet( struct proto *p, struct rip_packet *packet, int num, ip_addr
 
   switch( packet->heading.command ) {
   case RIPCMD_REQUEST: DBG( "Asked to send my routing table\n" ); 
-    /* 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 */
-         rip_sendto( p, whotoldme, port, NULL ); /* no broadcast */
+         if (P_CF->honour == HO_NEVER) {
+           log( L_WARN "They asked me to send routing table, but I was told not to do it\n" );
+           return 0;
+         }
+         if ((P_CF->honour == HO_NEIGHBOUR) && (!neigh_find( p, &whotoldme, 0 ))) {
+           log( L_WARN "They asked me to send routing table, but he is not my neighbour\n" );
+           return 0;
+         }
+         rip_sendto( p, whotoldme, port, HEAD(P->interfaces) ); /* no broadcast */
           break;
   case RIPCMD_RESPONSE: DBG( "*** Rtable from %I\n", whotoldme ); 
           if (port != P_CF->port) {
@@ -281,8 +288,6 @@ rip_process_packet( struct proto *p, struct rip_packet *packet, int num, ip_addr
            return 0;
          }
 
-         /* FIXME: Should check if it is not my own packet */
-
           for (i=0; i<num; i++) {
            struct rip_block *block = &packet->block[i];
            if (block->family == 0xffff)
@@ -487,7 +492,10 @@ new_iface(struct proto *p, struct iface *new, unsigned long flags, struct iface_
   rif->sock->err_hook = rip_tx_err;
   rif->sock->daddr = IPA_NONE;
   rif->sock->dport = P_CF->port;
-  rif->sock->ttl = 1; /* FIXME: care must be taken not to send requested responses from this socket */
+  if (new)
+    rif->sock->ttl = 1;
+  else
+    rif->sock->ttl = 30;
   rif->sock->tos = IP_PREC_INTERNET_CONTROL;
 
   if (flags & IF_BROADCAST)
@@ -504,8 +512,8 @@ new_iface(struct proto *p, struct iface *new, unsigned long flags, struct iface_
   } else
     if (!(rif->patt->mode & IM_NOLISTEN))
       if (sk_open(rif->sock)<0) {
-       log( L_WARN "RIP/%s: could not listen on %s", P_NAME, rif->iface ? rif->iface->name : "(dummy)" );
-       /* FIXME: Don't try to transmit into this one */
+       log( L_ERR "RIP/%s: could not listen on %s", P_NAME, rif->iface ? rif->iface->name : "(dummy)" );
+       /* Don't try to transmit into this one? Well, why not? This should not happen, anyway :-) */
       }
 
   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" );
index 911d347340813bfd673544d78bd0e33b2c636a5b..4dcc396d248a3a5aad189d8e700f625c945f4df6 100644 (file)
@@ -8,6 +8,9 @@
 #define EA_RIP_TAG     EA_CODE(EAP_RIP, 0)
 #define EA_RIP_METRIC  EA_CODE(EAP_RIP, 1)
 
+#define PACKET_MAX 25
+#define PACKET_MD5_MAX 18      /* FIXME */
+
 struct rip_connection {
   node n;
 
@@ -115,6 +118,10 @@ struct rip_proto_config {
 #define AT_NONE 0
 #define AT_PLAINTEXT 2
 #define AT_MD5 3
+  int honour;
+#define HO_NEVER 0
+#define HO_NEIGHBOUR 1
+#define HO_ALWAYS 2
 };
 
 struct rip_proto {