Date: Mon, 14 Feb 2000 14:45:38 -0800 From: Nathan <nboeger@getrelevant.com> To: rbg@pmr.com, "freebsd-net@FreeBSD.ORG" <freebsd-net@FreeBSD.ORG> Subject: Re: HELP ! programing routes ?? Message-ID: <38A88592.8F1B94E7@getrelevant.com> References: R01YxZF
next in thread | raw e-mail | index | archive | help
rbg@pmr.com wrote: > ----- ORIGINAL INTERNET MAIL FOLLOWS 02/14/2000 02:26 PM PST ----- > From: rbg@pmr.com > To: nboeger > > Nath.. > > I don't see were l is getting set to the size you're > writing to the socket... > > ----- Original Message ----- > From: "Nathan" <nboeger@getrelevant.com> > To: <freebsd-net@FreeBSD.ORG> > Sent: Monday, February 14, 2000 4:07 PM > Subject: HELP ! programing routes ?? > > > Sorry if this is a repeat ! > > > > > > I have a question, I need to write a small program that sets the default > > > > gw. It is written in C and I have looked at several way to do it. One > > way is using ioctl but that way seems a little "old" and not very well > > documented. Here is a simple snippet of my code, now when I run it I get > > > > an error "error 22" invalid arg. Does anyone have experience with this > > and can point out what I am doing wrong ? I did have it to where it > > would work but the kernel never added my netmask to the routing table. > > So the route would kinda "hang" their and not do anything. I did tell it > > > > that it was being sent but..... also the flags never where set proper on > > > > the route (when doing route -dvn flush ) > > > > > > Any help would be great ! (oh if this looks familiar, I learned this > > from reading both ruote.c and netstat.c. ) > > > > struct rt_data_msg{ > > struct rt_msghdr add_rtm; > > union{ > > struct sockaddr sa; > > struct sockaddr_in sin; > > struct sockaddr_dl sdl; > > }rt_dst, rt_gate, rt_mask; > > }; > > > > int set_droute(char *gw){ > > > > int sockfd, i, err = 0; > > int flags = 0, r_addrs = 0; > > u_long inits; > > char t_gw[32]; > > register int l; > > struct rt_data_msg add_rt; > > pid_t pid; > > > > /* check to see if we have a gateway address or quit */ > > if(!gw){ > > ERR("set_droute: FREEBSD no route sent ! %d"); > > return(BAD); > > } > > else{ > > /* convet this address if not valid quit */ > > if((inet_aton(gw, &so_gate.sin.sin_addr)) < 0){ > > ERR("set_droute: FREEBSD route not valid ! %d"); > > > > return(BAD); > > } > > } > > > > memset(&add_rt, 0, sizeof(struct rt_data_msg)); > > > > /* check to see if thier is an existing route or not make an > > entry from scratch */ > > if( (i = get_droute(t_gw)) == BAD){ > > > > /* make the address and netmasks */ > > > > if((inet_aton("0.0.0.0", &add_rt.rt_mask.sin.sin_addr)) > > < 0){ err++; } > > if((inet_aton("0.0.0.0", &add_rt.rt_dst.sin.sin_addr)) < > > > > 0) { err++; } > > if((inet_aton(gw, &add_rt.rt_gate.sin.sin_addr)) < 0){ > > err++; } > > if(err > 0){ > > ERR("get_droute: FREEBSD cannot set mask or dst > > or gw invalid addresses %d"); > > return(BAD); > > } > > > > inits = RTV_EXPIRE; > > inits |= RTV_RPIPE; > > inits |= RTV_SPIPE; > > inits |= RTV_SSTHRESH; > > > > r_addrs = RTAX_DST; > > r_addrs |= RTAX_GATEWAY; > > r_addrs |= RTAX_NETMASK; > > > > flags = RTF_UP; > > flags |= RTF_GATEWAY; > > flags |= RTF_STATIC; > > flags |= RTF_PRCLONING; > > > > /* add thier size */ > > #define ADD_SIZE(w) l = ROUNDUP(w.sa.sa_len) > > #define ROUNDUP(a) ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) > > : sizeof(long)); > > > > ADD_SIZE(add_rt.rt_dst); > > ADD_SIZE(add_rt.rt_gate); > > ADD_SIZE(add_rt.rt_mask); > > > > /* add their address family */ > > #define ADD_FAM(x) x.sin.sin_family = AF_INET; > > ADD_FAM(add_rt.rt_dst); > > ADD_FAM(add_rt.rt_gate); > > ADD_FAM(add_rt.rt_mask); > > ADD_FAM(add_rt.rt_genmask); > > > > /* set up all of the flags and tables */ > > #define RD add_rt.add_rtm > > RD.rtm_msglen = l; > > RD.rtm_version = RTM_VERSION; > > RD.rtm_type = RTM_ADD; > > RD.rtm_flags = flags; > > RD.rtm_addrs = rtm_addrs; > > RD.rtm_inits = RTF_GATEWAY; > > RD.rtm_pid = pid = getpid(); > > RD.rtm_seq = ++SEQ; > > > > if( (sockfd = socket(PF_ROUTE, SOCK_RAW, 0)) < 0){ > > ERR("set_droute: FREEBSD cannot open socket > > %d"); > > } > > /* send it to the kernel */ > > i = write(sockfd, (char *)&add_rt, l); > > syslog(LOG_ERR, "errno = %d ", errno); > > } > > else{ > > /* get a buffer for the data */ > > ERR("get_droute returned ok %d "); > > } > > > > return(GOOD); > > } > > > > > > Thank you > > > > nathan > > > > > > > > To Unsubscribe: send mail to majordomo@FreeBSD.org > > with "unsubscribe freebsd-net" in the body of the message > > Good point ! this is an older copy, but the size I have fixed that and it receives a size of 128,. Now the problem I think is that the sizeof the struct rt_msghdr is 92, now that would be followed by my 3 sockaddr_in structs which are 16 each so total is 140 ? now the size of 128 is the size that the actual route.c sends and the difference is that they make a struct with a rt_msghdr, and a char buf of 512 and then he formats that without the popen numbers and only writes the fist 128. Now what I need to know if that is the case then what exactly needs to follow the rt_msghdr the doc's that I have found say that it needs in order: sockaddr dst /* destination rt_msghdr == 92 + this == 108*/ sockaddr gtw /* gateway current 108 + 16 == 124*/ sockaddr ntmsl /* net mask current 124 + 16 == 140 ? */ so does it really need the first destination or is that implied when you send the netmask ? or is their a location that is inside the struct rt_msghdr that you need to fill-in besides the obvious ? To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-net" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?38A88592.8F1B94E7>