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>