#include "pcapio.h"
#include <pcap.h>
#include <string.h>
namespace PCAPIO{

std::string ifaddresses(pcap_if_t *d);

std::string pcapio_interfaces(std::map<std::string,std::string> & devmap)
{
    std::string res;
    pcap_if_t *alldevs;
    char errbuf[PCAP_ERRBUF_SIZE];
    if(pcap_findalldevs(&alldevs, errbuf) == -1){
        res = errbuf;
        return res;
    }
    for(auto d = alldevs; d != NULL; d = d->next){
        std::string d_name = d->name;
        std::string d_des = ifaddresses(d);
        devmap[d_name] = d_des;
    }

    pcap_freealldevs(alldevs);
    return res;
}
std::string address_print(unsigned char * v)
{
    std::string res;
    char buf[1024];
    res += "HEX(";
    for (unsigned char i =0; i<sizeof(sockaddr::sa_data);++i)
    {
        if (i)   res += ":";
        snprintf(buf,1024,"%02X", (unsigned int)v[i]);
        res += buf;
    }
    res += ")";
    res += "DEC(";
    for (unsigned char i =0; i<sizeof(sockaddr::sa_data);++i)
    {
        if (i)   res += ":";
        snprintf(buf,1024,"%03u", (unsigned int)v[i] );
        res += buf;
    }
    res += ")";

    return res;
}
/* Print all the available information on the given interface */
std::string ifaddresses(pcap_if_t *d)
{
    char buf[1024];
    pcap_addr_t *a;
    std::string res = "NAME=";
    res+=d->name;
    res += "\n";
    if(d->description)
    {
        res += "Description=";
        res += d->description;
        res += "\n";
    }

    for(a=d->addresses;a;a=a->next) {
        snprintf(buf,1024,"  AF_0x%02X:",(unsigned int)a->addr->sa_family);
        res += buf;
        if (a->addr)
        {
            snprintf(buf,1024,"\n    Addr:%s ",address_print((unsigned char *)a->addr->sa_data).c_str());
            res += buf;
        }
        if (a->netmask)
        {
            snprintf(buf,1024,"\n    Mask:%s ",address_print((unsigned char *)a->netmask->sa_data).c_str());
            res += buf;
        }
        if (a->broadaddr)
        {
            snprintf(buf,1024,"\n    Cast:%s ",address_print((unsigned char *)a->broadaddr->sa_data).c_str());
            res += buf;
        }
        if (a->dstaddr)
        {
            snprintf(buf,1024,"\n    Dest:%s ",address_print((unsigned char *)a->dstaddr->sa_data).c_str());
            res += buf;
        }
        res += "\n";
    }
    return res;
}
}

