Mensi updaty do ripu. Pridana passwd autentikace (netestovano).
This commit is contained in:
parent
f7103dfcfe
commit
1b16029c12
5 changed files with 115 additions and 44 deletions
|
@ -1,4 +1,4 @@
|
||||||
source=rip.c
|
source=rip.c auth.c
|
||||||
root-rel=../../
|
root-rel=../../
|
||||||
dir-name=proto/rip
|
dir-name=proto/rip
|
||||||
|
|
||||||
|
|
57
proto/rip/auth.c
Normal file
57
proto/rip/auth.c
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
/*
|
||||||
|
* Rest in pieces - RIP protocol
|
||||||
|
*
|
||||||
|
* Copyright (c) 1999 Pavel Machek <pavel@ucw.cz>
|
||||||
|
*
|
||||||
|
* Can be freely distributed and used under the terms of the GNU GPL.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define LOCAL_DEBUG
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "nest/bird.h"
|
||||||
|
#include "nest/iface.h"
|
||||||
|
#include "nest/protocol.h"
|
||||||
|
#include "nest/route.h"
|
||||||
|
#include "lib/socket.h"
|
||||||
|
#include "lib/resource.h"
|
||||||
|
#include "lib/lists.h"
|
||||||
|
#include "lib/timer.h"
|
||||||
|
|
||||||
|
#include "rip.h"
|
||||||
|
|
||||||
|
#define P ((struct rip_proto *) p)
|
||||||
|
#define P_CF ((struct rip_proto_config *)p->cf)
|
||||||
|
|
||||||
|
int
|
||||||
|
rip_incoming_authentication( struct proto *p, struct rip_block *block, struct rip_packet *packet, int num )
|
||||||
|
{
|
||||||
|
DBG( "Incoming authentication: " );
|
||||||
|
|
||||||
|
switch (block->tag) { /* Authentication type */
|
||||||
|
case AT_PLAINTEXT:
|
||||||
|
DBG( "Plaintext passwd" );
|
||||||
|
if (strncmp( (char *) (&block->network), P_CF->password, 16)) {
|
||||||
|
log( L_AUTH, "Passwd authentication failed!\n" );
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rip_outgoing_authentication( struct proto *p, struct rip_block *block, struct rip_packet *packet, int num )
|
||||||
|
{
|
||||||
|
DBG( "Outgoing authentication: " );
|
||||||
|
|
||||||
|
block->tag = P_CF->authtype;
|
||||||
|
switch (P_CF->authtype) {
|
||||||
|
case AT_PLAINTEXT:
|
||||||
|
strncpy( (char *) (&block->network), P_CF->password, 16);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,11 +7,7 @@
|
||||||
/*
|
/*
|
||||||
To add:
|
To add:
|
||||||
|
|
||||||
passive option (== do not send routing updates to this interface)
|
|
||||||
version1 switch
|
version1 switch
|
||||||
multicast off option for interface
|
|
||||||
|
|
||||||
interface mode broadcast/multicast/quiet
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -28,9 +24,11 @@ struct rip_patt *rip_get_iface(void);
|
||||||
|
|
||||||
CF_DECLS
|
CF_DECLS
|
||||||
|
|
||||||
CF_KEYWORDS(RIP, INFINITY, METRIC, PORT, PERIOD, GARBAGETIME, MODE, MULTICAST, BROADCAST, QUIET, DEFAULT)
|
CF_KEYWORDS(RIP, INFINITY, METRIC, PORT, PERIOD, GARBAGETIME, PASSWORD,
|
||||||
|
MODE, BROADCAST, QUIET, NOLISTEN, VERSION1,
|
||||||
|
AUTHENTICATION, NONE, PLAINTEXT, MD5)
|
||||||
|
|
||||||
%type <i> rip_mode
|
%type <i> rip_mode rip_auth
|
||||||
|
|
||||||
CF_GRAMMAR
|
CF_GRAMMAR
|
||||||
|
|
||||||
|
@ -49,15 +47,22 @@ RIP_CFG:
|
||||||
| RIP_CFG PORT expr ';' { RIP_CFG->port = $3; }
|
| RIP_CFG PORT expr ';' { RIP_CFG->port = $3; }
|
||||||
| RIP_CFG PERIOD expr ';' { RIP_CFG->period = $3; }
|
| RIP_CFG PERIOD expr ';' { RIP_CFG->period = $3; }
|
||||||
| RIP_CFG GARBAGETIME expr ';' { RIP_CFG->garbage_time = $3; }
|
| RIP_CFG GARBAGETIME expr ';' { RIP_CFG->garbage_time = $3; }
|
||||||
|
| RIP_CFG PASSWORD TEXT ';' { RIP_CFG->password = $3; }
|
||||||
|
| RIP_CFG AUTHENTICATION rip_auth ';' {RIP_CFG->authtype = $3; }
|
||||||
| RIP_CFG rip_iface_list ';'
|
| RIP_CFG rip_iface_list ';'
|
||||||
;
|
;
|
||||||
|
|
||||||
|
rip_auth:
|
||||||
|
PLAINTEXT { $$=AT_PLAINTEXT; }
|
||||||
|
| MD5 { $$=AT_MD5; }
|
||||||
|
| NONE { $$=AT_NONE; }
|
||||||
|
;
|
||||||
|
|
||||||
rip_mode:
|
rip_mode:
|
||||||
MULTICAST { $$=IM_MULTICAST; }
|
BROADCAST { $$|=IM_BROADCAST; }
|
||||||
| BROADCAST { $$=IM_BROADCAST; }
|
| QUIET { $$|=IM_QUIET; }
|
||||||
| QUIET { $$=IM_QUIET; }
|
| NOLISTEN { $$|=IM_NOLISTEN; }
|
||||||
| DEFAULT { $$=IM_DEFAULT; }
|
| VERSION1 { $$|=IM_VERSION1 | IM_BROADCAST; }
|
||||||
;
|
;
|
||||||
|
|
||||||
rip_iface_item:
|
rip_iface_item:
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* Rest in pieces - RIP protocol
|
* Rest in pieces - RIP protocol
|
||||||
*
|
*
|
||||||
* Copyright (c) 1998 Pavel Machek <pavel@ucw.cz>
|
* Copyright (c) 1998, 1999 Pavel Machek <pavel@ucw.cz>
|
||||||
*
|
*
|
||||||
* Can be freely distributed and used under the terms of the GNU GPL.
|
* Can be freely distributed and used under the terms of the GNU GPL.
|
||||||
*/
|
*/
|
||||||
|
@ -75,7 +75,7 @@ rip_tx( sock *s )
|
||||||
packet->heading.version = RIP_V2;
|
packet->heading.version = RIP_V2;
|
||||||
packet->heading.unused = 0;
|
packet->heading.unused = 0;
|
||||||
|
|
||||||
i = 0;
|
i = !!P_CF->authtype;
|
||||||
FIB_ITERATE_START(&P->rtable, &c->iter, z) {
|
FIB_ITERATE_START(&P->rtable, &c->iter, z) {
|
||||||
struct rip_entry *e = (struct rip_entry *) z;
|
struct rip_entry *e = (struct rip_entry *) z;
|
||||||
DBG( "." );
|
DBG( "." );
|
||||||
|
@ -103,6 +103,9 @@ rip_tx( sock *s )
|
||||||
|
|
||||||
break_loop:
|
break_loop:
|
||||||
|
|
||||||
|
if (P_CF->authtype)
|
||||||
|
rip_outgoing_authentication(p, &packet->block[0], packet, i);
|
||||||
|
|
||||||
DBG( ", sending %d blocks, ", i );
|
DBG( ", sending %d blocks, ", i );
|
||||||
|
|
||||||
if (ipa_nonzero(c->daddr))
|
if (ipa_nonzero(c->daddr))
|
||||||
|
@ -170,13 +173,6 @@ find_interface(struct proto *p, struct iface *what)
|
||||||
* Input processing
|
* Input processing
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int
|
|
||||||
process_authentication( struct proto *p, struct rip_block *block )
|
|
||||||
{
|
|
||||||
/* FIXME: Should do md5 authentication */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Let main routing table know about our new entry */
|
/* Let main routing table know about our new entry */
|
||||||
static void
|
static void
|
||||||
advertise_entry( struct proto *p, struct rip_block *b, ip_addr whotoldme )
|
advertise_entry( struct proto *p, struct rip_block *b, ip_addr whotoldme )
|
||||||
|
@ -289,7 +285,7 @@ rip_process_packet( struct proto *p, struct rip_packet *packet, int num, ip_addr
|
||||||
struct rip_block *block = &packet->block[i];
|
struct rip_block *block = &packet->block[i];
|
||||||
if (block->family == 0xffff)
|
if (block->family == 0xffff)
|
||||||
if (!i) {
|
if (!i) {
|
||||||
if (process_authentication(p, block))
|
if (rip_incoming_authentication(p, block, packet, num))
|
||||||
BAD( "Authentication failed" );
|
BAD( "Authentication failed" );
|
||||||
} else BAD( "Authentication is not the first!" );
|
} else BAD( "Authentication is not the first!" );
|
||||||
ipa_ntoh( block->network );
|
ipa_ntoh( block->network );
|
||||||
|
@ -372,7 +368,7 @@ rip_timer(timer *t)
|
||||||
struct iface *iface = rif->iface;
|
struct iface *iface = rif->iface;
|
||||||
|
|
||||||
if (!iface) continue;
|
if (!iface) continue;
|
||||||
if (rif->patt->mode == IM_QUIET) continue;
|
if (rif->patt->mode & IM_QUIET) continue;
|
||||||
if (!(iface->flags & IF_UP)) continue;
|
if (!(iface->flags & IF_UP)) continue;
|
||||||
if (iface->flags & (IF_IGNORE | IF_LOOPBACK)) continue;
|
if (iface->flags & (IF_IGNORE | IF_LOOPBACK)) continue;
|
||||||
|
|
||||||
|
@ -400,7 +396,7 @@ rip_start(struct proto *p)
|
||||||
P->timer->recurrent = P_CF->period;
|
P->timer->recurrent = P_CF->period;
|
||||||
P->timer->hook = rip_timer;
|
P->timer->hook = rip_timer;
|
||||||
tm_start( P->timer, 5 );
|
tm_start( P->timer, 5 );
|
||||||
rif = new_iface(p, NULL, 0); /* Initialize dummy interface */
|
rif = new_iface(p, NULL, 0, NULL); /* Initialize dummy interface */
|
||||||
add_head( &P->interfaces, NODE rif );
|
add_head( &P->interfaces, NODE rif );
|
||||||
CHK_MAGIC;
|
CHK_MAGIC;
|
||||||
|
|
||||||
|
@ -460,19 +456,20 @@ kill_iface(struct proto *p, struct rip_interface *i)
|
||||||
* new maybe null if we are creating initial send socket
|
* new maybe null if we are creating initial send socket
|
||||||
*/
|
*/
|
||||||
struct rip_interface *
|
struct rip_interface *
|
||||||
new_iface(struct proto *p, struct iface *new, unsigned long flags)
|
new_iface(struct proto *p, struct iface *new, unsigned long flags, struct iface_patt *patt )
|
||||||
{
|
{
|
||||||
struct rip_interface *rif;
|
struct rip_interface *rif;
|
||||||
int want_multicast;
|
int want_multicast = 0;
|
||||||
|
|
||||||
rif = mb_alloc(p->pool, sizeof( struct rip_interface ));
|
rif = mb_alloc(p->pool, sizeof( struct rip_interface ));
|
||||||
rif->iface = new;
|
rif->iface = new;
|
||||||
rif->proto = p;
|
rif->proto = p;
|
||||||
rif->busy = NULL;
|
rif->busy = NULL;
|
||||||
|
rif->patt = (struct rip_patt *) patt;
|
||||||
|
|
||||||
want_multicast = 0 && (flags & IF_MULTICAST);
|
if (rif->patt)
|
||||||
/* FIXME: should have config option to disable this one */
|
want_multicast = (!(rif->patt->mode & IM_BROADCAST)) && (flags & IF_MULTICAST);
|
||||||
/* FIXME: lookup multicasts over unnumbered links */
|
/* lookup multicasts over unnumbered links - no: rip is not defined over unnumbered links */
|
||||||
|
|
||||||
rif->sock = sk_new( p->pool );
|
rif->sock = sk_new( p->pool );
|
||||||
rif->sock->type = want_multicast?SK_UDP_MC:SK_UDP;
|
rif->sock->type = want_multicast?SK_UDP_MC:SK_UDP;
|
||||||
|
@ -489,19 +486,18 @@ new_iface(struct proto *p, struct iface *new, unsigned long flags)
|
||||||
rif->sock->ttl = 1; /* FIXME: care must be taken not to send requested responses from this socket */
|
rif->sock->ttl = 1; /* FIXME: care must be taken not to send requested responses from this socket */
|
||||||
|
|
||||||
if (want_multicast)
|
if (want_multicast)
|
||||||
rif->sock->daddr = ipa_from_u32(0x7f000001); /* FIXME: must lookup address in rfc's */
|
rif->sock->daddr = ipa_from_u32(0xe0000009);
|
||||||
if (flags & IF_BROADCAST)
|
if (flags & IF_BROADCAST)
|
||||||
rif->sock->daddr = new->addr->brd;
|
rif->sock->daddr = new->addr->brd;
|
||||||
if (flags & IF_UNNUMBERED)
|
if (flags & IF_UNNUMBERED) /* Hmm, rip is not defined over unnumbered links */
|
||||||
rif->sock->daddr = new->addr->opposite;
|
rif->sock->daddr = new->addr->opposite;
|
||||||
|
|
||||||
if (!ipa_nonzero(rif->sock->daddr))
|
if (!ipa_nonzero(rif->sock->daddr)) {
|
||||||
log( L_WARN "RIP: interface %s is too strange for me", rif->iface ? rif->iface->name : "(dummy)" );
|
log( L_WARN "RIP/%s: interface %s is too strange for me", P_NAME, rif->iface ? rif->iface->name : "(dummy)" );
|
||||||
/* FIXME: Should ignore the interface instead of blindly trying to bind on it */
|
} else
|
||||||
|
if (!(rif->patt->mode & IM_NOLISTEN))
|
||||||
if (sk_open(rif->sock)<0)
|
if (sk_open(rif->sock)<0)
|
||||||
die( "RIP/%s: could not listen on %s", P_NAME, rif->iface ? rif->iface->name : "(dummy)" );
|
log( L_WARN "RIP/%s: could not listen on %s", P_NAME, rif->iface ? rif->iface->name : "(dummy)" );
|
||||||
/* FIXME: Should not be fatal, since the interface might have gone */
|
|
||||||
|
|
||||||
return rif;
|
return rif;
|
||||||
}
|
}
|
||||||
|
@ -526,8 +522,7 @@ rip_if_notify(struct proto *p, unsigned c, struct iface *iface)
|
||||||
|
|
||||||
if (!k) return; /* We are not interested in this interface */
|
if (!k) return; /* We are not interested in this interface */
|
||||||
DBG("adding interface %s\n", iface->name );
|
DBG("adding interface %s\n", iface->name );
|
||||||
rif = new_iface(p, iface, iface->flags);
|
rif = new_iface(p, iface, iface->flags, k);
|
||||||
rif->patt = (void *) k;
|
|
||||||
add_head( &P->interfaces, NODE rif );
|
add_head( &P->interfaces, NODE rif );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -608,6 +603,8 @@ rip_init_config(struct rip_proto_config *c)
|
||||||
c->port = 520;
|
c->port = 520;
|
||||||
c->period = 30;
|
c->period = 30;
|
||||||
c->garbage_time = 120+180;
|
c->garbage_time = 120+180;
|
||||||
|
c->password = "PASSWORD";
|
||||||
|
c->authtype = AT_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -69,10 +69,11 @@ struct rip_interface {
|
||||||
|
|
||||||
int metric; /* User configurable data */
|
int metric; /* User configurable data */
|
||||||
int mode;
|
int mode;
|
||||||
#define IM_DEFAULT 0
|
#define IM_MULTICAST 1
|
||||||
#define IM_QUIET 1
|
#define IM_BROADCAST 2
|
||||||
#define IM_MULTICAST 2
|
#define IM_QUIET 4
|
||||||
#define IM_BROADCAST 3
|
#define IM_NOLISTEN 8
|
||||||
|
#define IM_VERSION1 16
|
||||||
};
|
};
|
||||||
|
|
||||||
struct rip_patt {
|
struct rip_patt {
|
||||||
|
@ -90,6 +91,12 @@ struct rip_proto_config {
|
||||||
int port;
|
int port;
|
||||||
int period;
|
int period;
|
||||||
int garbage_time;
|
int garbage_time;
|
||||||
|
|
||||||
|
char *password;
|
||||||
|
int authtype;
|
||||||
|
#define AT_NONE 0
|
||||||
|
#define AT_PLAINTEXT 2
|
||||||
|
#define AT_MD5 1234 /* FIXME: get a real number for this one */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct rip_proto {
|
struct rip_proto {
|
||||||
|
@ -108,4 +115,9 @@ struct rip_proto {
|
||||||
|
|
||||||
void rip_init_instance(struct proto *p);
|
void rip_init_instance(struct proto *p);
|
||||||
void rip_init_config(struct rip_proto_config *c);
|
void rip_init_config(struct rip_proto_config *c);
|
||||||
struct rip_interface *new_iface(struct proto *p, struct iface *new, unsigned long flags);
|
struct rip_interface *new_iface(struct proto *p, struct iface *new, unsigned long flags, struct iface_patt *patt);
|
||||||
|
|
||||||
|
/* Authentication functions */
|
||||||
|
|
||||||
|
int rip_incoming_authentication( struct proto *p, struct rip_block *block, struct rip_packet *packet, int num );
|
||||||
|
void rip_outgoing_authentication( struct proto *p, struct rip_block *block, struct rip_packet *packet, int num );
|
||||||
|
|
Loading…
Reference in a new issue