From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 21444 invoked by alias); 31 Jul 2006 07:32:00 -0000 Received: (qmail 21410 invoked by uid 22791); 31 Jul 2006 07:31:56 -0000 X-Spam-Check-By: sourceware.org Received: from Unknown (HELO netic.com) (66.28.185.252) by sourceware.org (qpsmtpd/0.31) with ESMTP; Mon, 31 Jul 2006 07:31:52 +0000 Received: from piii550 (203-206-167-254.perm.iinet.net.au [203.206.167.254]) by netic.com (8.12.10/8.11.0) with SMTP id k6V7VlYK028513; Mon, 31 Jul 2006 01:31:48 -0600 Reply-To: From: "Laurie Gellatly" To: , Date: Mon, 31 Jul 2006 07:32:00 -0000 Message-ID: MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_NextPart_000_0036_01C6B4C7.540604D0" X-Mailer: Microsoft Outlook IMO, Build 9.0.2416 (9.0.2911.0) In-Reply-To: X-IsSubscribed: yes Mailing-List: contact ecos-discuss-help@ecos.sourceware.org; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: ecos-discuss-owner@ecos.sourceware.org Subject: RE: [ECOS] Dynamic IP/DHCP/Routing the 'right way' X-SW-Source: 2006-07/txt/msg00247.txt.bz2 ------=_NextPart_000_0036_01C6B4C7.540604D0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-length: 3448 Hi Joe, I've attached my network_support.c file. You'll see references to MCB... (that's my master control block structure) that holds the devices configuration like DHCP enabled or not. MCB.ucXXX are unsigned chars holding the IPv4 address as 4 bytes. It only assumes a single eth0 (and not eth1) though it would be easy to add that back in. HTH ...Laurie:{) -----Original Message----- From: ecos-discuss-owner@ecos.sourceware.org [mailto:ecos-discuss-owner@ecos.sourceware.org]On Behalf Of Joe Porthouse Sent: Saturday, 29 July 2006 11:53 AM To: laurie.gellatly@netic.com; ecos-discuss@ecos.sourceware.org Subject: RE: [ECOS] Dynamic IP/DHCP/Routing the 'right way' Laurie, See a copy, definitely. Many thanks!!! :) I have been digging through eCos files attempting to get an understanding of how things are working with the network, but it's kinda like walking through an unfamiliar house with only a flashlight to show you the way. I have not been able to see the entire picture yet. I was originally looking at the DHCP code and saw during a renewal it was shutting down the interface just before calling net_init() again. Still having lots to do, I would rather use a solution that has worked for someone else. BTW, grepping through the eCos packages I could not find StackInit, IP_SetIP, or IP_SetMask. Is there another package I need to install or are these your functions? Thanks, Joe Porthouse Toptech Systems, Inc. Longwood, FL 32750 -----Original Message----- From: Laurie Gellatly [mailto:laurie.gellatly@netic.com] Sent: Friday, July 28, 2006 6:01 PM To: jporthouse@toptech.com; ecos-discuss@ecos.sourceware.org Subject: RE: [ECOS] Dynamic IP/DHCP/Routing the 'right way' Hi Joe, Taking Andrew's suggestion I rolled my own. Would you like to see a copy? ...Laurie:{) -----Original Message----- From: Joe Porthouse [mailto:jporthouse@toptech.com] Sent: Saturday, 29 July 2006 7:30 AM To: ecos-discuss@ecos.sourceware.org; 'Laurie Gellatly' Subject: RE: [ECOS] Dynamic IP/DHCP/Routing the 'right way' Laurie, Did you find a solution that worked? I'm also dealing with this same issue. Thanks, Joe Porthouse Toptech Systems, Inc. Longwood, FL 32750 -----Original Message----- From: ecos-discuss-owner@ecos.sourceware.org [mailto:ecos-discuss-owner@ecos.sourceware.org] On Behalf Of Andrew Lunn Sent: Tuesday, June 06, 2006 7:19 AM To: Laurie Gellatly Cc: ecos-discuss@ecos.sourceware.org Subject: Re: [ECOS] Dynamic IP/DHCP/Routing the 'right way' On Tue, Jun 06, 2006 at 09:09:29PM +1000, Laurie Gellatly wrote: > Hi Andrew, > Thanks for the swift response. > SNTP - yes. Thanks for the tips there and with DNS, I'll look at those. > > init_net() was not sufficient. It left the old addresses active. I've > combined StackInit and IP_SetIP, IP_SetMask to remove the old address > and mask. Still think the routing is not being updated, but before I > launched into debugging all that I wanted to ensure I wasn't > re-inventing the wheel. I think this is a new wheel, at least i've not seen a public available wheel which does this. cyg_route_reinit() might help with your routing problem. Andrew -- Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss -- Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss ------=_NextPart_000_0036_01C6B4C7.540604D0 Content-Type: application/octet-stream; name="network_support.c" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="network_support.c" Content-length: 12566 //=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =0A= //=0A= // Adapted from network_support.c=0A= //=0A= // Misc network support functions=0A= // $Id: network_support.c,v 1.7 2006/07/18 04:58:44 gellatly Exp $=0A= //=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =0A= // BOOTP support=0A= =0A= #include =0A= #undef _KERNEL=0A= #include =0A= #include =0A= #include =0A= #include =0A= =0A= #include =0A= #include =0A= #include =0A= #include =0A= #include =0A= =0A= #include =0A= #include =0A= =0A= #include // for 'sprintf()'=0A= =0A= #include =0A= #include =0A= #include =0A= =0A= #include =0A= =0A= #include =0A= #include "mydev.h"=0A= =0A= #define CYGHWR_NET_DRIVER_ETH0_BOOTP_SHOW 1=0A= struct bootp eth0_bootp_data;=0A= cyg_bool_t eth0_up =3D false;=0A= const char *eth0_name =3D "eth0";=0A= =0A= #define _string(s) #s=0A= #define string(s) _string(s)=0A= =0A= #ifndef CYGPKG_LIBC_STDIO=0A= #define perror(s) diag_printf(#s ": %s\n", strerror(errno))=0A= #endif=0A= =0A= #ifdef CYGPKG_NET_NLOOP=0A= #if 0 < CYGPKG_NET_NLOOP=0A= //=20=20=0A= // Initialize loopback interface ---------- Added by sorin@netappi.com= =20=0A= //=0A= cyg_bool_t init_loopback_interface(int lo)=0A= {=0A= struct sockaddr_in *addrp;=0A= struct ifreq ifr;=0A= int s;=0A= int one =3D 1;=0A= struct ecos_rtentry route;=0A= struct in_addr netmask, gateway;=0A= =0A= s =3D socket(AF_INET, SOCK_DGRAM, 0);=20=0A= if (s < 0) {=0A= perror("socket");=0A= return false;=0A= }=0A= if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &one, sizeof(one))) {=0A= perror("setsockopt");=0A= close(s);=0A= return false;=0A= }=0A= =0A= addrp =3D (struct sockaddr_in *) &ifr.ifr_addr;=0A= memset(addrp, 0, sizeof(*addrp));=0A= addrp->sin_family =3D AF_INET;=0A= addrp->sin_len =3D sizeof(*addrp);=0A= addrp->sin_port =3D 0;=0A= // Make an address 127.0..1 to manage multiple loopback ifs.=0A= // (There is normally only 1, so it's the standard 127.0.0.1)=0A= addrp->sin_addr.s_addr =3D htonl((0x100 * lo) + INADDR_LOOPBACK) ;=20= =0A= =0A= #if CYGPKG_NET_NLOOP > 1=0A= // Init the one we were told to=0A= sprintf(ifr.ifr_name, "lo%d", lo);=0A= #else=0A= strcpy(ifr.ifr_name, "lo0");=0A= #endif=20=20=20=20=0A= =0A= if (ioctl(s, SIOCSIFADDR, &ifr)) {=0A= perror("SIOCIFADDR");=0A= close(s);=0A= return false;=0A= }=0A= =20=20=20=20=0A= #if 1 < CYGPKG_NET_NLOOP=0A= // We cheat to make different nets for multiple loopback devs=0A= addrp->sin_addr.s_addr =3D netmask.s_addr =3D htonl(IN_CLASSC_NET);=0A= #else=0A= //=20=0A= addrp->sin_addr.s_addr =3D netmask.s_addr =3D htonl(IN_CLASSA_NET);=0A= #endif=0A= if (ioctl(s, SIOCSIFNETMASK, &ifr)) {=0A= perror("SIOCSIFNETMASK");=0A= return false;=0A= }=0A= ifr.ifr_flags =3D IFF_UP | IFF_BROADCAST | IFF_RUNNING;=0A= if (ioctl(s, SIOCSIFFLAGS, &ifr)) {=0A= perror("SIOCSIFFLAGS");=0A= close(s);=0A= return false;=0A= }=0A= =0A= gateway.s_addr =3D htonl(INADDR_LOOPBACK);=20=20=0A= memset(&route, 0, sizeof(route));=0A= addrp->sin_family =3D AF_INET;=0A= addrp->sin_len =3D sizeof(*addrp);=0A= addrp->sin_port =3D 0;=0A= addrp->sin_addr.s_addr =3D htonl((0x100 * lo) + INADDR_LOOPBACK) & netm= ask.s_addr;=0A= memcpy(&route.rt_dst, addrp, sizeof(*addrp));=0A= addrp->sin_addr =3D netmask;=0A= memcpy(&route.rt_genmask, addrp, sizeof(*addrp));=0A= addrp->sin_addr =3D gateway;=0A= memcpy(&route.rt_gateway, addrp, sizeof(*addrp));=0A= =20=20=20=20=0A= route.rt_dev =3D ifr.ifr_name;=0A= route.rt_flags =3D RTF_UP|RTF_GATEWAY;=0A= route.rt_metric =3D 0;=0A= =0A= if (ioctl(s, SIOCADDRT, &route)) {=0A= diag_printf("Route - dst: %s", inet_ntoa(((struct sockaddr_in *)&ro= ute.rt_dst)->sin_addr));=0A= diag_printf(", mask: %s", inet_ntoa(((struct sockaddr_in *)&route.r= t_genmask)->sin_addr));=0A= diag_printf(", gateway: %s\n", inet_ntoa(((struct sockaddr_in *)&ro= ute.rt_gateway)->sin_addr));=0A= if (errno !=3D EEXIST) {=0A= perror("SIOCADDRT 3");=0A= close(s);=0A= return false;=0A= }=0A= }=0A= close(s);=0A= return true;=0A= }=0A= #endif=0A= #endif=0A= =0A= =0A= //=0A= // Internal function which builds up a fake BOOTP database for=0A= // an interface.=0A= //=0A= =0A= static unsigned char * add_tag(unsigned char *vp,=0A= unsigned char tag,=0A= void *val,=0A= int len) {=0A= int i;=0A= unsigned char *xp =3D (unsigned char *)val;=0A= *vp++ =3D tag;=0A= *vp++ =3D len;=0A= for (i =3D 0; i < len; i++) {=0A= *vp++ =3D *xp++;=0A= }=0A= return vp;=0A= }=0A= =0A= static void build_bootp_struct(struct bootp *bp,=0A= const char * if_name,=0A= unsigned char addrs_ip[],=0A= unsigned char addrs_netmask[],=0A= unsigned char addrs_gateway[],=0A= unsigned char addrs_DNSsv1[],=0A= unsigned char addrs_DNSsv2[],=0A= unsigned char addrs_NTPsv1[],=0A= unsigned char addrs_NTPsv2[]){=0A= int i, s;=0A= in_addr_t addr[2];=0A= unsigned char *vp,ucAddrBuf[4];=0A= unsigned char cookie[] =3D VM_RFC1048;=0A= struct ifreq ifr;=0A= =0A= bzero(bp, sizeof(struct bootp));=0A= bp->bp_op =3D BOOTREPLY;=0A= bp->bp_htype =3D HTYPE_ETHERNET;=0A= bp->bp_hlen =3D 6;=0A= =0A= // Query the hardware address=0A= for (i =3D 0; i < bp->bp_hlen; i++) {=0A= bp->bp_chaddr[i] =3D 0xFF; // Unknown=0A= }=0A= s =3D socket(AF_INET, SOCK_DGRAM, 0);=0A= if (s >=3D 0) {=0A= strcpy(ifr.ifr_name, if_name);=0A= if (ioctl(s, SIOCGIFHWADDR, &ifr) >=3D 0) {=0A= bcopy(ifr.ifr_hwaddr.sa_data, bp->bp_chaddr, bp->bp_hlen);=0A= }=0A= close(s);=0A= }=0A= =0A= // Fill in the provided IP addresses=0A= memcpy(&bp->bp_ciaddr.s_addr,addrs_ip,4);=0A= memcpy(&bp->bp_yiaddr.s_addr,addrs_ip,4);=0A= memcpy(&bp->bp_siaddr.s_addr,addrs_DNSsv1,4);=0A= memcpy(&bp->bp_giaddr.s_addr,addrs_gateway,4);=0A= for(i=3D0;i<4;++i) ucAddrBuf[i]=3Daddrs_ip[i] | (0xFF ^ addrs_netmask[i= ]); //Make the broadcast addr=0A= vp =3D &bp->bp_vend[0];=0A= bcopy(&cookie, vp, sizeof(cookie));=0A= vp +=3D sizeof(cookie);=0A= vp =3D add_tag(vp, TAG_SUBNET_MASK, addrs_netmask, sizeof(in_addr_t));= =0A= vp =3D add_tag(vp, TAG_IP_BROADCAST, ucAddrBuf, sizeof(in_addr_t));=0A= vp =3D add_tag(vp, TAG_GATEWAY, addrs_gateway, sizeof(in_addr_t));=0A= i=3D0;=0A= if(*(long*)addrs_DNSsv1) memcpy(&addr[i++],addrs_DNSsv1, sizeof(in_addr= _t));=0A= if(*(long*)addrs_DNSsv2) memcpy(&addr[i++],addrs_DNSsv2, sizeof(in_addr= _t));=0A= if(i) vp =3D add_tag(vp, TAG_DOMAIN_SERVER, addr, (i=3D=3D2)? sizeof(in= _addr_t)+sizeof(in_addr_t):sizeof(in_addr_t));=0A= i=3D0;=0A= if(*(long*)addrs_NTPsv1) memcpy(&addr[i++],addrs_NTPsv1, sizeof(in_addr= _t));=0A= if(*(long*)addrs_NTPsv2) memcpy(&addr[i++],addrs_NTPsv2, sizeof(in_addr= _t));=0A= if(i) vp =3D add_tag(vp, TAG_NTP_SERVER, addr, (i=3D=3D2)? sizeof(in_ad= dr_t)+sizeof(in_addr_t):sizeof(in_addr_t));=0A= *vp =3D TAG_END;=0A= }=0A= =0A= void del_eth0( void ) {=0A= int s;=0A= struct ifreq ifr;=0A= =20=20=0A= s =3D socket(PF_INET, SOCK_DGRAM, 0);=0A= =20=20=0A= if (s < 0){=0A= diag_printf("socket: %d\n",s);=0A= return;=0A= }=0A= memset(&ifr,0,sizeof( struct ifreq ) );=0A= =0A= strcpy(ifr.ifr_name, "eth0");=0A= =0A= if( ioctl( s, SIOCGIFADDR, &ifr ) =3D=3D -1 ){=0A= diag_printf("Impossible to obtain an IP address of '%s' because '%s'"= ,ifr.ifr_name,strerror(errno));=0A= } else {=0A= if( ioctl( s, SIOCDIFADDR, &ifr ) !=3D 0 ){=0A= diag_printf("Impossible to remove IP address '%s' because '%s'",if= r.ifr_name,strerror(errno));=0A= }=0A= }=0A= diag_printf("del_eth0 complete.\n");=0A= close(s);=0A= }=0A= =0A= //=0A= // Initialize network interface[s] using BOOTP/DHCP=0A= //=0A= void init_all_network_interfaces(void) {=0A= static volatile int in_init_all_network_interfaces =3D 0;=0A= #ifdef CYGOPT_NET_IPV6_ROUTING_THREAD=0A= int rs_wait =3D 40;=0A= #endif=0A= =0A= cyg_scheduler_lock(); // Make this call idempotent=0A= while ( in_init_all_network_interfaces ) {=0A= // Another thread is doing this...=0A= cyg_scheduler_unlock();=0A= cyg_thread_delay( 10 );=0A= cyg_scheduler_lock();=0A= }=0A= in_init_all_network_interfaces =3D 1;=0A= cyg_scheduler_unlock();=0A= if(eth0_up && ((MCB.icIPUseDHCP =3D=3D 3) || ! MCB.icIPUseDHCP)){ // DH= CP is coming up or not running=0A= del_eth0(); // Delete the old static address first=0A= }=0A= // Deal with DHCP start/stop first then static addressing=0A= if(MCB.icIPUseDHCP =3D=3D 3){ // Change in state of DHCP to UP= =0A= // Perform a complete initialization, using BOOTP/DHCP=0A= eth0_up =3D true;=0A= eth0_dhcpstate =3D 0; // Says that initialization is external to dhc= p=0A= if (!do_dhcp(eth0_name, ð0_bootp_data, ð0_dhcpstate, ð0_lea= se)){=0A= diag_printf("BOOTP/DHCP failed on eth0\n");=0A= eth0_up =3D false;=0A= }=0A= }else if(MCB.icIPUseDHCP =3D=3D 2){ // Change in state of DHCP to do= wn=0A= if ( eth0_up ) {=0A= // eth0_dhcpstate =3D 0; // Says that initialization is external = to dhcp=0A= do_dhcp_down_net(eth0_name, ð0_bootp_data, ð0_dhcpstate, &e= th0_lease);=0A= }=0A= eth0_up =3D true;=0A= }=0A= if(!(MCB.icIPUseDHCP & 1)){ // DHCP is down so set static address=0A= //Build the bootp data so gateway & mask tags are set correctly=0A= build_bootp_struct(ð0_bootp_data,=0A= eth0_name,=0A= MCB.ucSNMPIPV4Addr,=0A= MCB.ucSNMPIPV4Mask,=0A= MCB.ucSNMPIPV4Gate,=0A= MCB.ucIPV4DNSServ1Addr,=0A= MCB.ucIPV4DNSServ2Addr,=0A= MCB.ucIPV4NTPServ1Addr,=0A= MCB.ucIPV4NTPServ2Addr);=0A= eth0_up =3D true;=0A= }=0A= #ifdef CYGHWR_NET_DRIVER_ETH0_BOOTP_SHOW=0A= //Show what HDCP or static addresses have been setup=0A= show_bootp(eth0_name, ð0_bootp_data);=0A= #endif=0A= if (eth0_up) {=0A= if (!init_net(eth0_name, ð0_bootp_data)) {=0A= diag_printf("Network initialization failed for eth0\n");=0A= eth0_up =3D false;=0A= }=0A= #ifdef CYGHWR_NET_DRIVER_ETH0_IPV6_PREFIX=0A= if (!init_net_IPv6(eth0_name, ð0_bootp_data,=20=0A= string(CYGHWR_NET_DRIVER_ETH0_IPV6_PREFIX))) {= =0A= diag_printf("Static IPv6 network initialization failed for eth0= \n");=0A= eth0_up =3D false; // ???=0A= }=0A= #endif=0A= }=0A= =0A= if(MCB.icIPUseDHCP =3D=3D 3) dhcp_start_dhcp_mgt_thread();=0A= =0A= #ifdef CYGOPT_NET_IPV6_ROUTING_THREAD=0A= ipv6_start_routing_thread();=0A= =0A= // Wait for router solicit process to happen.=0A= while (rs_wait-- && !cyg_net_get_ipv6_advrouter(NULL)) {=0A= cyg_thread_delay(10);=0A= }=0A= if (rs_wait =3D=3D 0 ) {=0A= diag_printf("No router solicit received\n");=0A= } else {=0A= // Give Duplicate Address Detection time to work=0A= cyg_thread_delay(200);=0A= }=0A= #endif=0A= #ifdef CYGDAT_NS_DNS_DOMAINNAME_NAME=0A= {=0A= const char buf[] =3D "mycompany.com";=0A= int len =3D strlen(buf);=0A= =20=20=20=20=20=20=0A= setdomainname(buf,len);=0A= }=0A= #endif=0A= // Open the monitor to other threads.=0A= in_init_all_network_interfaces =3D 0;=0A= }=0A= =0A= // EOF network_support.c=0A= =0A= ------=_NextPart_000_0036_01C6B4C7.540604D0 Content-Type: text/plain; charset=us-ascii Content-length: 148 -- Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss ------=_NextPart_000_0036_01C6B4C7.540604D0--