📄 network_support.c
字号:
//==========================================================================
//
// network_support.c
//
// Misc network support functions
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
// Copyright (C) 2003 Andrew Lunn <andrew.lunn@ascom.ch>
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//==========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): gthomas
// Contributors: gthomas, sorin@netappi.com ("Sorin Babeanu"), hmt, jlarmour,
// andrew.lunn@ascom.ch
// Date: 2000-01-10
// Purpose:
// Description:
//
//
//####DESCRIPTIONEND####
//
//==========================================================================
// BOOTP support
#include <pkgconf/net.h>
#undef _KERNEL
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/errno.h>
#include <net/if.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <net/route.h>
#include <cyg/infra/diag.h>
#include <cyg/kernel/kapi.h>
#include <stdio.h> // for 'sprintf()'
#include <bootp.h>
#include <network.h>
#include <arpa/inet.h>
#ifdef CYGPKG_IO_PCMCIA
#include <cyg/io/eth/netdev.h>
#endif
#ifdef CYGPKG_NET_DHCP
#include <dhcp.h>
#endif
#ifdef CYGPKG_NS_DNS
#include <pkgconf/ns_dns.h>
#endif
#ifdef CYGHWR_NET_DRIVER_ETH0
struct bootp eth0_bootp_data;
cyg_bool_t eth0_up = false;
const char *eth0_name = "eth0";
#endif
#ifdef CYGHWR_NET_DRIVER_ETH1
struct bootp eth1_bootp_data;
cyg_bool_t eth1_up = false;
const char *eth1_name = "eth1";
#endif
#define _string(s) #s
#define string(s) _string(s)
#ifndef CYGPKG_LIBC_STDIO
#define perror(s) diag_printf(#s ": %s\n", strerror(errno))
#endif
#ifdef CYGPKG_NET_NLOOP
#if 0 < CYGPKG_NET_NLOOP
//
// Initialize loopback interface ---------- Added by sorin@netappi.com
//
cyg_bool_t init_loopback_interface(int lo)
{
struct sockaddr_in *addrp;
struct ifreq ifr;
int s;
int one = 1;
struct ecos_rtentry route;
struct in_addr netmask, gateway;
s = socket(AF_INET, SOCK_DGRAM, 0);
if (s < 0) {
perror("socket");
return false;
}
if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &one, sizeof(one))) {
perror("setsockopt");
close(s);
return false;
}
addrp = (struct sockaddr_in *) &ifr.ifr_addr;
memset(addrp, 0, sizeof(*addrp));
addrp->sin_family = AF_INET;
addrp->sin_len = sizeof(*addrp);
addrp->sin_port = 0;
// Make an address 127.0.<lo>.1 to manage multiple loopback ifs.
// (There is normally only 1, so it's the standard 127.0.0.1)
addrp->sin_addr.s_addr = htonl((0x100 * lo) + INADDR_LOOPBACK) ;
#if CYGPKG_NET_NLOOP > 1
// Init the one we were told to
sprintf(ifr.ifr_name, "lo%d", lo);
#else
strcpy(ifr.ifr_name, "lo0");
#endif
if (ioctl(s, SIOCSIFADDR, &ifr)) {
perror("SIOCIFADDR");
close(s);
return false;
}
#if 1 < CYGPKG_NET_NLOOP
// We cheat to make different nets for multiple loopback devs
addrp->sin_addr.s_addr = netmask.s_addr = htonl(IN_CLASSC_NET);
#else
//
addrp->sin_addr.s_addr = netmask.s_addr = htonl(IN_CLASSA_NET);
#endif
if (ioctl(s, SIOCSIFNETMASK, &ifr)) {
perror("SIOCSIFNETMASK");
return false;
}
ifr.ifr_flags = IFF_UP | IFF_BROADCAST | IFF_RUNNING;
if (ioctl(s, SIOCSIFFLAGS, &ifr)) {
perror("SIOCSIFFLAGS");
close(s);
return false;
}
gateway.s_addr = htonl(INADDR_LOOPBACK);
memset(&route, 0, sizeof(route));
addrp->sin_family = AF_INET;
addrp->sin_len = sizeof(*addrp);
addrp->sin_port = 0;
addrp->sin_addr.s_addr = htonl((0x100 * lo) + INADDR_LOOPBACK) & netmask.s_addr;
memcpy(&route.rt_dst, addrp, sizeof(*addrp));
addrp->sin_addr = netmask;
memcpy(&route.rt_genmask, addrp, sizeof(*addrp));
addrp->sin_addr = gateway;
memcpy(&route.rt_gateway, addrp, sizeof(*addrp));
route.rt_dev = ifr.ifr_name;
route.rt_flags = RTF_UP|RTF_GATEWAY;
route.rt_metric = 0;
if (ioctl(s, SIOCADDRT, &route)) {
diag_printf("Route - dst: %s", inet_ntoa(((struct sockaddr_in *)&route.rt_dst)->sin_addr));
diag_printf(", mask: %s", inet_ntoa(((struct sockaddr_in *)&route.rt_genmask)->sin_addr));
diag_printf(", gateway: %s\n", inet_ntoa(((struct sockaddr_in *)&route.rt_gateway)->sin_addr));
if (errno != EEXIST) {
perror("SIOCADDRT 3");
close(s);
return false;
}
}
close(s);
return true;
}
#endif
#endif
//
// Internal function which builds up a fake BOOTP database for
// an interface.
//
static unsigned char *
add_tag(unsigned char *vp,
unsigned char tag,
void *val,
int len)
{
int i;
unsigned char *xp = (unsigned char *)val;
*vp++ = tag;
*vp++ = len;
for (i = 0; i < len; i++) {
*vp++ = *xp++;
}
return vp;
}
void
build_bootp_record(struct bootp *bp,
const char *if_name,
const char *addrs_ip,
const char *addrs_netmask,
const char *addrs_broadcast,
const char *addrs_gateway,
const char *addrs_server)
{
int i, s;
in_addr_t addr;
unsigned char *vp;
unsigned char cookie[] = VM_RFC1048;
struct ifreq ifr;
bzero(bp, sizeof(struct bootp));
bp->bp_op = BOOTREPLY;
bp->bp_htype = HTYPE_ETHERNET;
bp->bp_hlen = 6;
// Query the hardware address
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -