Date: Thu, 17 Jun 1999 14:39:05 -0700 (PDT) From: pkunk@i.am To: freebsd-gnats-submit@freebsd.org Subject: kern/12265: using routing socket to find default route when there is none panics kernel with rtfree Message-ID: <19990617213905.B695B14D21@hub.freebsd.org>
index | next in thread | raw e-mail
>Number: 12265
>Category: kern
>Synopsis: using routing socket to find default route when there is none panics kernel with rtfree
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Thu Jun 17 14:40:01 PDT 1999
>Closed-Date:
>Last-Modified:
>Originator: Lawrence D. Contam Jr.
>Release: FreeBSD 3.1
>Organization:
Hewlett Packard
>Environment:
FreeBSD fury.engr.telegra.com 3.1-RELEASE FreeBSD 3.1-RELEASE #0: Sun Jun 13 19:30:31 PDT 1999 root@fury.engr.telegra.com:/usr/src/sys/compile/FURY i386
>Description:
When using a piece of C code I put together for our custom application under PicoBSD, I discovered that the kernel panics when the machine has no default route and this code tries to find it, using the routing socket (socket(AF_ROUTE, SOCK_RAW, 0)). Further research found the same thing happens on my full FreeBSD 3.1 machine. I know route(8) doesnt cause a panic when you fetch the default route (route get default) and there is none, so maybe my code is broken.. but should broken code simply setting a RTM_GET to the routing socket panic the kernel?
>How-To-Repeat:
Here's the sniplet of code that causes the panic. Delete your default route and run it.
//
// macros and defines for get_rtaddrs
//
#define RSOCK_BUFLEN (sizeof(struct rt_msghdr) + 512)
#define RSOCK_SEQ 6699
#define RSOCK_ROUNDUP(a, size) (((a) & ((size)-1)) ? (1 + ((a) | ((size)
-1))) : (a))
#define NEXT_SA(ap) ap = (struct sockaddr *) ((caddr_t) ap + (ap->sa_len
? RSOCK_ROUNDUP(ap->sa_len, sizeof(u_long)) : sizeof(u_long)))
void get_rtaddrs(int addrs, struct sockaddr *sa, struct sockaddr **rti_info)
{
int i;
for(i = 0; i < RTAX_MAX; i++)
{
if(addrs & (1 << i))
{
rti_info[i] = sa;
NEXT_SA(sa);
}
else rti_info[i] = NULL;
}
}
int GetDefaultRoute(struct sockaddr * psa)
{
int sockfd, retval = 0;
char *buf;
pid_t pid;
ssize_t n;
struct rt_msghdr *rtm;
struct sockaddr *sa, *rti_info[RTAX_MAX];
struct sockaddr_in *sin;
if( (sockfd = socket(AF_ROUTE, SOCK_RAW, 0)) == -1)
{
errx(1,"socket");
}
buf = (char *)calloc(1, RSOCK_BUFLEN);
rtm = (struct rt_msghdr *)buf;
rtm->rtm_msglen = sizeof(struct rt_msghdr) + sizeof(struct sockaddr_in);
rtm->rtm_version = RTM_VERSION;
rtm->rtm_type = RTM_GET;
rtm->rtm_addrs = RTA_DST;
rtm->rtm_pid = pid = getpid();
rtm->rtm_seq = RSOCK_SEQ;
sin = (struct sockaddr_in *)(rtm + 1);
memset(sin,0,sizeof(struct sockaddr_in));
sin->sin_len = sizeof(struct sockaddr_in);
sin->sin_family = AF_INET;
//
// default route is 0.0.0.0, so just get the route to that.
//
write(sockfd, rtm, rtm->rtm_msglen);
do
{
n = read(sockfd, rtm, RSOCK_BUFLEN);
dprintf(5,"read %d bytes from routing socket\n",n);
} while(rtm->rtm_type != RTM_GET ||
rtm->rtm_seq != RSOCK_SEQ ||
rtm->rtm_pid != pid);
rtm = (struct rt_msghdr *) buf;
sa = (struct sockaddr *)(rtm + 1);
get_rtaddrs(rtm->rtm_addrs, sa, rti_info);
//
// we're only interested in gateway!
//
if((sa = rti_info[RTAX_GATEWAY]) != NULL)
{
//
// found it... copy to caller
//
memcpy(psa, sa, sizeof(struct sockaddr));
retval = 1;
}
//
// clean up and get out
//
free(buf);
close(sockfd);
return(retval);
}
>Fix:
>Release-Note:
>Audit-Trail:
>Unformatted:
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message
home |
help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?19990617213905.B695B14D21>
