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