⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bootp_support.c

📁 ecos实时嵌入式操作系统
💻 C
📖 第 1 页 / 共 2 页
字号:
//==========================================================================////      lib/bootp_support.c////      Minimal BOOTP functions////==========================================================================//####ECOSGPLCOPYRIGHTBEGIN####// -------------------------------------------// This file is part of eCos, the Embedded Configurable Operating System.// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.//// 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// Date:         2000-01-10// Purpose:      // Description:  //              ////####DESCRIPTIONEND####////==========================================================================// BOOTP support (and a little DHCP support also)#include <pkgconf/system.h>#include <pkgconf/net.h>#include <pkgconf/isoinfra.h>#include <network.h>#include <errno.h>#ifdef CYGPKG_NET_FREEBSD_STACK  // New layout#include <net/if_var.h>#include <netinet/in_var.h>#include <netinet6/nd6.h>#endif#ifdef CYGINT_ISO_DNS#include <netdb.h>#endif#ifndef CYGPKG_LIBC_STDIO#define perror(s) diag_printf(#s ": %s\n", strerror(errno))#endif// This function sets up the interface it the simplest configuration.// Just enough to broadcast a BOOTP request and get a response.// It returns 'true' if a response was obtained.cyg_bool_tdo_bootp(const char *intf, struct bootp *recv){    struct sockaddr_in *addrp;    struct ifreq ifr;    struct sockaddr_in cli_addr, serv_addr, bootp_server_addr;    struct ecos_rtentry route;    int s, addrlen;    int one = 1;    struct bootp bootp_xmit;    unsigned char mincookie[] = {99,130,83,99,255} ;    struct timeval tv;    cyg_bool_t retcode = true;    // Ensure clean slate    cyg_route_reinit();  // Force any existing routes to be forgotten    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");        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;    addrp->sin_addr.s_addr = INADDR_ANY;    strcpy(ifr.ifr_name, intf);    if (ioctl(s, SIOCSIFADDR, &ifr)) {        perror("SIOCSIFADDR");        return false;    }    if (ioctl(s, SIOCSIFNETMASK, &ifr)) {        perror("SIOCSIFNETMASK");        return false;    }    /* the broadcast address is 255.255.255.255 */    memset(&addrp->sin_addr, 255, sizeof(addrp->sin_addr));    if (ioctl(s, SIOCSIFBRDADDR, &ifr)) {        perror("SIOCSIFBRDADDR");        return false;    }    ifr.ifr_flags = IFF_UP | IFF_BROADCAST | IFF_RUNNING;    if (ioctl(s, SIOCSIFFLAGS, &ifr)) {        perror("SIOCSIFFLAGS");        return false;    }    if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) {        perror("SIOCGIFHWADDR");        return false;    }    // Set up routing    /* the broadcast address is 255.255.255.255 */    memset(&addrp->sin_addr, 255, sizeof(addrp->sin_addr));    memset(&route, 0, sizeof(route));    memcpy(&route.rt_gateway, addrp, sizeof(*addrp));    addrp->sin_family = AF_INET;    addrp->sin_port = 0;    addrp->sin_addr.s_addr = INADDR_ANY;    memcpy(&route.rt_dst, addrp, sizeof(*addrp));    memcpy(&route.rt_genmask, 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)) {        if (errno != EEXIST) {            perror("SIOCADDRT 3");            return false;        }    }    memset((char *) &cli_addr, 0, sizeof(cli_addr));    cli_addr.sin_family = AF_INET;    cli_addr.sin_addr.s_addr = htonl(INADDR_ANY);    cli_addr.sin_port = htons(IPPORT_BOOTPC);        if(bind(s, (struct sockaddr *) &cli_addr, sizeof(cli_addr)) < 0) {        perror("bind error");        return false;    }    if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one))) {        perror("setsockopt SO_REUSEADDR");        return false;    }    if (setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &one, sizeof(one))) {        perror("setsockopt SO_REUSEPORT");        return false;    }        memset((char *) &serv_addr, 0, sizeof(serv_addr));    serv_addr.sin_family = AF_INET;    serv_addr.sin_addr.s_addr = htonl(INADDR_BROADCAST);    serv_addr.sin_port = htons(IPPORT_BOOTPS);    // Fill in the BOOTP request    bzero(&bootp_xmit, sizeof(bootp_xmit));    if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) {        perror("SIOCGIFHWADDR");        return false;    }    bootp_xmit.bp_htype = HTYPE_ETHERNET;    bootp_xmit.bp_hlen = IFHWADDRLEN;    bcopy(ifr.ifr_hwaddr.sa_data, &bootp_xmit.bp_chaddr, bootp_xmit.bp_hlen);    bootp_xmit.bp_secs = 0;    bcopy(mincookie, bootp_xmit.bp_vend, sizeof(mincookie));    bootp_xmit.bp_op = BOOTREQUEST;    if(sendto(s, &bootp_xmit, sizeof(struct bootp), 0,               (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {        perror("sendto error");        return false;    }    tv.tv_sec = 5;    tv.tv_usec = 0;    setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));    addrlen = sizeof(bootp_server_addr);    if (recvfrom(s, recv, sizeof(struct bootp), 0,                 (struct sockaddr *)&bootp_server_addr, &addrlen) < 0) {        // This is an "acceptable" error, it means there is no server for        // us: do not initialize the interface.        retcode = false;    }    // Shut things down regardless of success of rx, otherwise other    // interfaces cannot be initialised!    memset(addrp, 0, sizeof(*addrp));    addrp->sin_family = AF_INET;    addrp->sin_len = sizeof(*addrp);    addrp->sin_port = 0;    addrp->sin_addr.s_addr = INADDR_ANY;    strcpy(ifr.ifr_name, intf);    if (ioctl(s, SIOCDIFADDR, &ifr)) {        perror("SIOCDIFADDR");    }    // Shut down interface so it can be reinitialized    ifr.ifr_flags &= ~(IFF_UP | IFF_RUNNING);    if (ioctl(s, SIOCSIFFLAGS, &ifr)) {        perror("SIOCSIFFLAGS");        return false;    }    // All done with socket    close(s);    return retcode;}static char *_bootp_op[] = {"", "REQUEST", "REPLY"};static char *_bootp_hw_type[] = {"", "Ethernet", "Exp Ethernet", "AX25",                                     "Pronet", "Chaos", "IEEE802", "Arcnet"};static char *_dhcpmsgs[] = {"","DISCOVER", "OFFER", "REQUEST", "DECLINE",                           "ACK", "NAK", "RELEASE" };voidshow_bootp(const char *intf, struct bootp *bp){    int i, len;    unsigned char *op, *ap = 0, optover;    unsigned char name[128];    struct in_addr addr[32];    unsigned int length;        diag_printf("BOOTP[%s] op: %s\n", intf, _bootp_op[bp->bp_op]);    diag_printf("       htype: %s\n", _bootp_hw_type[bp->bp_htype]);    diag_printf("        hlen: %d\n", bp->bp_hlen );    diag_printf("        hops: %d\n", bp->bp_hops );    diag_printf("         xid: 0x%x\n", bp->bp_xid );    diag_printf("        secs: %d\n", bp->bp_secs );    diag_printf("       flags: 0x%x\n", bp->bp_flags );    diag_printf("       hw_addr: ");    for (i = 0;  i < bp->bp_hlen;  i++) {        diag_printf("%02x", bp->bp_chaddr[i]);        if (i != (bp->bp_hlen-1)) diag_printf(":");    }    diag_printf("\n");    diag_printf("     client IP: %s\n", inet_ntoa(bp->bp_ciaddr));    diag_printf("         my IP: %s\n", inet_ntoa(bp->bp_yiaddr));    diag_printf("     server IP: %s\n", inet_ntoa(bp->bp_siaddr));    diag_printf("    gateway IP: %s\n", inet_ntoa(bp->bp_giaddr));    optover = 0; // See whether sname and file are overridden for options    length = sizeof(optover);    (void)get_bootp_option( bp, TAG_DHCP_OPTOVER, &optover, &length );    if ( !(1 & optover) && bp->bp_sname[0] )        diag_printf("        server: %s\n", bp->bp_sname);    if ( ! (2 & optover) && bp->bp_file[0] )        diag_printf("          file: %s\n", bp->bp_file);    if (bp->bp_vend[0]) {        diag_printf("  options:\n");        op = &bp->bp_vend[4];        while (*op != TAG_END) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -