Home | History | Annotate | Download | only in snoop
      1     0  stevel /*
      2     0  stevel  * CDDL HEADER START
      3     0  stevel  *
      4     0  stevel  * The contents of this file are subject to the terms of the
      5  1676     jpk  * Common Development and Distribution License (the "License").
      6  1676     jpk  * You may not use this file except in compliance with the License.
      7     0  stevel  *
      8     0  stevel  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9     0  stevel  * or http://www.opensolaris.org/os/licensing.
     10     0  stevel  * See the License for the specific language governing permissions
     11     0  stevel  * and limitations under the License.
     12     0  stevel  *
     13     0  stevel  * When distributing Covered Code, include this CDDL HEADER in each
     14     0  stevel  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15     0  stevel  * If applicable, add the following below this CDDL HEADER, with the
     16     0  stevel  * fields enclosed by brackets "[]" replaced with your own identifying
     17     0  stevel  * information: Portions Copyright [yyyy] [name of copyright owner]
     18     0  stevel  *
     19     0  stevel  * CDDL HEADER END
     20     0  stevel  */
     21     0  stevel /*
     22  1676     jpk  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
     23     0  stevel  * Use is subject to license terms.
     24     0  stevel  */
     25     0  stevel 
     26     0  stevel #pragma ident	"%Z%%M%	%I%	%E% SMI"
     27     0  stevel 
     28     0  stevel #include <stdio.h>
     29     0  stevel #include <string.h>
     30     0  stevel #include <strings.h>
     31     0  stevel #include <fcntl.h>
     32     0  stevel #include <sys/types.h>
     33     0  stevel #include <sys/socket.h>
     34     0  stevel #include <netinet/in.h>
     35     0  stevel #include <arpa/inet.h>
     36     0  stevel #define	RIPVERSION	RIPv2
     37     0  stevel #include <protocols/routed.h>
     38     0  stevel #include "snoop.h"
     39     0  stevel 
     40  1676     jpk static const char *show_cmd(int);
     41  1676     jpk static int get_numtokens(unsigned int);
     42  1676     jpk static const struct rip_sec_entry *rip_next_sec_entry(
     43  1676     jpk     const struct rip_sec_entry *, int);
     44     0  stevel 
     45     0  stevel int
     46     0  stevel interpret_rip(int flags, struct rip *rip, int fraglen)
     47     0  stevel {
     48     0  stevel 	const struct netinfo *nip;
     49     0  stevel 	const struct entryinfo *ep;
     50     0  stevel 	const struct netauth *nap;
     51  1676     jpk 	const struct rip_sec_entry *rsep, *rsn;
     52  1676     jpk 	const struct rip_emetric *rep;
     53  1676     jpk 	const uint32_t *tokp;
     54     0  stevel 	int len, count;
     55     0  stevel 	const char *cmdstr, *auth;
     56     0  stevel 	struct in_addr dst;
     57     0  stevel 	uint32_t mval;
     58     0  stevel 	const struct sockaddr_in *sin;
     59     0  stevel 	/* Room for IP destination + "/" + IP mask */
     60     0  stevel 	char addrstr[15+1+15+1];
     61     0  stevel 	/* Room for "RIPv" + uint8_t as %d */
     62     0  stevel 	char ripvers[4+3+1];
     63     0  stevel 
     64     0  stevel 	/* RIP header is 4 octets long */
     65     0  stevel 	if ((len = fraglen - 4) < 0)
     66     0  stevel 		return (0);
     67     0  stevel 
     68     0  stevel 	if (flags & F_SUM) {
     69     0  stevel 		switch (rip->rip_cmd) {
     70     0  stevel 		case RIPCMD_REQUEST:	cmdstr = "C";		break;
     71     0  stevel 		case RIPCMD_RESPONSE:	cmdstr = "R";		break;
     72     0  stevel 		case RIPCMD_TRACEON:	cmdstr = "Traceon";	break;
     73     0  stevel 		case RIPCMD_TRACEOFF:	cmdstr = "Traceoff";	break;
     74     0  stevel 		case RIPCMD_POLL:	cmdstr = "Poll";	break;
     75     0  stevel 		case RIPCMD_POLLENTRY:	cmdstr = "Poll entry";	break;
     76  1676     jpk 		case RIPCMD_SEC_RESPONSE: cmdstr = "R - SEC";	break;
     77  1676     jpk 		case RIPCMD_SEC_T_RESPONSE: cmdstr = "R - SEC_T"; break;
     78     0  stevel 		default: cmdstr = "?"; break;
     79     0  stevel 		}
     80     0  stevel 
     81     0  stevel 		if (rip->rip_vers == RIPv1)
     82     0  stevel 			(void) strlcpy(ripvers, "RIP", sizeof (ripvers));
     83     0  stevel 		else
     84     0  stevel 			(void) snprintf(ripvers, sizeof (ripvers), "RIPv%d",
     85     0  stevel 			    rip->rip_vers);
     86     0  stevel 
     87     0  stevel 		switch (rip->rip_cmd) {
     88     0  stevel 		case RIPCMD_REQUEST:
     89     0  stevel 		case RIPCMD_RESPONSE:
     90     0  stevel 		case RIPCMD_POLL:
     91     0  stevel 			nip = rip->rip_nets;
     92     0  stevel 			auth = "";
     93     0  stevel 			if (len >= sizeof (*nip) &&
     94     0  stevel 			    nip->n_family == RIP_AF_AUTH) {
     95     0  stevel 				nap = (struct netauth *)nip;
     96     0  stevel 				len -= sizeof (*nip);
     97     0  stevel 				if (nap->a_type == RIP_AUTH_MD5 &&
     98     0  stevel 				    len >= ntohs(nap->au.a_md5.md5_auth_len))
     99     0  stevel 					len -= ntohs(nap->au.a_md5.
    100     0  stevel 					    md5_auth_len);
    101     0  stevel 				auth = " +Auth";
    102     0  stevel 			}
    103     0  stevel 			count = len / sizeof (*nip);
    104     0  stevel 			len %= sizeof (*nip);
    105     0  stevel 			(void) snprintf(get_sum_line(), MAXLINE,
    106     0  stevel 			    "%s %s (%d destinations%s%s)", ripvers, cmdstr,
    107     0  stevel 			    count, (len != 0 ? "?" : ""), auth);
    108     0  stevel 			break;
    109     0  stevel 
    110     0  stevel 		case RIPCMD_TRACEON:
    111     0  stevel 		case RIPCMD_TRACEOFF:
    112     0  stevel 			(void) snprintf(get_sum_line(), MAXLINE,
    113     0  stevel 			    "%s %s File=\"%.*s\"", ripvers, cmdstr, len,
    114     0  stevel 			    rip->rip_tracefile);
    115     0  stevel 			len = 0;
    116     0  stevel 			break;
    117     0  stevel 
    118  1676     jpk 		case RIPCMD_SEC_RESPONSE:
    119  1676     jpk 		case RIPCMD_SEC_T_RESPONSE:
    120  1676     jpk 			if (len < sizeof (rip->rip_tsol.rip_generation))
    121  1676     jpk 				break;
    122  1676     jpk 			len -= sizeof (rip->rip_tsol.rip_generation);
    123  1676     jpk 			count = 0;
    124  1676     jpk 			rsep = rip->rip_tsol.rip_sec_entry;
    125  1676     jpk 			while (len > 0) {
    126  1676     jpk 				rsn = rip_next_sec_entry(rsep, len);
    127  1676     jpk 				if (rsn == NULL)
    128  1676     jpk 					break;
    129  1676     jpk 				len -= (const char *)rsn - (const char *)rsep;
    130  1676     jpk 				rsep = rsn;
    131  1676     jpk 				count++;
    132  1676     jpk 			}
    133  1676     jpk 			(void) snprintf(get_sum_line(), MAXLINE,
    134  1676     jpk 			    "%s %s (%d destinations%s)", ripvers, cmdstr,
    135  1676     jpk 			    count, (len != 0 ? "?" : ""));
    136  1676     jpk 			break;
    137  1676     jpk 
    138     0  stevel 		default:
    139     0  stevel 			(void) snprintf(get_sum_line(), MAXLINE,
    140     0  stevel 			    "%s %d (%s)", ripvers, rip->rip_cmd, cmdstr);
    141     0  stevel 			len = 0;
    142     0  stevel 			break;
    143     0  stevel 		}
    144     0  stevel 	}
    145     0  stevel 
    146     0  stevel 	if (flags & F_DTAIL) {
    147     0  stevel 
    148     0  stevel 		len = fraglen - 4;
    149     0  stevel 		show_header("RIP:  ", "Routing Information Protocol", fraglen);
    150     0  stevel 		show_space();
    151  1676     jpk 		(void) snprintf(get_line(0, 0), get_line_remain(),
    152  1676     jpk 		    "Opcode = %d (%s)", rip->rip_cmd,
    153  1676     jpk 		    show_cmd(rip->rip_cmd));
    154  1676     jpk 		(void) snprintf(get_line(0, 0), get_line_remain(),
    155  1676     jpk 		    "Version = %d", rip->rip_vers);
    156     0  stevel 
    157     0  stevel 		switch (rip->rip_cmd) {
    158     0  stevel 		case RIPCMD_REQUEST:
    159     0  stevel 		case RIPCMD_RESPONSE:
    160     0  stevel 		case RIPCMD_POLL:
    161     0  stevel 			show_space();
    162     0  stevel 			(void) snprintf(get_line(0, 0), get_line_remain(),
    163     0  stevel 			    "Destination                     Next Hop        "
    164     0  stevel 			    "Tag    Metric");
    165     0  stevel 			for (nip = rip->rip_nets; len >= sizeof (*nip); nip++,
    166     0  stevel 			    len -= sizeof (*nip)) {
    167     0  stevel 				if (nip->n_family == RIP_AF_AUTH) {
    168     0  stevel 					nap = (const struct netauth *)nip;
    169     0  stevel 					if (nap->a_type == RIP_AUTH_NONE) {
    170     0  stevel 						(void) snprintf(get_line
    171     0  stevel 						    ((char *)nip - dlc_header,
    172     0  stevel 							sizeof (*nip)),
    173     0  stevel 						    get_line_remain(),
    174     0  stevel 						    " *** Auth None");
    175     0  stevel 					} else if (nap->a_type == RIP_AUTH_PW) {
    176     0  stevel 						(void) snprintf(get_line
    177     0  stevel 						    ((char *)nip - dlc_header,
    178     0  stevel 							sizeof (*nip)),
    179     0  stevel 						    get_line_remain(),
    180     0  stevel 						    " *** Auth PW \"%.*s\"",
    181     0  stevel 						    RIP_AUTH_PW_LEN,
    182     0  stevel 						    nap->au.au_pw);
    183     0  stevel 					} else if (nap->a_type ==
    184     0  stevel 					    RIP_AUTH_MD5) {
    185  1676     jpk 						(void) snprintf(get_line(0, 0),
    186     0  stevel 						    get_line_remain(),
    187     0  stevel 						    " *** Auth MD5 pkt len %d, "
    188     0  stevel 						    "keyid %d, sequence %08lX, "
    189     0  stevel 						    "authlen %d",
    190     0  stevel 						    ntohs(nap->au.a_md5.
    191     0  stevel 							md5_pkt_len),
    192     0  stevel 						    nap->au.a_md5.md5_keyid,
    193  1676     jpk 						    (long)ntohl(nap->au.a_md5.
    194     0  stevel 							md5_seqno),
    195     0  stevel 						    ntohs(nap->au.a_md5.
    196     0  stevel 							md5_auth_len));
    197     0  stevel 						if (len - sizeof (*nip) >=
    198     0  stevel 						    ntohs(nap->au.a_md5.
    199     0  stevel 						    md5_auth_len))
    200     0  stevel 							len -= ntohs(nap->au.
    201     0  stevel 							    a_md5.md5_auth_len);
    202     0  stevel 						else
    203     0  stevel 							len = sizeof (*nip);
    204     0  stevel 					} else {
    205     0  stevel 						(void) snprintf(get_line
    206     0  stevel 						    ((char *)nip - dlc_header,
    207     0  stevel 							sizeof (*nip)),
    208     0  stevel 						    get_line_remain(),
    209     0  stevel 						    " *** Auth Type %d?",
    210     0  stevel 						    ntohs(nap->a_type));
    211     0  stevel 					}
    212     0  stevel 					continue;
    213     0  stevel 				}
    214     0  stevel 				if (nip->n_family == RIP_AF_UNSPEC &&
    215     0  stevel 				    rip->rip_cmd == RIPCMD_REQUEST) {
    216  1676     jpk 					(void) snprintf(get_line(0, 0),
    217     0  stevel 					    get_line_remain(),
    218     0  stevel 					    " *** All routes");
    219     0  stevel 					continue;
    220     0  stevel 				}
    221     0  stevel 				if (nip->n_family != RIP_AF_INET) {
    222  1676     jpk 					(void) snprintf(get_line(0, 0),
    223     0  stevel 					    get_line_remain(),
    224     0  stevel 					    " *** Address Family %d?",
    225     0  stevel 					    ntohs(nip->n_family));
    226     0  stevel 					continue;
    227     0  stevel 				}
    228     0  stevel 				if (nip->n_dst == htonl(RIP_DEFAULT)) {
    229     0  stevel 					(void) strcpy(addrstr, "default");
    230     0  stevel 				} else {
    231     0  stevel 					dst.s_addr = nip->n_dst;
    232     0  stevel 					(void) strlcpy(addrstr, inet_ntoa(dst),
    233     0  stevel 					    sizeof (addrstr));
    234     0  stevel 				}
    235     0  stevel 				if (nip->n_dst != htonl(RIP_DEFAULT) &&
    236     0  stevel 				    rip->rip_vers >= RIPv2) {
    237     0  stevel 					count = strlen(addrstr);
    238     0  stevel 					mval = ntohl(nip->n_mask);
    239     0  stevel 					/* LINTED */
    240     0  stevel 					if (mval == INADDR_ANY) {
    241     0  stevel 						/* No mask */;
    242     0  stevel 					} else if ((mval + (mval & -mval)) ==
    243     0  stevel 					    0) {
    244     0  stevel 						(void) snprintf(addrstr + count,
    245     0  stevel 						    sizeof (addrstr) - count,
    246     0  stevel 						    "/%d", 33 - ffs(mval));
    247     0  stevel 					} else {
    248     0  stevel 						dst.s_addr = nip->n_mask;
    249     0  stevel 						(void) snprintf(addrstr + count,
    250     0  stevel 						    sizeof (addrstr) - count,
    251     0  stevel 						    "/%s", inet_ntoa(dst));
    252     0  stevel 					}
    253     0  stevel 				}
    254     0  stevel 				dst.s_addr = nip->n_nhop;
    255     0  stevel 				mval = ntohl(nip->n_metric);
    256  1676     jpk 				(void) snprintf(get_line(0, 0),
    257     0  stevel 				    get_line_remain(),
    258     0  stevel 				    "%-31s %-15s %-6d %d%s",
    259     0  stevel 				    addrstr,
    260     0  stevel 				    dst.s_addr == htonl(INADDR_ANY) ?
    261     0  stevel 				    "--" : addrtoname(AF_INET, &dst),
    262     0  stevel 				    ntohs(nip->n_tag),
    263     0  stevel 				    mval,
    264     0  stevel 				    (mval == HOPCNT_INFINITY ?
    265     0  stevel 					" (not reachable)" : ""));
    266     0  stevel 			}
    267     0  stevel 			break;
    268     0  stevel 
    269     0  stevel 		case RIPCMD_POLLENTRY:
    270     0  stevel 			if (len < sizeof (*ep))
    271     0  stevel 				break;
    272     0  stevel 			len -= sizeof (*ep);
    273     0  stevel 			ep = (const struct entryinfo *)rip->rip_nets;
    274     0  stevel 			/* LINTED */
    275     0  stevel 			sin = (const struct sockaddr_in *)&ep->rtu_dst;
    276  1676     jpk 			(void) snprintf(get_line(0, 0), get_line_remain(),
    277     0  stevel 			    "Destination = %s %s",
    278     0  stevel 			    inet_ntoa(sin->sin_addr),
    279     0  stevel 			    addrtoname(AF_INET, (void *)&sin->sin_addr));
    280     0  stevel 			/* LINTED */
    281     0  stevel 			sin = (const struct sockaddr_in *)&ep->rtu_router;
    282  1676     jpk 			(void) snprintf(get_line(0, 0), get_line_remain(),
    283     0  stevel 			    "Router      = %s %s",
    284     0  stevel 			    inet_ntoa(sin->sin_addr),
    285     0  stevel 			    addrtoname(AF_INET, (void *)&sin->sin_addr));
    286  1676     jpk 			(void) snprintf(get_line(0, 0), get_line_remain(),
    287     0  stevel 			    "Flags = %4x", (unsigned)ep->rtu_flags);
    288  1676     jpk 			(void) snprintf(get_line(0, 0), get_line_remain(),
    289     0  stevel 			    "State = %d", ep->rtu_state);
    290  1676     jpk 			(void) snprintf(get_line(0, 0), get_line_remain(),
    291     0  stevel 			    "Timer = %d", ep->rtu_timer);
    292  1676     jpk 			(void) snprintf(get_line(0, 0), get_line_remain(),
    293     0  stevel 			    "Metric = %d", ep->rtu_metric);
    294  1676     jpk 			(void) snprintf(get_line(0, 0), get_line_remain(),
    295     0  stevel 			    "Int flags = %8x", ep->int_flags);
    296  1676     jpk 			(void) snprintf(get_line(0, 0), get_line_remain(),
    297     0  stevel 			    "Int name = \"%.*s\"", sizeof (ep->int_name),
    298     0  stevel 			    ep->int_name);
    299     0  stevel 			break;
    300     0  stevel 
    301  1676     jpk 		case RIPCMD_SEC_RESPONSE:
    302  1676     jpk 		case RIPCMD_SEC_T_RESPONSE:
    303  1676     jpk 			if (len < sizeof (rip->rip_tsol.rip_generation))
    304  1676     jpk 				break;
    305  1676     jpk 			len -= sizeof (rip->rip_tsol.rip_generation);
    306  1676     jpk 			show_space();
    307  1676     jpk 			(void) snprintf(get_line(0, 0), get_line_remain(),
    308  1676     jpk 			    "Generation = %u",
    309  1676     jpk 			    (unsigned)ntohl(rip->rip_tsol.rip_generation));
    310  1676     jpk 			rsep = rip->rip_tsol.rip_sec_entry;
    311  1676     jpk 			(void) snprintf(get_line(0, 0), get_line_remain(),
    312  1676     jpk 			    "Address         E-METRIC");
    313  1676     jpk 			rsep = rip->rip_tsol.rip_sec_entry;
    314  1676     jpk 			while (len > 0) {
    315  1676     jpk 				char *cp;
    316  1676     jpk 				int blen, num;
    317  1676     jpk 
    318  1676     jpk 				rsn = rip_next_sec_entry(rsep, len);
    319  1676     jpk 				if (rsn == NULL)
    320  1676     jpk 					break;
    321  1676     jpk 				dst.s_addr = rsep->rip_dst;
    322  1676     jpk 				cp = get_line(0, 0);
    323  1676     jpk 				blen = get_line_remain();
    324  1676     jpk 				(void) snprintf(cp, blen, "%-16s ",
    325  1676     jpk 				    inet_ntoa(dst));
    326  1676     jpk 				cp += 17;
    327  1676     jpk 				blen -= 17;
    328  1676     jpk 				rep = rsep->rip_emetric;
    329  1676     jpk 				for (count = ntohl(rsep->rip_count); count > 0;
    330  1676     jpk 				    count--) {
    331  1676     jpk 					(void) snprintf(cp, blen, "metric=%d",
    332  1676     jpk 					    ntohs(rep->rip_metric));
    333  1676     jpk 					blen -= strlen(cp);
    334  1676     jpk 					cp += strlen(cp);
    335  1676     jpk 					tokp = rep->rip_token;
    336  1676     jpk 					num = get_numtokens(
    337  1676     jpk 					    ntohs(rep->rip_mask));
    338  1676     jpk 					/* advance to the next emetric */
    339  1676     jpk 					rep = (const struct rip_emetric *)
    340  1676     jpk 					    &rep->rip_token[num];
    341  1676     jpk 					if (num > 0) {
    342  1676     jpk 						(void) snprintf(cp, blen,
    343  1676     jpk 						    ",tokens=%lx",
    344  1676     jpk 						    (long)ntohl(*tokp));
    345  1676     jpk 						tokp++;
    346  1676     jpk 						num--;
    347  1676     jpk 					} else {
    348  1676     jpk 						(void) strlcpy(cp, ",no tokens",
    349  1676     jpk 						    blen);
    350  1676     jpk 					}
    351  1676     jpk 					while (num > 0) {
    352  1676     jpk 						blen -= strlen(cp);
    353  1676     jpk 						cp += strlen(cp);
    354  1676     jpk 						(void) snprintf(cp, blen,
    355  1676     jpk 						    ",%lx",
    356  1676     jpk 						    (long)ntohl(*tokp));
    357  1676     jpk 						tokp++;
    358  1676     jpk 						num--;
    359  1676     jpk 					}
    360  1676     jpk 					blen -= strlen(cp);
    361  1676     jpk 					cp += strlen(cp);
    362  1676     jpk 				}
    363  1676     jpk 				if (rsep->rip_count == 0) {
    364  1676     jpk 					(void) strlcpy(cp,
    365  1676     jpk 					    "NULL (not reachable)", blen);
    366  1676     jpk 				}
    367  1676     jpk 				len -= (const char *)rsn - (const char *)rsep;
    368  1676     jpk 				rsep = rsn;
    369  1676     jpk 			}
    370  1676     jpk 			break;
    371  1676     jpk 
    372     0  stevel 		case RIPCMD_TRACEON:
    373     0  stevel 		case RIPCMD_TRACEOFF:
    374  1676     jpk 			(void) snprintf(get_line(0, 0), get_line_remain(),
    375     0  stevel 			    "Trace file = %.*s", len, rip->rip_tracefile);
    376     0  stevel 			len = 0;
    377     0  stevel 			break;
    378     0  stevel 		}
    379     0  stevel 	}
    380     0  stevel 
    381     0  stevel 	return (fraglen - len);
    382     0  stevel }
    383     0  stevel 
    384  1676     jpk static const char *
    385     0  stevel show_cmd(int c)
    386     0  stevel {
    387     0  stevel 	switch (c) {
    388     0  stevel 	case RIPCMD_REQUEST:
    389     0  stevel 		return ("route request");
    390     0  stevel 	case RIPCMD_RESPONSE:
    391     0  stevel 		return ("route response");
    392     0  stevel 	case RIPCMD_TRACEON:
    393     0  stevel 		return ("route trace on");
    394     0  stevel 	case RIPCMD_TRACEOFF:
    395     0  stevel 		return ("route trace off");
    396     0  stevel 	case RIPCMD_POLL:
    397     0  stevel 		return ("route poll");
    398     0  stevel 	case RIPCMD_POLLENTRY:
    399     0  stevel 		return ("route poll entry");
    400  1676     jpk 	case RIPCMD_SEC_RESPONSE:
    401  1676     jpk 		return ("route sec response");
    402  1676     jpk 	case RIPCMD_SEC_T_RESPONSE:
    403  1676     jpk 		return ("route sec_t response");
    404     0  stevel 	}
    405     0  stevel 	return ("?");
    406     0  stevel }
    407  1676     jpk 
    408  1676     jpk static int
    409  1676     jpk get_numtokens(unsigned int mask)
    410  1676     jpk {
    411  1676     jpk 	int num = 0;
    412  1676     jpk 
    413  1676     jpk 	while (mask != 0) {
    414  1676     jpk 		num++;
    415  1676     jpk 		mask &= mask - 1;
    416  1676     jpk 	}
    417  1676     jpk 	return (num);
    418  1676     jpk }
    419  1676     jpk 
    420  1676     jpk static const struct rip_sec_entry *
    421  1676     jpk rip_next_sec_entry(const struct rip_sec_entry *rsep, int len)
    422  1676     jpk {
    423  1676     jpk 	const struct rip_emetric *rep;
    424  1676     jpk 	const char *limit = (const char *)rsep + len;
    425  1676     jpk 	long count;
    426  1676     jpk 
    427  1676     jpk 	if ((const char *)(rep = rsep->rip_emetric) > limit)
    428  1676     jpk 		return (NULL);
    429  1676     jpk 	count = ntohl(rsep->rip_count);
    430  1676     jpk 	while (count > 0) {
    431  1676     jpk 		if ((const char *)rep->rip_token > limit)
    432  1676     jpk 			return (NULL);
    433  1676     jpk 		rep = (struct rip_emetric *)
    434  1676     jpk 		    &rep->rip_token[get_numtokens(ntohs(rep->rip_mask))];
    435  1676     jpk 		if ((const char *)rep > limit)
    436  1676     jpk 			return (NULL);
    437  1676     jpk 		count--;
    438  1676     jpk 	}
    439  1676     jpk 	return ((const struct rip_sec_entry *)rep);
    440  1676     jpk }
    441