📄 dhcp_support.c
字号:
/*==========================================================================//// dhcp_support.c//// Support code == friendly API for DHCP client////==========================================================================//####ECOSPDCOPYRIGHTBEGIN####//// Copyright (C) 2000, 2001, 2002 Red Hat, Inc.// All Rights Reserved.//// Permission is granted to use, copy, modify and redistribute this// file.////####ECOSPDCOPYRIGHTEND####//==========================================================================//#####DESCRIPTIONBEGIN####//// Author(s): hmt// Contributors: gthomas// Date: 2000-07-01// Purpose: DHCP support// Description: ////####DESCRIPTIONEND####////========================================================================*/#include <pkgconf/system.h>#include <pkgconf/net.h>/* Define these locally because we are porting this code from a later package, * therefore these are not defined in pkgconf/net.h */#define CYGPKG_NET_DHCP#define CYGOPT_NET_DHCP_DHCP_THREAD#ifdef CYGPKG_NET_DHCP#include <network.h>#include <dhcp.h>typedef struct MIB_DHCP_s{ unsigned long IPAddr; unsigned long SubnetMask; unsigned long GwyAddr;}MIB_DHCP;#ifdef AP5XMIB_DHCP mib_DHCP;#define SUBNETMASK (mib_DHCP.SubnetMask)#define IPADDR (mib_DHCP.IPAddr)#define GWYADDR (mib_DHCP.GwyAddr)#elseextern MIB_DHCP *mib_DHCP_p;#define SUBNETMASK (mib_DHCP_p->SubnetMask)#define IPADDR (mib_DHCP_p->IPAddr)#define GWYADDR (mib_DHCP_p->GwyAddr)#endifextern unsigned char mib_dhcpenable;void init_static_network_interfaces(int);void update_IP_Info(void);extern int SetUserConfig(void);extern void Reset(void);static unsigned long ipaddr;// ---------------------------------------------------------------------------#ifdef CYGHWR_NET_DRIVER_ETH0cyg_uint8 eth0_dhcpstate = 0;#endif#ifdef CYGHWR_NET_DRIVER_ETH1cyg_uint8 eth1_dhcpstate = 0;#endifcyg_sem_t dhcp_needs_attention;#ifdef CYGHWR_NET_DRIVER_ETH0struct dhcp_lease eth0_lease = { &dhcp_needs_attention, 0, 0, 0, 0, 0, 0 };#endif#ifdef CYGHWR_NET_DRIVER_ETH1struct dhcp_lease eth1_lease = { &dhcp_needs_attention, 0, 0, 0, 0, 0, 0 };#endif// ---------------------------------------------------------------------------//// The point of this module is to deal with all the horrid written out in// full stuff of having two interfaces; it's ugly but it's also most// flexible. The dhcp_prot.c module should do all the work...//// ---------------------------------------------------------------------------// return value: 1 => everything OK, no change.// 0 => close your connections, then call do_dhcp_halt() to halt the// interface(s) in question (it knows because the state will be NOTBOUND).// After that you can return to the start and use// init_all_network_interfaces(); as usual, or call do_dhcp_bind() by hand,// or whatever...int dhcp_bind( void ){#ifdef CYGHWR_NET_DRIVER_ETH0 cyg_uint8 old_eth0_dhcpstate = eth0_dhcpstate;#endif#ifdef CYGHWR_NET_DRIVER_ETH1 cyg_uint8 old_eth1_dhcpstate = eth1_dhcpstate;#endif // If there are no interfaces at all, init it every time, doesn't // matter. In case we are called from elsewhere... if ( 1#ifdef CYGHWR_NET_DRIVER_ETH0 && eth0_dhcpstate == 0#endif#ifdef CYGHWR_NET_DRIVER_ETH1 && eth1_dhcpstate == 0#endif ) cyg_semaphore_init( &dhcp_needs_attention, 0 ); // Run the state machine...#ifdef CYGHWR_NET_DRIVER_ETH0 if (eth0_up && DHCPSTATE_FAILED != eth0_dhcpstate ) eth0_up = do_dhcp(eth0_name, ð0_bootp_data, ð0_dhcpstate, ð0_lease);#endif#ifdef CYGHWR_NET_DRIVER_ETH1 if (eth1_up && DHCPSTATE_FAILED != eth1_dhcpstate ) eth1_up = do_dhcp(eth1_name, ð1_bootp_data, ð1_dhcpstate, ð1_lease);#endif // If the interface newly came up, initialize it: // (this duplicates the code in init_all_network_interfaces() really).#ifdef CYGHWR_NET_DRIVER_ETH0 if ( eth0_up && eth0_dhcpstate == DHCPSTATE_BOUND && old_eth0_dhcpstate != eth0_dhcpstate ) { ipaddr = inet_address(eth0_bootp_data.bp_yiaddr.s_addr); if (!init_net(eth0_name, ð0_bootp_data)) { //if the server give us wrong gateway addr, net mask etc, init_net will fail //so we use the ip address and init ourself //eth0_up = false; init_static_network_interfaces(1); ipaddr = 0; } }#endif#ifdef CYGHWR_NET_DRIVER_ETH1 if ( eth1_up && eth1_dhcpstate == DHCPSTATE_BOUND && old_eth1_dhcpstate != eth1_dhcpstate ) { if (!init_net(eth1_name, ð1_bootp_data)) { eth1_up = false; } }#endif#ifdef CYGHWR_NET_DRIVER_ETH0 if ( old_eth0_dhcpstate == DHCPSTATE_BOUND && eth0_dhcpstate == DHCPSTATE_NOTBOUND ) return 0; // a lease timed out; we became unbound#endif#ifdef CYGHWR_NET_DRIVER_ETH1 if ( old_eth1_dhcpstate == DHCPSTATE_BOUND && eth1_dhcpstate == DHCPSTATE_NOTBOUND ) return 0; // a lease timed out; we became unbound#endif if (eth0_up) return 1; // all is well else return 0;}// Shutdown any interface whose state is DHCPSTATE_NOTBOUND.int dhcp_halt( void ){#ifdef CYGHWR_NET_DRIVER_ETH0 if ( eth0_up && eth0_dhcpstate != DHCPSTATE_FAILED ) { do_dhcp_down_net(eth0_name, ð0_bootp_data, ð0_dhcpstate, ð0_lease); eth0_bootp_data.bp_ciaddr.s_addr = 32; } eth0_up = false;#endif#ifdef CYGHWR_NET_DRIVER_ETH1 if ( eth1_up && eth1_dhcpstate != DHCPSTATE_FAILED ) { do_dhcp_down_net(eth1_name, ð1_bootp_data, ð1_dhcpstate, ð1_lease); } eth1_up = false;#endif return 1;}// Release (and set state to DHCPSTATE_NOTBOUND) all interfaces - we are// closing down. (unlikely but maybe useful for testing)int dhcp_release( void ){#ifdef CYGHWR_NET_DRIVER_ETH0 if (eth0_up) do_dhcp_release(eth0_name, ð0_bootp_data, ð0_dhcpstate, ð0_lease);#endif#ifdef CYGHWR_NET_DRIVER_ETH1 if (eth1_up) do_dhcp_release(eth1_name, ð1_bootp_data, ð1_dhcpstate, ð1_lease);#endif return 1;}unsigned int dhcp_del_old_ip_and_reset_interface( const char *if_name, int s, struct ifreq *ifrp /* socket for ioctl operations */){ strcpy(ifrp->ifr_name, if_name); memset(&(ifrp->ifr_addr),0, sizeof(ifrp->ifr_addr)); if (ioctl(s, SIOCGIFADDR, ifrp)) { if(errno != EADDRNOTAVAIL){ eth0_up = false; return false; } } else{ /* found IP so delete */ if (ioctl(s, SIOCDIFADDR, ifrp)) { perror("SIOCDIFADDR1"); } } // Shut down interface so it can be reinitialized ifrp->ifr_flags &= ~(IFF_UP | IFF_RUNNING); if (ioctl(s, SIOCSIFFLAGS, ifrp)) { eth0_up = false; return false; } ifrp->ifr_flags = IFF_UP | IFF_BROADCAST | IFF_RUNNING; if (ioctl(s, SIOCSIFFLAGS, ifrp)) { /* set ifnet flags */ perror("SIOCSIFFLAGS up"); return false; } return true;}// ------------------------------------------------------------------------// The management thread functionvoid dhcp_mgt_entry( cyg_addrword_t loop_on_failure ){ struct ifreq ifr; int s; init_static_network_interfaces(0);#ifdef DHCPTIMEOUTRETRY while (1) { if (dhcp_bind()) //Do a rebinding due to configuration in ECOS , todo break; else {#if 0 static int dhcpretrycnt = 0; dhcp_halt(); // tear everything down init_all_network_interfaces(); //try again if ( dhcpretrycnt++ > DHCPMAXRETRIES ) break;#else dhcp_halt(); // tear everything down init_all_network_interfaces(); //try again#endif } //cyg_thread_delay(10000*60);//retry binding every minute }#else#ifdef AP5X cyg_semaphore_post( &dhcp_needs_attention );#endif cyg_semaphore_wait( &dhcp_needs_attention ); if (mib_dhcpenable) { if (!dhcp_bind()) { dhcp_halt(); // tear everything down init_static_network_interfaces(0); } } init_static_network_interfaces(2); if((SUBNETMASK & 0xff000000) != 0xff000000) { if( (IPADDR & 0xC0000000) == 0xC0000000) SUBNETMASK = 0xffffff00; else if( (IPADDR & 0xC0000000) == 0x80000000) SUBNETMASK = 0xffff0000; else SUBNETMASK = 0xff000000; init_static_network_interfaces(0); }#endif while ( 1 ) { while ( 1 )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -