I'm writing a program that parses tcpdump output files. I have a tab delimited text file that contains MAC addresses and hostnames.

How can I have the program search this file for a MAC address and then return the corresponding hostname?

Any help would be appreciated.

Thanks.

This is the basic idea, you might have to modify it to suit yourself, such as do error checking and trim whitespace from end of the mac address after extracting it from the line.

std::string foo(std::string search)
{

std::string line;
ifstream in("filename.txt");
while( getline(in, line) )
{
   size_t pos = line.find('\t');
   std::string mac = line.substr(0,line);
   if( mac == search )
   {
      return line.substr(pos+1);
   }
}

Edited 6 Years Ago by Ancient Dragon: n/a

It works, but I'm having a strange issue when I print the results.

Here's what I have:

cout << "    Eth:    From:    " << source << "    (" << search_eaddr(source) << ")" << endl;

Here's what it looks like when it prints on the screen:

)       Eth:    From:    08:00:20:78:97:b2    (prime

Why is that second parenthesis going to the beginning of the line?

Thanks.

This is all that's in the input file that I'm using for the search:

00:00:0c:76:3d:c6    sisko2

00:00:c0:95:57:4b    mach

00:00:d0:00:80:05    oucsnet

00:00:e8:a0:06:e2    br209a

00:00:e8:a0:06:f3    kitten24

00:00:e8:a0:07:44    br209c

00:00:e8:a0:07:4a    puppy01

00:00:e8:a0:07:ce    puppy24

00:00:e8:a0:0a:30    puppy10

00:00:e8:a0:0c:64    puppy12

00:00:e8:a0:0d:31    cub11

00:00:e8:a0:0e:4a    puppy03

00:00:e8:a0:0f:b5    107mort1

00:00:e8:a0:0f:d0    puppy05

00:00:e8:a0:10:2d    puppy14

00:00:e8:a0:12:75    puppy21

00:00:e8:a0:13:69    br206b

00:00:e8:a0:14:05    puppy08

00:00:e8:a0:14:9c    br208a

00:00:e8:a0:14:ad    puppy18

00:00:e8:a0:16:92    puppy16

00:00:e8:a0:16:df    puppy11

00:00:e8:a0:17:83    puppy02

I just did a copy and paste.

In the actual file, there is not gap between lines.

Here's the search code:

string search_eaddr(string search)
{
    string line;
    ifstream in("eaddr.txt");
    while (!in.eof())
    {
        getline(in,line);
        size_t pos = line.find('\t');
        string mac = line.substr(0, pos);

        if(mac == search)
            return line.substr(pos + 1);    
    }
    return "";
}

Here is where the search string is generated and the output is printed:

char source[17], dest[17];

    sprintf(source, "%02x:%02x:%02x:%02x:%02x:%02x", eth.esrc[0], eth.esrc[1], \
        eth.esrc[2], eth.esrc[3], eth.esrc[4], eth.esrc[5]);
    
    sprintf(dest, "%02x:%02x:%02x:%02x:%02x:%02x", eth.edst[0], eth.edst[1], \
        eth.edst[2], eth.edst[3], eth.edst[4], eth.edst[5]);

    cout << "    Eth:    From:    " << source << "    (" << search_eaddr(source) << ")" << endl;
    cout << "        To:    " << dest << "    (" << search_eaddr(dest) << ")" << endl;

why do instructors insist on teaching while( !in.eof()) instead of while( getline(in, line) ) ? eof() doesn't work like that and cause the while loop to loop too many times.


You should probably attach the input file rather than trying to paste its contents into the editor because the editor. The file contents you posted does not contain tabs -- just spaces.

Edited 6 Years Ago by Ancient Dragon: n/a

Here is the full code, and the test file used for the search is attached.

#include <iostream>
#include <fstream>
#include <sstream>
#include <time.h>
#include <cstring>
#include "pdump.h"

using namespace std;

struct dump_file_header hdr;        // Initialize Dump File Header Structure 
struct dump_header dhdr;        // Initialize Dump Header Structure 
struct ether_header eth;        // Initialize Ethernet Header Structure
struct arp_header arp;            // Initialize ARP Header Structure
struct ip_header ip;            // Initialize Internet Protocol Structure

void frame_info();            // Declare function to print frame information
void eth_hdr();                // Declare function to print ethernet header
void arp_hdr();                // Declare function to print ARP header
void ip_hdr();                // Declare function to print IP header
void clear_eth_only_buffer();        // Declare function to clear buffer after printing ethernet header only
void clear_arp_buffer();        // Declare function to clear buffer after printing ARP header
void clear_ip_buffer();            // Declare function to clear buffer after printing IP header
string search_eaddr(string, string);    // Declare function to perform MAC to hostname lookup

FILE *input, *input2;            // Declare global variables for reading input files

unsigned char buff, array[1500];    // Declare global variables that will be used to clear buffer

int bit_swap;                // Declare global variable to indicate "endian" of dump file
string hostfile;            // Declare global variable to store name of file containing MAC to hostname list

int main(int argc, char *argv[])
{
    int count = 0;

    if (argc < 2 || argc > 3)    // Checks the number of arguments entered by user
    {
        // If too many or too few arguments provided, program usage will be displayed.
        printf("\n    Usage: %s <dump_filename> (host_filename) \n\n", argv[0]);
        return 1;
    }
    
    if (argc == 3)            // Checks if MAC to hostname file provided
    {
        input2 = fopen(argv[2], "r");    // Verifies that MAC to hostname file exists and can be opened.
        if(fopen == NULL)
        {
            printf("Cannot open host list\n");
            return 1;
        }
        else
        {
            hostfile = argv[2];
            fclose(input2);        // Closes MAC to hostname file after verification
        }
    }

    input = fopen(argv[1], "rb");    // Verifies that dump file can be opened

    if(fopen == NULL)
    {
        printf("Cannot open saved dump file\n");
        return 1;
    }
    else
    {
        fread((char *) &hdr, sizeof(hdr), 1, input);    // Reads packet header information
    
        if (hdr.magic != TCPDUMP_MAGIC && hdr.magic != TCPDUMP_MAGIC_BIG)    // Checks for Magic Number
        {
            printf("Invalid Magic Number.  Verify that supplied file is a valid tcpdump file.");
            return 1;
        }
        else if (hdr.magic == TCPDUMP_MAGIC_BIG)    // Checks endian of file by looking at Magic Number
        {
            bit_swap = 1;                // Flag tells program that bit swapping is necessary
        }
                    
        while(fread((char *) &dhdr, sizeof(dhdr), 1, input))    // Use While loop used to set the packet boundary
        {
            ++count;    // Increments count variable

            printf("Packet %d \n", count);     // Displays packet number
            
            frame_info();        // Calls function to display frame information
            eth_hdr();        // Calls function to display ethernet header information
                          
            printf("\n ");        // Adds blank line in between packet information
               
        } // end while loop
    } // end main else
          
    fclose(input); // Closes dump file
             
    return 0;
}

void frame_info()    // Function for displaying frame information
{
    if (bit_swap == 0)    // Checks endian flag to see if bit swapping is necessary
    {
        printf("    Packet Length %u (%u) \n", dhdr.caplen, dhdr.len);    // Prints packet length
                                            // captured size (off wire packet size)

        time_t newtime;                    // Creates new time_t variable for converting timestamp
        newtime = time_t (dhdr.ts_secs);        // Copies timestamp (in seconds) to time_t variable

        struct tm * timeinfo;                // Creates structure for new date/time format
        timeinfo = localtime (&newtime);        // Converts timestamp in seconds since epoch to date/time format

        char buffer[30];
        strftime(buffer, 30, "    Collected: %a %b %d %X", timeinfo);    // Formats date/time for output

        cout << buffer << "." << dhdr.ts_usecs << endl;        // Prints timestamp in formated form, including milliseconds
                            
    }
    else
    {
        printf("    Packet Length %u (%u) \n", SWAPLONG(dhdr.caplen), SWAPLONG(dhdr.len));    // Performs bit swap before 
                                                    // printing packet length

        time_t newtime;                    // Creates new time_t variable for converting timestamp
        newtime = time_t (SWAPLONG(dhdr.ts_secs));    // Performs bit swap, then copies timestamp (in seconds) to time_t variable

        struct tm * timeinfo;                // Creates structure for new date/time format
        timeinfo = localtime (&newtime);        // Converts timestamp in seconds since epoch to date/time format

        char buffer[80];                
        strftime(buffer, 80, "    Collected: %a %b %d %X", timeinfo);    // Formats date/time for output

        cout << buffer << "." << SWAPLONG(dhdr.ts_usecs) << endl;    // Performs bit swap on milliseconds variable
                            //Prints timestamp in formated form, including milliseconds                
    }
}

void eth_hdr()        // Function for printing ethernet header information
{

    string shost = "", dhost = "";

    fread((char *) &eth, sizeof(eth), 1, input);    // Read ethernet header information

    char source[17], dest[17];

    sprintf(source, "%02x:%02x:%02x:%02x:%02x:%02x", eth.esrc[0], eth.esrc[1], \
        eth.esrc[2], eth.esrc[3], eth.esrc[4], eth.esrc[5]);    // Concatenates seperate ethernet address variables into a single string
    
    sprintf(dest, "%02x:%02x:%02x:%02x:%02x:%02x", eth.edst[0], eth.edst[1], \
        eth.edst[2], eth.edst[3], eth.edst[4], eth.edst[5]);    // Concatenates seperate ethernet address variables into a single string

    if (hostfile != "")    // Checks if a MAC to hostname list file was provided
    {
        shost = search_eaddr(source, hostfile);        // Performs lookup against list file to display hostnames
        dhost = search_eaddr(dest, hostfile);
    }

    cout << "    Eth:    From:    " << source << "    (" << shost << ")" << endl;    // Prints ethernet source address
    cout << "        To:    " << dest << "    (" << dhost << ")" << endl;        // Prints ethernet destination address

    eth.etype = SWAPSHORT(eth.etype);    // Performs bit swap (regardless of endian) in preparation to display ethernet type

    switch (eth.etype)
    {
        case ETHERTYPE_IP:        // If type IP, runs function to print IP header information
            printf("        Type:    %#04x    (IP) \n", eth.etype);
            ip_hdr();
            break;
        case ETHERTYPE_ARP:        // If type ARP, runs function to print ARP header information
            printf("        Type:    %#04x    (ARP) \n", eth.etype);
            arp_hdr();
            break;
        case ETHERTYPE_RARP:        // If type RARP, runs function to print ARP header information
            printf("        Type:    %#04x     (RARP) \n", eth.etype);
            arp_hdr();
            break;
        default:            // If any other type, only prints ethernet header information and move to next packet
            printf("        Type:    %#04x    (OTHER) \n", eth.etype);
            clear_eth_only_buffer();
            break;
    }

    
}

void arp_hdr()        // Function to print ARP header information
{
    string shost = "", dhost = "";

    fread((char *) &arp, sizeof(arp), 1, input);    // Reads ARP header

    printf("    ARP:    HW type: %x \n", arp.arp_htype[1]);    // Prints ARP hardware type number

    switch (arp.arp_oper[1])    // Checks ARP operation
    {
        case 1:        // Operation type 1 displays "request"
            printf("        OP: %x    (request) \n", arp.arp_oper[1]);
            break;
        case 2:        // Operation type 2 displays "reply"
            printf("        OP: %x    (reply) \n", arp.arp_oper[1]);
            break;
        default:    // Any other operation type is invalid, but number will display for debugging purposes
            printf("        OP: %x    (invalid operation) \n", arp.arp_oper[1]);
            break;
    }

    char source[17], dest[17];

    sprintf(source, "%02x:%02x:%02x:%02x:%02x:%02x", arp.arp_hwsrc[0], arp.arp_hwsrc[1], \
        arp.arp_hwsrc[2], arp.arp_hwsrc[3], arp.arp_hwsrc[4], arp.arp_hwsrc[5]);
                            // Concatenates seperate ethernet address variables into a single string
    
    sprintf(dest, "%02x:%02x:%02x:%02x:%02x:%02x", arp.arp_hwdst[0], arp.arp_hwdst[1], \
        arp.arp_hwdst[2], arp.arp_hwdst[3], arp.arp_hwdst[4], arp.arp_hwdst[5]);
                            // Concatenates seperate ethernet address variables into a single string

    if (hostfile != "")    // Checks if a MAC to hostname list file was provided
    {
        shost = search_eaddr(source, hostfile);        // Performs lookup against list file to display hostnames
        dhost = search_eaddr(dest, hostfile);
    }

    cout << "        Hardware:    " << source << "    (" << shost << ")" << endl;    // Prints source hardware address
    cout << "            ==>    " << dest << "    (" << dhost << ")" << endl;    // Prints destination hardware address

    printf("        Protocol:    %d.%d.%d.%d \n", arp.arp_prosrc[0], arp.arp_prosrc[1], \
        arp.arp_prosrc[2], arp.arp_prosrc[3]);        // Prints source protocol address
    printf("            ==>    %d.%d.%d.%d \n", arp.arp_prodst[0], arp.arp_prodst[1], \
        arp.arp_prodst[2], arp.arp_prodst[3]);        // Prints destination protocol address

    clear_arp_buffer();    // Calls function to clear remainder of packet from buffer
}


void ip_hdr()        // Function to print IP header information
{
    fread((char *) &ip, sizeof(ip), 1, input);    // Reads IP header

    printf("    IP:    Vers:    %x \n", IP_V(&ip));    // Prints IP version 
    printf("        Hlen:    %d \n", IP_HL(&ip)*4);    // Prints IP header length

    printf("        Src:    %d.%d.%d.%d \n", ip.ip_src[0], ip.ip_src[1], \
        ip.ip_src[2], ip.ip_src[3]);    // Prints source IP address
    printf("        Dest:    %d.%d.%d.%d \n", ip.ip_dst[0], ip.ip_dst[1], \
        ip.ip_dst[2], ip.ip_dst[3]);    // Prints destination IP address

    printf("        TTL:    %d \n", ip.ip_ttl);    // Prints IP Time to Live (TTL)

    switch (ip.ip_proto)        // Determines type of information in IP packet
    {
        case IPPROTO_ICMP:    // For ICMP packets
            printf("        Type:    %#x    (ICMP) \n", ip.ip_proto);
            break;
        case IPPROTO_TCP:    // For TCP packets
            printf("        Type:    %#x    (TCP) \n", ip.ip_proto);
            break;
        case IPPROTO_UDP:    // For UDP packets
            printf("        Type:    %#x    (UDP) \n", ip.ip_proto);
            break;
        default:        // Any other types, only type number will be displayed.
            printf("        Type:    %#x \n", ip.ip_proto);
            break;
    }
    
    clear_ip_buffer();    // Calls function to clear remainder of packet from buffer
            
}

void clear_eth_only_buffer()    // Function to clear packet from buffer after only displaying ethernet header
{
    if (bit_swap == 0)
    {
        for (int i = 0; i < dhdr.caplen -14; i++)    // Remaining packet size is total length minus ethernet header size
               {
            fread((char *) &buff, sizeof(buff), 1 , input);
                    array[i] = buff;        // Empties buffer into a character array
               }
    }
    else
    {
        for (int i = 0; i < SWAPLONG(dhdr.caplen) -14; i++)    // Performs bit swap before determining packet size
               {
            fread((char *) &buff, sizeof(buff), 1 , input);
                    array[i] = buff;        // Empties buffer into a character array
               }
    }
}

void clear_arp_buffer()        // Function to clear packet from buffer after displaying ethernet header and ARP header
{

    if (bit_swap == 0)
    {
              for (int i = 0; i < dhdr.caplen -42; i++)    // Remaining packet size is total length minus ethernet header + ARP header
               {
            fread((char *) &buff, sizeof(buff), 1 , input);
                    array[i] = buff;        // Empties buffer into a character array
               }
    }
    else
    {
              for (int i = 0; i < SWAPLONG(dhdr.caplen) -42; i++)    // Performs bit swap before determining packet size
               {
            fread((char *) &buff, sizeof(buff), 1 , input);
                    array[i] = buff;        // Empties buffer into a character array
               }
    }
}

void clear_ip_buffer()        // Funcation to clear packet from buffer after displaying ethernet header and IP header
{

    if (bit_swap == 0)
    {
              for (int i = 0; i < dhdr.caplen -34; i++)    // Remaining packet size is total length minus ethernet header + IP header
               {
            fread((char *) &buff, sizeof(buff), 1 , input);
                    array[i] = buff;        // Empties buffer into a character array
               }
    }
    else
    {
              for (int i = 0; i < SWAPLONG(dhdr.caplen) -34; i++)    // Performs bit swap before determining packet size
               {
            fread((char *) &buff, sizeof(buff), 1 , input);
                    array[i] = buff;        // Empties buffer into a character array
               }
    }
}

string search_eaddr(string search, string hostfile)    // Function to perform lookup in provided MAC to hostname file
{
    string line;
    ifstream in(hostfile.c_str());

    while (getline(in,line))    // Reads each line of the file
    {
        size_t pos = line.find('\t');    // Finds tab delimiter
        string mac = line.substr(0, pos);    // Sets MAC address as portion before tab

        if(mac == search)    // Compares MAC address with search criteria
            return line.substr(pos+1);    // If found, will return the hostname after the tab
    }
    return "";    // If no match found, will return an empty string
}
Attachments
00:00:0c:76:3d:c6	sisko2
00:00:c0:95:57:4b	mach
00:00:d0:00:80:05	oucsnet
00:00:e8:a0:06:e2	br209a
00:00:e8:a0:06:f3	kitten24
00:00:e8:a0:07:44	br209c
00:00:e8:a0:07:4a	puppy01
00:00:e8:a0:07:ce	puppy24
00:00:e8:a0:0a:30	puppy10
00:00:e8:a0:0c:64	puppy12
00:00:e8:a0:0d:31	cub11
00:00:e8:a0:0e:4a	puppy03
00:00:e8:a0:0f:b5	107mort1
00:00:e8:a0:0f:d0	puppy05
00:00:e8:a0:10:2d	puppy14
00:00:e8:a0:12:75	puppy21
00:00:e8:a0:13:69	br206b
00:00:e8:a0:14:05	puppy08
00:00:e8:a0:14:9c	br208a
00:00:e8:a0:14:ad	puppy18
00:00:e8:a0:16:92	puppy16
00:00:e8:a0:16:df	puppy11
00:00:e8:a0:17:83	puppy02
00:00:e8:a0:18:75	puppy19
00:00:e8:a0:19:61	puppy17
00:00:e8:a0:1b:34	puppy20
00:00:e8:a0:1b:76	br206a
00:00:e8:a0:1b:fe	puppy07
00:00:e8:a0:1c:61	puppy09
00:00:e8:a0:1c:a2	puppy06
00:00:e8:a0:1c:a7	aizicovici
00:00:e8:a0:1c:fc	puppy04
00:40:27:01:df:3c	hub426
00:40:33:21:0a:21	mort558
00:40:f6:60:c3:49	lab0104
00:40:f6:60:c3:96	swardson
00:60:8c:c9:95:45	qvu
00:60:b0:1d:e9:8b	hplj4j
00:60:b0:52:3b:0d	hplj4h
00:60:b0:52:db:4e	hplj4i
00:a0:24:13:fc:50	lab0112
00:a0:24:24:06:9e	gillam
00:a0:24:24:08:86	kit02
00:a0:24:24:08:ba	kit03
00:a0:24:24:09:64	irwin
00:a0:24:24:09:82	kit01
00:a0:24:24:ab:3f	kit04
00:a0:24:81:2f:d1	kat01
00:a0:24:81:2f:d8	kat03
00:a0:24:94:7b:04	mort142
00:a0:24:94:7b:0d	kat04
00:a0:24:94:7c:44	kat05
00:a0:24:94:8a:4a	kat02
00:a0:24:94:8c:fa	seccy2
00:a0:24:94:92:12	seccy1
00:aa:00:0c:06:25	mort214a
00:aa:00:0c:4b:60	kitten22
00:aa:00:0c:4c:77	mort148
00:aa:00:0c:52:bc	br209d
00:aa:00:0d:8b:e4	cub22
00:aa:00:0d:8e:e1	cub02
00:aa:00:0d:9c:78	cub21
00:aa:00:12:d4:a6	cub10
00:aa:00:12:d5:28	cub09
00:aa:00:12:d8:b5	cub14
00:aa:00:12:d8:df	cs-office
00:aa:00:17:47:f9	pctest
00:aa:00:19:47:2c	cub08
00:aa:00:19:47:ad	cub20
00:aa:00:19:47:de	cub19
00:aa:00:19:49:ad	cub07
00:aa:00:19:49:ae	cub18
00:aa:00:19:49:cd	cub13
00:aa:00:19:49:d2	cub15
00:aa:00:19:58:18	cub17
00:aa:00:19:58:51	cub05
00:aa:00:19:59:76	cub03
00:aa:00:19:59:83	cub04
00:aa:00:19:5a:5a	cub16
00:aa:00:19:5b:b0	cub06
00:aa:00:19:5b:e5	cub12
00:aa:00:24:3f:13	br209b
00:aa:00:2f:3c:77	mathdept4
00:aa:00:46:80:a2	kitten04
00:aa:00:46:82:1b	kitten03
00:aa:00:46:86:b4	kitten21
00:aa:00:46:87:6a	kitten10
00:aa:00:46:b2:cd	theory
00:aa:00:46:c6:13	kitten20
00:aa:00:46:d2:06	kitten12
00:aa:00:46:d3:be	kitten09
00:aa:00:46:d3:c8	kitten11
00:aa:00:46:d4:b5	kitten19
00:aa:00:46:d4:b6	kitten06
00:aa:00:46:e5:a1	kitten07
00:aa:00:46:e5:ea	kitten02
00:aa:00:46:e6:7b	kitten13
00:aa:00:46:e7:a3	kitten17
00:aa:00:46:e7:aa	kat02
00:aa:00:46:e7:aa	kitten08
00:aa:00:46:e9:63	kitten15
00:aa:00:46:eb:2a	kitten14
00:aa:00:46:ec:27	kitten01
00:aa:00:46:ec:7f	kitten16
00:aa:00:46:ec:86	wicke
00:aa:00:46:f0:17	kitten18
02:60:8c:38:57:06	br204
02:60:8c:8f:81:62	puppy15
08:00:07:94:b3:78	quadra
08:00:07:af:9e:7f	grover
08:00:09:26:7b:3c	brhp202
08:00:09:26:92:1c	hp422
08:00:09:49:d4:f9	hp114
08:00:09:57:cb:c9	hplj4d
08:00:09:57:db:63	hplj4g
08:00:09:57:eb:de	hplj4f
08:00:09:74:21:20	hplj4e
08:00:09:95:fb:46	hp426
08:00:09:f7:3c:3f	lab01prt2
08:00:09:f7:6a:cc	hpcolor
08:00:20:09:99:75	levant
08:00:20:0e:e1:93	ra
08:00:20:0f:1a:be	oucsace
08:00:20:19:bb:fb	parallel3
08:00:20:19:bc:77	parallel2
08:00:20:1b:43:b2	td
08:00:20:1b:4b:f4	topdog
08:00:20:1b:66:e2	monsoon
08:00:20:1f:9d:94	parallel4
08:00:20:23:0e:68	boss
08:00:20:23:0e:68	boss2
08:00:20:23:0e:68	homeip
08:00:20:76:49:ab	bing
08:00:20:78:97:b2	prime
08:00:20:78:9a:a3	fac061
08:00:20:78:ec:7f	fac019
08:00:20:78:fa:e2	big
08:00:20:79:8d:2c	fac041
08:00:20:79:8d:66	fac003
08:00:20:7a:41:53	fac067
08:00:20:7a:da:c8	fac059
08:00:20:7a:dc:ce	fac017
08:00:20:7a:dc:f3	snowflake
08:00:20:7a:dd:3e	fac071
08:00:20:7a:dd:d0	fac005
08:00:20:7a:de:6e	fac031
08:00:20:7a:e0:aa	fac037
08:00:20:7a:e8:d3	fac001
08:00:20:7a:ea:54	fac007
08:00:20:7a:ea:92	fac047
08:00:20:7a:eb:16	fac013
08:00:20:7a:eb:19	fac002
08:00:20:7a:eb:32	fac029
08:00:20:7a:eb:55	fac023
08:00:20:7a:eb:b3	fac011
08:00:20:7a:eb:c9	fac053
08:00:20:7a:eb:cb	fac073
08:00:20:7a:eb:cb	roadkill
08:00:20:7b:0a:ff	fac043
08:00:20:80:a3:10	leon
08:00:20:81:52:ff	endor
08:00:20:85:9c:83	even04
08:00:20:85:ae:4a	even16
08:00:20:85:b4:0c	even18
08:00:20:85:b5:1c	even20
08:00:20:85:b9:b8	even30
08:00:20:85:f6:50	even32
08:00:20:86:02:e3	roadkill
08:00:20:86:0d:03	even26
08:00:20:86:0d:0f	even10
08:00:20:86:0d:1a	even14
08:00:20:86:0d:e2	even34
08:00:20:86:0e:1c	even38
08:00:20:86:1e:bb	even02
08:00:20:86:1f:18	even40
08:00:20:86:1f:82	instruct1
08:00:20:86:1f:93	even06
08:00:20:86:1f:9e	even36
08:00:20:86:2b:dc	even12
08:00:20:86:7a:06	even24
08:00:20:86:7f:ef	even42
08:00:20:86:83:63	roadpizza
08:00:20:86:83:a0	even22
08:00:20:86:83:d4	even28
08:00:20:87:94:47	even08
08:00:2b:17:94:43	bird23
08:00:2b:1a:8f:69	bird09
08:00:2b:1a:90:3e	bird10
08:00:2b:1a:90:45	bird03
08:00:2b:1b:aa:60	bird01
08:00:2b:1b:b4:75	bird07
08:00:2b:1b:b7:2c	bird15
08:00:2b:1b:b8:94	bird21
08:00:2b:1b:bc:88	bird14
08:00:2b:1b:bc:a2	bird13
08:00:2b:1b:bd:08	bird08
08:00:2b:1b:bd:3c	bird12
08:00:2b:1b:bd:d8	bird05
08:00:2b:1b:be:cc	bird02
08:00:2b:1b:be:dd	bird22
08:00:2b:1b:c1:65	chelb1
08:00:2b:1b:c1:a6	bird04
08:00:2b:1d:e0:cc	bigbird
80:00:10:03:00:f2	brandx
aa:00:04:00:fc:b5	gateway1
08:00:20:22:46:6a	jarok
aa:00:04:00:fd:b5	oldgateway
08:00:20:1b:42:d0	elvis
08:00:09:94:b6:f5	rarpme
80:00:10:03:00:00	view
ff:ff:ff:ff:ff:ff	BROADCAST

A suggestion, you might use stringstream for extracting the two fields, that would work for both TAB and SPACE -separated fields.
That would be along the lines of ..

#include <sstream> // for stringstream

// Function to perform lookup in provided MAC to hostname file
string search_eaddr(const string & search, const string & hostfile)
{
  ifstream in(hostfile.c_str());

  if(!in)
  {
    // Error, do something here ...
  }

  string line;
  while (getline(in,line))
  {
    // Stuff the line into the stream
    stringstream ss(line);
    string mac, host;

    // Extract, note that any trailing whitespace will NOT end up in 'host'
    if(ss >> mac >> host)
    {
      if(mac == search)
        return host;
    }
  }
  return "";    // If no match found, will return an empty string
}

Then a couple of things .. this

if (argc < 2 || argc > 3)    // Checks the number of arguments entered by user
{
  // If too many or too few arguments provided, program usage will be displayed.
  printf("\n    Usage: %s <dump_filename> (host_filename) \n\n", argv[0]);
  return 1;
}
if (argc == 3) // Checks if MAC to hostname file provided
{
   ...

could be simplified to

// Checks the number of arguments entered by user
if(argc != 3)
{
  // complain here and return 
  return 1;
}

Then instead of

input2 = fopen(argv[2], "r");    // Verifies that MAC to hostname file exists and can be opened.
if(fopen == NULL)
{
  printf("Cannot open host list\n");
  return 1;
}

you definitely want to have

input2 = fopen(argv[2], "r");    // Verifies that MAC to hostname file exists and can be opened.
// Check input2, NOT fopen
if(input2 == NULL)
{
  printf("Cannot open host list\n");
  return 1;
}

Then

  • Your source and dest buffers are too small, you need more than 17 bytes, don't forget the terminating '\0' added by sprintf()
  • You might check that every fread() call actually reads the expected amount of data.
  • Magic numbers (14, 32, 42) could be avoided.

Changing the code to using stringstream fixed my strange parenthesis issue.

I also updated the code per your suggestions.

Thanks for your help!

A suggestion, you might use stringstream for extracting the two fields, that would work for both TAB and SPACE -separated fields.
That would be along the lines of ..

#include <sstream> // for stringstream

// Function to perform lookup in provided MAC to hostname file
string search_eaddr(const string & search, const string & hostfile)
{
  ifstream in(hostfile.c_str());

  if(!in)
  {
    // Error, do something here ...
  }

  string line;
  while (getline(in,line))
  {
    // Stuff the line into the stream
    stringstream ss(line);
    string mac, host;

    // Extract, note that any trailing whitespace will NOT end up in 'host'
    if(ss >> mac >> host)
    {
      if(mac == search)
        return host;
    }
  }
  return "";    // If no match found, will return an empty string
}
This question has already been answered. Start a new discussion instead.