Few fixme's fixed in rip (will not crash any more on request for
sending routing table - hopefully). Next few steps in md5 authentication (not yet complete).
This commit is contained in:
parent
f651941402
commit
bce8a34b12
5 changed files with 70 additions and 19 deletions
|
@ -58,6 +58,7 @@ protocol rip MyRIP_test {
|
||||||
garbagetime 30;
|
garbagetime 30;
|
||||||
interface "*";
|
interface "*";
|
||||||
export filter testf;
|
export filter testf;
|
||||||
|
honour neighbour;
|
||||||
passwords { password "ahoj" from 0 to 10;
|
passwords { password "ahoj" from 0 to 10;
|
||||||
password "nazdar" from 10 to 20;
|
password "nazdar" from 10 to 20;
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,6 @@ int
|
||||||
rip_incoming_authentication( struct proto *p, struct rip_block_auth *block, struct rip_packet *packet, int num )
|
rip_incoming_authentication( struct proto *p, struct rip_block_auth *block, struct rip_packet *packet, int num )
|
||||||
{
|
{
|
||||||
DBG( "Incoming authentication: " );
|
DBG( "Incoming authentication: " );
|
||||||
|
|
||||||
switch (block->authtype) { /* Authentication type */
|
switch (block->authtype) { /* Authentication type */
|
||||||
case AT_PLAINTEXT:
|
case AT_PLAINTEXT:
|
||||||
DBG( "Plaintext passwd" );
|
DBG( "Plaintext passwd" );
|
||||||
|
@ -50,10 +49,13 @@ rip_incoming_authentication( struct proto *p, struct rip_block_auth *block, stru
|
||||||
struct password_item *head;
|
struct password_item *head;
|
||||||
struct rip_md5_tail *tail;
|
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)));
|
tail = (struct rip_md5_tail *) ((char *) packet + (block->packetlen - sizeof(struct rip_block_auth)));
|
||||||
|
|
||||||
head = P_CF->passwords;
|
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) {
|
if (head->id == block->keyid) {
|
||||||
struct MD5Context ctxt;
|
struct MD5Context ctxt;
|
||||||
char md5sum_packet[16];
|
char md5sum_packet[16];
|
||||||
|
@ -81,16 +83,45 @@ rip_incoming_authentication( struct proto *p, struct rip_block_auth *block, stru
|
||||||
void
|
void
|
||||||
rip_outgoing_authentication( struct proto *p, struct rip_block_auth *block, struct rip_packet *packet, int num )
|
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: " );
|
DBG( "Outgoing authentication: " );
|
||||||
|
|
||||||
|
if (!passwd) {
|
||||||
|
log( L_ERR "no suitable password found for authentication\n" );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
block->authtype = P_CF->authtype;
|
block->authtype = P_CF->authtype;
|
||||||
|
block->mustbeFFFF = 0xffff;
|
||||||
switch (P_CF->authtype) {
|
switch (P_CF->authtype) {
|
||||||
case AT_PLAINTEXT:
|
case AT_PLAINTEXT:
|
||||||
if (!P_CF->passwords) {
|
password_strncpy( (char *) (&block->packetlen), passwd->password, 16);
|
||||||
log( L_ERR "no passwords set and password authentication requested\n" );
|
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;
|
return;
|
||||||
}
|
}
|
||||||
password_strncpy( (char *) (&block->packetlen), P_CF->passwords->password, 16);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,8 @@ CF_DECLS
|
||||||
|
|
||||||
CF_KEYWORDS(RIP, INFINITY, METRIC, PORT, PERIOD, GARBAGETIME, PASSWORDS,
|
CF_KEYWORDS(RIP, INFINITY, METRIC, PORT, PERIOD, GARBAGETIME, PASSWORDS,
|
||||||
MODE, BROADCAST, QUIET, NOLISTEN, VERSION1,
|
MODE, BROADCAST, QUIET, NOLISTEN, VERSION1,
|
||||||
AUTHENTICATION, NONE, PLAINTEXT, MD5)
|
AUTHENTICATION, NONE, PLAINTEXT, MD5,
|
||||||
|
HONOUR, NEVER, NEIGHBOUR, ALWAYS)
|
||||||
|
|
||||||
%type <i> rip_mode rip_auth
|
%type <i> rip_mode rip_auth
|
||||||
|
|
||||||
|
@ -47,6 +48,9 @@ RIP_CFG:
|
||||||
| RIP_CFG GARBAGETIME expr ';' { RIP_CFG->garbage_time = $3; }
|
| RIP_CFG GARBAGETIME expr ';' { RIP_CFG->garbage_time = $3; }
|
||||||
| RIP_CFG AUTHENTICATION rip_auth ';' {RIP_CFG->authtype = $3; }
|
| RIP_CFG AUTHENTICATION rip_auth ';' {RIP_CFG->authtype = $3; }
|
||||||
| RIP_CFG PASSWORDS '{' password_list '}' {RIP_CFG->passwords = $4; }
|
| 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 ';'
|
| RIP_CFG rip_iface_list ';'
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
|
@ -96,7 +96,7 @@ rip_tx( sock *s )
|
||||||
ipa_hton( packet->block[i].netmask );
|
ipa_hton( packet->block[i].netmask );
|
||||||
ipa_hton( packet->block[i].nexthop );
|
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);
|
FIB_ITERATE_PUT(&c->iter, z);
|
||||||
goto break_loop;
|
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 ) {
|
switch( packet->heading.command ) {
|
||||||
case RIPCMD_REQUEST: DBG( "Asked to send my routing table\n" );
|
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 */
|
if (P_CF->honour == HO_NEVER) {
|
||||||
rip_sendto( p, whotoldme, port, NULL ); /* no broadcast */
|
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;
|
break;
|
||||||
case RIPCMD_RESPONSE: DBG( "*** Rtable from %I\n", whotoldme );
|
case RIPCMD_RESPONSE: DBG( "*** Rtable from %I\n", whotoldme );
|
||||||
if (port != P_CF->port) {
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: Should check if it is not my own packet */
|
|
||||||
|
|
||||||
for (i=0; i<num; i++) {
|
for (i=0; i<num; i++) {
|
||||||
struct rip_block *block = &packet->block[i];
|
struct rip_block *block = &packet->block[i];
|
||||||
if (block->family == 0xffff)
|
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->err_hook = rip_tx_err;
|
||||||
rif->sock->daddr = IPA_NONE;
|
rif->sock->daddr = IPA_NONE;
|
||||||
rif->sock->dport = P_CF->port;
|
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;
|
rif->sock->tos = IP_PREC_INTERNET_CONTROL;
|
||||||
|
|
||||||
if (flags & IF_BROADCAST)
|
if (flags & IF_BROADCAST)
|
||||||
|
@ -504,8 +512,8 @@ new_iface(struct proto *p, struct iface *new, unsigned long flags, struct iface_
|
||||||
} else
|
} else
|
||||||
if (!(rif->patt->mode & IM_NOLISTEN))
|
if (!(rif->patt->mode & IM_NOLISTEN))
|
||||||
if (sk_open(rif->sock)<0) {
|
if (sk_open(rif->sock)<0) {
|
||||||
log( L_WARN "RIP/%s: could not listen on %s", P_NAME, rif->iface ? rif->iface->name : "(dummy)" );
|
log( L_ERR "RIP/%s: could not listen on %s", P_NAME, rif->iface ? rif->iface->name : "(dummy)" );
|
||||||
/* FIXME: Don't try to transmit into this one */
|
/* 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" );
|
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" );
|
||||||
|
|
|
@ -8,6 +8,9 @@
|
||||||
#define EA_RIP_TAG EA_CODE(EAP_RIP, 0)
|
#define EA_RIP_TAG EA_CODE(EAP_RIP, 0)
|
||||||
#define EA_RIP_METRIC EA_CODE(EAP_RIP, 1)
|
#define EA_RIP_METRIC EA_CODE(EAP_RIP, 1)
|
||||||
|
|
||||||
|
#define PACKET_MAX 25
|
||||||
|
#define PACKET_MD5_MAX 18 /* FIXME */
|
||||||
|
|
||||||
struct rip_connection {
|
struct rip_connection {
|
||||||
node n;
|
node n;
|
||||||
|
|
||||||
|
@ -115,6 +118,10 @@ struct rip_proto_config {
|
||||||
#define AT_NONE 0
|
#define AT_NONE 0
|
||||||
#define AT_PLAINTEXT 2
|
#define AT_PLAINTEXT 2
|
||||||
#define AT_MD5 3
|
#define AT_MD5 3
|
||||||
|
int honour;
|
||||||
|
#define HO_NEVER 0
|
||||||
|
#define HO_NEIGHBOUR 1
|
||||||
|
#define HO_ALWAYS 2
|
||||||
};
|
};
|
||||||
|
|
||||||
struct rip_proto {
|
struct rip_proto {
|
||||||
|
|
Loading…
Reference in a new issue