| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349 |
- /*
- * Copyright (C) 2001-2004 by egnite Software GmbH
- * Copyright (c) 1993 by Digital Equipment Corporation
- * Copyright (c) 1983, 1993 by The Regents of the University of California
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the copyright holders nor the names of
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * For additional information see http://www.ethernut.de/
- */
- /*!
- * \file net/ifconfig.c
- * \brief Network interface configuration functions.
- *
- * \verbatim
- * $Id: ifconfig.c 4636 2012-09-20 09:02:23Z haraldkipp $
- * \endverbatim
- */
- #include <cfg/os.h>
- #include <string.h>
- #include <io.h>
- #include <dev/ppp.h>
- #include <net/if.h>
- #include <net/ether.h>
- #include <net/route.h>
- #include <arpa/inet.h>
- #include <netinet/ppp_fsm.h>
- #include <netinet/if_ether.h>
- #include <netinet/igmp.h>
- #include <netinet/in.h>
- #include <sys/event.h>
- #include <dev/uart.h>
- #include <sys/confnet.h>
- #include <pro/dhcp.h>
- #ifdef NUTDEBUG
- #include <sys/osdebug.h>
- #include <net/netdebug.h>
- #endif
- /*!
- * \addtogroup xgIP
- */
- /*@{*/
- /*!
- * \brief Network interface setup.
- *
- * \param dev Identifies the network device to setup.
- * \param ip_addr Specified IP address in network byte order.
- * \param ip_mask Specified IP network mask in network byte order.
- * \param gateway Optional default gateway.
- *
- * \return 0 on success, -1 otherwise.
- *
- * \note Typical applications do not use this function, but call
- * NutDhcpIfConfig() or NutNetIfConfig().
- */
- int NutNetIfSetup(NUTDEVICE * dev, uint32_t ip_addr, uint32_t ip_mask, uint32_t gateway)
- {
- IFNET *nif;
- nif = dev->dev_icb;
- /*
- * Use specified or previously used IP address.
- */
- if (ip_addr == 0 && (ip_addr = confnet.cdn_ip_addr) == 0)
- return -1;
- nif->if_local_ip = ip_addr;
- /*
- * Use specified or default mask.
- */
- if (ip_mask == 0) {
- #ifdef __BIG_ENDIAN__
- ip_mask = 0xFFFFFF00UL;
- #else
- ip_mask = 0x00FFFFFFUL;
- #endif
- }
- nif->if_mask = ip_mask;
- /*
- * Add routing entries.
- */
- NutIpRouteAdd(ip_addr & ip_mask, ip_mask, 0, dev);
- if (gateway)
- NutIpRouteAdd(0, 0, gateway, dev);
- /*
- * Save configuration in EEPROM.
- */
- memcpy(confnet.cd_name, dev->dev_name, sizeof(confnet.cd_name));
- /* Never save an invalid MAC address. */
- if (!ETHER_IS_BROADCAST(nif->if_mac) && !ETHER_IS_ZERO(nif->if_mac)) {
- memcpy(confnet.cdn_mac, nif->if_mac, sizeof(nif->if_mac));
- }
- confnet.cdn_ip_addr = ip_addr;
- confnet.cdn_ip_mask = ip_mask;
- /*
- * Set gateway, if one was provided by the caller. Remove
- * gateway, if it's outside of our network.
- */
- if (gateway || (confnet.cdn_gateway & ip_mask) != (ip_addr & ip_mask))
- confnet.cdn_gateway = gateway;
- return NutNetSaveConfig();
- }
- /*!
- * \brief Configure a network interface.
- *
- * Devices must have been registered by NutRegisterDevice() before
- * calling this function.
- *
- * For Ethernet devices applications may alternatively call
- * NutDhcpIfConfig(), which allows automatic configuration by DHCP or
- * the so called ARP method.
- *
- * \param name Name of the device to configure.
- * \param params Pointer to interface specific parameters. For Ethernet
- * interfaces this parameter may be a pointer to a buffer
- * containing the 6 byte long MAC address. This will
- * override the MAC address stored in the non-volatile
- * configuration memory. If this memory is uninitialized
- * or not available, the MAC address must be specified.
- * For PPP client interfaces this parameter is NULL,
- * while PPP server interfaces expect a pointer to a
- * \ref PPPSERVER_CFG structure containing the server
- * configuration.
- * \param ip_addr Specified IP address in network byte order. This must
- * be a unique address within the Internet. If you do not
- * directly communicate with other Internet hosts, you can
- * use a locally assigned address. With PPP interfaces this
- * may be set to 0.0.0.0, in which case the remote peer
- * will be queried for an IP address.
- * \param ip_mask Specified IP network mask in network byte order.
- * Typical Ethernet networks use 255.255.255.0, which
- * allows up to 254 hosts. For PPP interfaces 255.255.255.255
- * is the default.
- *
- * \return 0 on success, -1 otherwise.
- *
- * \note The whole interface configuration has become a mess over
- * the years and need a major redesign.
- */
- int NutNetIfConfig(const char *name, void *params, uint32_t ip_addr, uint32_t ip_mask)
- {
- return NutNetIfConfig2(name, params, ip_addr, ip_mask, 0);
- }
- /*!
- * \brief Configure a network interface including the default gateway.
- *
- * Devices must have been registered by NutRegisterDevice() before
- * calling this function.
- *
- * For Ethernet devices applications may alternatively call
- * NutDhcpIfConfig(), which allows automatic configuration by DHCP or
- * the so called ARP method.
- *
- * \param name Name of the device to configure.
- * \param params Pointer to interface specific parameters. For Ethernet
- * interfaces this parameter may be a pointer to a buffer
- * containing the 6 byte long MAC address. This will
- * override the MAC address stored in the non-volatile
- * configuration memory. If this memory is uninitialized
- * or not available, the MAC address must be specified.
- * For PPP client interfaces this parameter is NULL,
- * while PPP server interfaces expect a pointer to a
- * \ref PPPSERVER_CFG structure containing the server
- * configuration.
- * \param ip_addr Specified IP address in network byte order. This must
- * be a unique address within the Internet. If you do not
- * directly communicate with other Internet hosts, you can
- * use a locally assigned address. With PPP interfaces this
- * may be set to 0.0.0.0, in which case the remote peer
- * will be queried for an IP address.
- * \param ip_mask Specified IP network mask in network byte order.
- * Typical Ethernet networks use 255.255.255.0, which
- * allows up to 254 hosts. For PPP interfaces 255.255.255.255
- * is the default.
- * \param gateway Specified IP address of gateway or next router in LAN.
- *
- * \return 0 on success, -1 otherwise.
- *
- * \note I do not like this function, because setting a gateway should
- * be handled by NutIpRouteAdd(). It's not yet deprecated, but I
- * recommend not to use it in application code.
- */
- int NutNetIfConfig2(const char *name, void *params, uint32_t ip_addr, uint32_t ip_mask, uint32_t gateway)
- {
- NUTDEVICE *dev;
- IFNET *nif;
- /*
- * Check if this is a registered network device.
- */
- if ((dev = NutDeviceLookup(name)) == 0 || dev->dev_type != IFTYP_NET)
- return -1;
- /*
- * Setup Ethernet interfaces.
- */
- nif = dev->dev_icb;
- if (nif->if_type == IFT_ETHER) {
- /* Check if ioctl is supported. */
- if (dev->dev_ioctl) {
- uint32_t flags;
- /* Driver has ioctl, use it. */
- dev->dev_ioctl(dev, SIOCGIFFLAGS, &flags);
- dev->dev_ioctl(dev, SIOCSIFADDR, params);
- flags |= IFF_UP;
- dev->dev_ioctl(dev, SIOCSIFFLAGS, &flags);
- } else {
- /* No ioctl, set MAC address to start driver. */
- memcpy(nif->if_mac, params, sizeof(nif->if_mac));
- }
- return NutNetIfSetup(dev, ip_addr, ip_mask, gateway);
- }
- /*
- * Setup PPP interfaces.
- */
- else if (nif->if_type == IFT_PPP) {
- PPPDCB *dcb = dev->dev_dcb;
- PPPSERVER_CFG *ppsc = params;
- /*
- * Set the interface's IP address, make sure that the state
- * change queue is empty and switch hardware driver into
- * network mode.
- */
- dcb->dcb_local_ip = ip_addr;
- dcb->dcb_ip_mask = ip_mask ? ip_mask : 0xffffffff;
- if (ppsc) {
- dcb->dcb_remote_ip = ppsc->ppsc_remote_ip;
- }
- NutEventBroadcast(&dcb->dcb_state_chg);
- _ioctl(dcb->dcb_fd, HDLC_SETIFNET, &dev);
- /*
- * Wait for network layer up and configure the interface on
- * success.
- */
- if (NutEventWait(&dcb->dcb_state_chg, 60000) == 0 && dcb->dcb_ipcp_state == PPPS_OPENED) {
- return NutNetIfSetup(dev, dcb->dcb_local_ip, dcb->dcb_ip_mask, dcb->dcb_remote_ip);
- }
- }
- return -1;
- }
- int NutNetIfAddMcastAddr(const char *name, uint32_t ip_addr)
- {
- NUTDEVICE *dev;
- IFNET *nif;
- int rc = -1;
- /*
- * Check if this is a registered network device.
- */
- if ((dev = NutDeviceLookup(name)) == 0 || dev->dev_type != IFTYP_NET)
- return -1;
- /*
- * Setup multicast address
- */
- nif = dev->dev_icb;
- if (nif->if_type == IFT_ETHER) {
- /* Check if ioctl is supported. */
- if (dev->dev_ioctl) {
- /* Driver has ioctl, use it. */
- rc = dev->dev_ioctl(dev, SIOCADDMULTI, &ip_addr);
- if ((rc == 0) && (ip_addr != INADDR_ALLHOSTS_GROUP)) {
- NutIgmpJoinGroup(dev, ip_addr);
- }
- }
- }
- return rc;
- }
- int NutNetIfDelMcastAddr(const char *name, uint32_t ip_addr)
- {
- NUTDEVICE *dev;
- IFNET *nif;
- int rc = -1;
- /*
- * Check if this is a registered network device.
- */
- if ((dev = NutDeviceLookup(name)) == 0 || dev->dev_type != IFTYP_NET)
- return -1;
- /*
- * Setup multicast address
- */
- nif = dev->dev_icb;
- if (nif->if_type == IFT_ETHER) {
- /* Check if ioctl is supported. */
- if (dev->dev_ioctl) {
- /* Driver has ioctl, use it. */
- rc = dev->dev_ioctl(dev, SIOCDELMULTI, &ip_addr);
- if ((rc == 0) && (ip_addr != INADDR_ALLHOSTS_GROUP)) {
- NutIgmpLeaveGroup(dev, ip_addr);
- }
- }
- }
- return rc;
- }
- /*@}*/
|