Question

in a function, that gets unsigned char && unsigned char length,

void pcap_callback(u_char *args, const struct pcap_pkthdr* pkthdr, const u_char* packet) 
{
    std::vector<unsigned char> vec(packet, packet+pkthdr->len); // optimized from foo.
    std::stringstream scp;
    for (int i=0;i<pkthdr->len;i++) {
        scp<<vec[i];
    }
    std::string mystr =  std::string(scp.rdbuf()->str());
    std::cout << "WAS: " << packet << std::endl;
    std::cout << "GOOD: " << scp.str() << std::endl;
    std::cout << "BAD: "  << scp.str().c_str() << std::endl;
    std::cout << "TEST: " << mystr.size() << std::endl;
    assert(mystr.size() == pkthdr->len); 
}

Results:

  • WAS: prints nothing (guess there is a pointer to const.. case)
  • GOOD: prints data
  • BAD: prints nothing
  • TEST, assert: prints that mystr.size() is equal to passed unsigned char size.

I tried:

  • string.assign(scp.rdbuf());
  • memcpy(char, scp.str(), 10);
  • different methods of creating/allocating temporary chars, strings

No help.. it is wanted to get a std::cout'able std::string that contains data, (which was picked from foo, which was unsigned char, which was packet data).

Guessing either the original foo may not be null-terminated, or the problem is something like this - simple, but can't get in.. what are the things to look for here?

(this code is another attempt to use libpcap, just to print packets in C++ way, without using known C++ magic wrappers like libpcapp).

Was it helpful?

Solution

For a quick test, throw in a check for scp.str().size() == strlen(scp.str().c_str()) to see if there are embedded '\0' characters in the string, which is what I suspect is happening.

OTHER TIPS

I think you're going about this the wrong way. It looks like you're dealing with binary data here, in which case you can't expect to meaningfully output it to the screen as text. What you really need is a hex dump.

const unsigned char* ucopy = packet;
std::ios_base::fmtflags old_flags = std::cout.flags();
std::cout.setf(std::ios::hex, std::ios::basefield);

for (const unsigned char* p = ucopy, *e = p + pkthdr->len; p != e; ++p) {
    std::cout << std::setw(2) << std::setfill('0') << static_cast<unsigned>(*p) << " ";
}

std::cout.flags(old_flags);

This will output the data byte-by-byte, and let you examine the individual hex values of the binary data. A null byte will simply be output as 00.

Check std::cout.good() after the failed output attempt. My guess is that there's some failure on output (i.e. trying to write a nonprintable character to the console), which is setting failbit on cout.

Also check to ensure the string does not start with a NULL, which would cause empty output to be the expected behavior :)

(Side note, please use reinterpret_cast for unsigned char *ucopy = (unsigned char*)packet; if you're in C++ ;) )

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top