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

📄 dhcp-rawnet.c

📁 this is sample about DHCP-agent
💻 C
📖 第 1 页 / 共 2 页
字号:
/* $Header: /cvsroot/dhcp-agent/dhcp-agent/src/dhcp-rawnet.c,v 1.12 2003/07/06 05:37:23 actmodern Exp $ * * Copyright 2002 Thamer Alharbash * * 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. The names of the authors may not be used to endorse or promote * products derived from this software without specific prior * written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * * Raw network module. *  */#define MODULE_NAME "dhcp-rawnet"#include "dhcp-local.h"#include "dhcp-limits.h"#include "dhcp-libutil.h"#include "dhcp-librawnet.h"#include "dhcp-interface.h"/************************ * Address Manipulation.* ************************//* get IP address. */ip_addr_t rawnet_get_ip_addr(rawnet_t *net){    return net->cip_addr;}/* get port number for named service. */int rawnet_port_for_service(const char *serv, const char *proto){    struct servent *sv;    setservent(0);    if((sv = getservbyname(serv, proto)) == NULL) {        ERROR_MESSAGE("rawnet: could not get service listing: %d", strerror(errno));        return -1;    }    return (sv->s_port);}/* variation on network_addr_to_string in dhcp-convert.c we use * this when we don't want to run around freeing results up, and * know that it will be statically stored. Useful for insertion * in message log routines. */char *rawnet_network_address_to_string_static(uint32_t addr){    struct in_addr in;    in.s_addr = addr;    return (inet_ntoa(in));}/* * * * * * * * * * * * * * * Interface Manipulation. * * * * * * * * * * * * * * *//* get interface address. */int rawnet_get_hw_addr(rawnet_t *net, eth_addr_t *addr){    /* are we using a fake address? */    if(net->fake_hw_addr != NULL) {        memcpy(addr, &net->fake_hw_addr, ETH_ADDR_LEN);        return 0;    } else {        memcpy(addr, &net->chw_addr, ETH_ADDR_LEN);        return 0;    }}/* get real interface address skipping fake even if its available. */int rawnet_get_real_hw_addr(rawnet_t *net, eth_addr_t *addr){    return (eth_get(net->eth, addr));}/* bring up interface, and assign ourselves the address passed. */int rawnet_interface_up(rawnet_t *net, ip_addr_t addr, ip_addr_t netmask, int mtu, int set_address){    if(interface_up(net->intf_handle, addr, netmask, mtu, set_address)) {        ERROR_MESSAGE("could not bring interface up.");        return -1;    }    interface_get_ip_addr(net->intf_handle, &net->cip_addr);    xfree(net->packet_data);    net->packet_data = xmalloc(mtu);    return 0;}/* bring down interface. */int rawnet_interface_down(rawnet_t *net){    if(interface_down(net->intf_handle)) {        ERROR_MESSAGE("could not bring interface down.");        return -1;    }    memset(&net->cip_addr, 0, IP_ADDR_LEN); /* clear our IP address -- this isn't very useful though. */    return 0;}uint16_t rawnet_get_mtu(rawnet_t *net){    return interface_get_mtu(net->intf_handle);}list_t *rawnet_list_active_interfaces(void){    return (interface_get_active_interfaces());}list_t *rawnet_list_inactive_interfaces(void){    return (interface_get_inactive_interfaces());}/* * Initialization of packet capturing device. *  */static pcap_t *initialize_pcap_device(char *interface_name, int snaplen,                                       char *filter_string, int promiscuous){    pcap_t *pcap;    struct bpf_program filter;    char errbuf[PCAP_ERRBUF_SIZE];    uint32_t mask = 0xffffffff;#if defined(HAVE_BPF_IMMEDIATE)    int fd;    u_int on = 1;#endif                          /* HAVE_BPF_IMMEDIATE */    /* Open packet capturing device. */    pcap = pcap_open_live(interface_name, snaplen, promiscuous, 0, errbuf);    if(pcap == NULL) {        ERROR_MESSAGE("could not open pcap device: %s", pcap_geterr(pcap));        return NULL;    }    if(pcap_compile(pcap, &filter, filter_string, 1, mask) == -1) {        ERROR_MESSAGE("could not compile pcap filter: %s", pcap_geterr(pcap));        pcap_close(pcap);        return NULL;    }    if(pcap_setfilter(pcap, &filter) == -1) {        ERROR_MESSAGE("could not compile pcap filter: %s", pcap_geterr(pcap));        pcap_close(pcap);        return NULL;    }    /* looks like NetBSD ships with a libpcap that does not have     * pcap_freecode there's nothing we can do except not compile     * against it.  this unfortunately will probably introduce     * memory leaks :| */#ifdef HAVE_PCAP_FREECODE    pcap_freecode(&filter);#endif /* HAVE_PCAP_FREECODE */#if defined(HAVE_BPF_IMMEDIATE)    /* FreeBSD, and possibly other flavors with BPF need us to     * set the descriptor non blocking with BIOCIMMEDIATE. */    if((fd = pcap_fileno(pcap)) < 0) {        ERROR_MESSAGE("could not obtain pcap descriptor: %s", pcap_geterr(pcap));        pcap_close(pcap);        return NULL;    }    if(ioctl(fd, BIOCIMMEDIATE, &on) < 0) {        ERROR_MESSAGE("initialize_pcap_device", "could not set BIOCIMMEDIATE: %s", strerror(errno));        pcap_close(pcap);        return NULL;    }#endif                          /* HAVE_BPF_IMMEDIATE */    return pcap;}/* Create the workhorse raw network module. */rawnet_t *rawnet_create(const char *device, const char *filter, int mtu,                        int dhcp_src_port, int dhcp_dst_port, int promiscuous, int clear_address){    rawnet_t *net;    int retval;    net = xcalloc(sizeof(rawnet_t));    net->src_port = dhcp_src_port;    net->dst_port = dhcp_dst_port;    net->device = xstrdup(device);    net->pcap_filter = xstrdup(filter);    net->promiscuous = promiscuous;    net->mtu = mtu;    /* get the interface handle for bringing it up or down and querying it. */    net->intf_handle = create_interface_control(net->device);    if(net->intf_handle == NULL) {        ERROR_MESSAGE("could not acquire interface handle");        rawnet_destroy(net);        return NULL;    }    /* Is the interface up? */    retval = interface_is_up(net->intf_handle);    if(retval == -1) {        /* error on interface detection */        ERROR_MESSAGE("error on interface detection for device: %s", device);        rawnet_destroy(net);        return NULL;    }    if(retval == 0) {        /* interface down */        /* bring it up with dum values. */        if(rawnet_interface_up(net, 0, 0, net->mtu, clear_address)) {            ERROR_MESSAGE("error trying to bring device up: %s", device);            rawnet_destroy(net);            return NULL;        }    } else if(clear_address) {        /* interface down but we've been told to clear its address,         * so our caller wants us to initialize it either way. */        if(rawnet_interface_up(net, 0, 0, net->mtu, clear_address)) {            ERROR_MESSAGE("error trying to bring device up: %s", device);            rawnet_destroy(net);            return NULL;        }    }    if(net->mtu == -1)  { /* were we passed an mtu? */        /* if not get it from the interface that was just brought up. */        net->mtu = rawnet_get_mtu(net);    }    /* now allocate packet data since we know the mtu. */    net->packet_data = xcalloc(net->mtu);    /* any other value of retval and the interface is already up. */    /* Get the interface and make sure its an ethernet interface or     * else we're hosed. */    net->eth = eth_open(device);    if(net->eth == NULL) {        ERROR_MESSAGE("device not available or supported: %s : %s", device, strerror(errno));        rawnet_destroy(net);        return NULL;    }    /* get pcap handler */    net->pcap = initialize_pcap_device(net->device, net->mtu, net->pcap_filter, promiscuous);    if(net->pcap == NULL) {        ERROR_MESSAGE("could not initialize pcap device for: %s", device);        return NULL;    }    net->pcap_fd = pcap_fileno(net->pcap);    if(net->pcap_fd < 0) {        ERROR_MESSAGE("could not get pcap descriptor for: %s: %s", device, pcap_geterr(net->pcap));        rawnet_destroy(net);        return NULL;    }    /* store a copy of our hardware and ip address. */    eth_get(net->eth, &net->chw_addr);    interface_get_ip_addr(net->intf_handle, &net->cip_addr);    /* Packet handler objects.     *      * These exit on failure.     *      */    net->ether_p = eth_create();    net->ip_p = ip_create();    net->arp_p = arp_create();    net->icmp_p = icmp_create();    net->udp_p = udp_create();    net->dhcp_p = dhcp_create();    return net;}/* Use a fake hardware address (diagnostic purposes).  We need to * reinitialize our rawnet to use promiscuous packet capturing * since we do want to accept packets for this hardware * address. */int rawnet_use_fake_hw_addr(rawnet_t *net, char *mac_string){    unsigned char mac_addr[ETH_ADDR_LEN];    net->fake_hw_addr = xmalloc(sizeof(eth_addr_t));    if(hex_string_to_value(mac_string, mac_addr)) {        ERROR_MESSAGE("malformed mac address: %s", mac_string);        xfree(net->fake_hw_addr);        net->fake_hw_addr = NULL;        return -1;    }    memcpy(net->chw_addr.data, mac_addr, ETH_ADDR_LEN);    /* now reinitialize in promiscuous mode */    reinitialize_rawnet(net, 1);    return 0;}void rawnet_destroy(rawnet_t *net){    if(net->eth != NULL)        eth_close(net->eth);    if(net->intf_handle)        destroy_interface_control(net->intf_handle);    if(net->pcap != NULL)        pcap_close(net->pcap);    if(net->device)        xfree(net->device);    if(net->packet_data)        xfree(net->packet_data);    if(net->pcap_filter)        xfree(net->pcap_filter);    if(net->ether_p)        eth_destroy(net->ether_p);    if(net->ip_p)        ip_destroy(net->ip_p);    if(net->arp_p)        arp_destroy(net->arp_p);    if(net->icmp_p)

⌨️ 快捷键说明

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