Skip site navigation (1)Skip section navigation (2)
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>

next in thread | raw e-mail | index | archive | help

>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




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?19990617213905.B695B14D21>