Beispiel #1
0
int main ( int argc, char ** argv )
{
    char      optChar;
    char    * target;
    int       optindx  = 0;
    int       interval = 0;
    int       count    = -1;
    int       timeout  = ICMP_TIMEOUT_SECS;
    bool      debug    = false;
    size_t    size     = 0;

    timeval   tvin, tvsnt, tvo;

    static struct option l_opts[] = { {"count", required_argument, 0, 'c'},
                                      {"debug", no_argument, 0, 'd'},
                                      {"interval", required_argument, 0, 'i'},
                                      {"help", no_argument, 0, 'h'},
                                      {"size", required_argument, 0, 's'},
                                      {"version", no_argument, 0, 'v'},
                                      {0,0,0,0}
                                    };

    if ( argc < 2 )
        usage();

    while ( (optChar = getopt_long(argc, argv, "c:di:hs:v", l_opts, &optindx)) != EOF )
    {
        switch ( optChar ) {
            case 'c':
                count = StringUtils::FromString<int>(optarg);
                break;
            case 'd':
                debug = true;
                break;
            case 'i':
                interval = StringUtils::FromString<int>(optarg);
                break;
            case 'h':
                usage();
                break;
            case 's':
                size = StringUtils::FromString<size_t>(optarg);
                break;
            case 'v':
                version();
                break;
            default:
                usage();
                break;
        }
    }

    target = strdup(argv[argc-1]);
    ::memset(&tvsnt, 0, sizeof(tvsnt));
    ::memset(&tvin, 0, sizeof(tvin));
    ::memset(&tvo, 0, sizeof(tvo));

    if ( interval == 0 )
        interval = 1000;

    std::string host = target;
    ::free(target);

    Pid  = ::getpid() & 0xFFFF;
    ::signal(SIGPIPE, SIG_IGN);
    ::signal(SIGINT,  &sigHandler);

    ipv4addr_t dstaddr = AddrInfo::GetHostAddr(host);

    if ( dstaddr == 0 ) {
        std::cout << "Invalid target host: " << host << std::endl;
        exit(-1);
    }

    Socket * icmps  = new Socket(dstaddr, SOCKET_ICMP, SOCKTYPE_RAW, SOCKET_ICMP);
    icmps->init(false);

    dropPriv();

    neticmp_h  * req     = NULL;
    icmp_ts    * its     = NULL;
    char       * wptr    = NULL;
    char       * wbuff   = NULL;
    char       * data    = NULL;
    const char * dt      = NULL;
    bool         sendReq = true;

    sockaddr_t   csock;
    sockaddr_in* sa;
    ipv4addr_t   addr;
    size_t       sz, buflen, idsz;
    ssize_t      wt, rd;
    int          cnt, sent, rcvd;
    float        mstot, avg;

    cnt    = 1;
    sent   = 0;
    rcvd   = 0;
    mstot  = 0.0;
    avg    = 0.0;
    buflen = 2048;
    idsz   = sizeof(neticmp_h) + sizeof(icmp_ts);

    CircularBuffer * rbuff = new CircularBuffer(buflen);

    wbuff       = (char*) ::malloc(buflen);
    req         = (neticmp_h*) wbuff;
    its         = (icmp_ts*) wbuff + sizeof(neticmp_h);
    data        = wbuff + idsz;

    req->type   = ICMP_ECHO;
    req->code   = 0;
    req->chksum = 0;
    req->id     = Pid;
    req->seq    = 0;

    if ( count > 0 )
        cnt = count;

    if ( size > (buflen - idsz) )
        size = buflen - idsz - 4;

    size  += Serializer::PadLen(size);
    InitDataBlock(size);

    dt = RandData.substr(0, size).data();
    ::memcpy(data, dt, size);
    its->size = size;

    std::cout << "Sending ";
    if ( count > 0 )
        std::cout << "(" << count << ") " ;
    std::cout << "ICMP echo requests to " << IpAddr::ntop(dstaddr) 
              << " (" << host << ")" << std::endl;
    std::cout << "ICMP data size is " << size << std::endl;

    while ( ! Alarm )
    {
        rbuff->reset();

        if ( ! getTimeOfDay(tvin) )
            errorOut("error in gettime");

        float lastsnt = timeDiff(tvin, tvsnt);

        if ( lastsnt >= interval )
            sendReq = true;

        if ( sendReq && cnt > 0 ) {
            sz           = idsz + size; // account for added data size
            tvsnt        = tvin;
            its->secs    = tvin.tv_sec;
            its->usecs   = tvin.tv_usec;
            req->chksum  = 0;
            req->seq++;
            req->chksum  = Socket::IpChkSum((uint16_t*)req, sz);

            wt  = icmps->write(wbuff, sz);
            if ( wt < 0 )
                errorOut("Error in write " + icmps->getErrorString());
            
            sent++;
            sendReq = false;
            if ( count > 0 )
                cnt--;

            if ( debug )
                std::cout << "Request <" << sent << "> sent" << std::endl;
        }

        sz   = rbuff->writePtrAvailable();
        wptr = rbuff->getWritePtr(&sz);
        if ( wptr == NULL )
            errorOut("Error in writing to rbuff");

        rd   = icmps->readFrom(wptr, sz, csock);
        if ( rd < 0 )
            errorOut("Error in readFrom " + icmps->getErrorString());
        
        sa   = (sockaddr_in*) &csock;
        addr = sa->sin_addr.s_addr;

        rbuff->setWritePtr(rd);

        if ( rd > 0 && addr == dstaddr )
        {
            IcmpResponse   response;
            
            if ( ! getTimeOfDay(tvin) )
                errorOut("error in gettime");

            rd = readIcmpHeader(rbuff, response);

            if ( rd > 0 && response.icmph.id == Pid ) {
                sz      = rbuff->readAvailable();
                rcvd++;

                if ( sz == sizeof(icmp_ts) ) {
                    timeval   tv;
                    char    * idf = rbuff->getReadPtr(&sz);
                    icmp_ts * ist = (icmp_ts*) idf;
                    tv.tv_sec     = ist->secs;
                    tv.tv_usec    = ist->usecs;

                    if ( debug ) 
                        std::cout << " Received data field in echo response" << std::endl;

                    rbuff->setReadPtr(sz);
                }

                float ms = timeDiff(tvin, tvsnt);

                std::cout << (rd+sz) << " bytes from " << IpAddr::ntop(addr)
                    << ": seq=" << response.icmph.seq << " time=" << ms << " ms" 
                    << std::endl;

                mstot += ms;
                avg    = (float) mstot / rcvd;

                if ( debug )
                    std::cout << " mstot=" << mstot << " rcvd = " << rcvd << std::endl;
            }
        } 
        
        if ( cnt == 0 ) {
            if ( rcvd == cnt )
                break;
            if ( tvo.tv_sec == 0 )
                tvo.tv_sec = tvin.tv_sec;
            else if ( (tvin.tv_sec - tvo.tv_sec) > timeout )
                break;
        }

        ::usleep(1000);
    }

    float loss;
    if ( rcvd == sent )
        loss = 0.0;
    else
        loss = (  100.0 - ( ((float) rcvd / (float) sent) * 100.0) );

    std::cout << std::endl << "Results:" << std::endl;
    std::cout << "  Sent " << sent << " requests, received " << rcvd 
        << ": Loss=" << loss << "% : Avg Time= " << avg << " ms " 
        << std::endl;

    return 0;

}
Beispiel #2
0
int main ( int argc, char ** argv )
{
    size_t  buffsize = DEFAULT_CIRBUFFER_SIZE;
    size_t  maxsize  = MAX_CIRBUFFER_SIZE;

    if ( argc == 2 )
        buffsize = StringUtils::FromString<size_t>(argv[1]);

    CircularBuffer * buff  = new CircularBuffer(buffsize);
    std::string      bstr  = "0123456789";
    int              count = buffsize / bstr.length();

    std::cout << " buffer capacity = " << buff->size() 
        << ", max is " << maxsize
        << ", string '" << bstr << std::endl
        << "', count is " << count << std::endl << std::endl;

    while ( buff->writeAvailable() >= bstr.length() )
        buff->write(bstr.c_str(), bstr.length());

    char * out = (char*) calloc(bstr.length(), sizeof(char));

    std::cout << " dataAvail in buffer = " << buff->readAvailable()
              << std::endl;

    for ( int i = 0; i < (count / 2); ++i ) {
        buff->read(out, bstr.length());
    }
    std::cout << " read: '" << out << "'" << std::endl;

    buffsize = buffsize - (count / 2);
    std::cout << " resizing to " << buffsize << std::endl;

    if ( ! buff->resize(buffsize) )
        std::cout << "RESIZE FAILED" << std::endl;

    std::cout << " buffer capacity = " << buff->size() << std::endl 
        << " fullDataAvail = " << buff->readAvailable()
        << " dataAvail = " << buff->readPtrAvailable() << std::endl
        << " fullSpaceAvail = " << buff->writeAvailable()
        << " spaceAvail = " << buff->writePtrAvailable()
              << std::endl << std::endl;

    int c = 0;
    while ( buff->writePtrAvailable() >= bstr.length() ) {
        buff->write(bstr.c_str(), bstr.length());
        c++;
    }
    std::cout << " write count = " << c << std::endl << std::endl;

    std::cout << " buffer capacity = " << buff->size() << std::endl 
              << " fullDataAvail = "   << buff->readAvailable()
              << " dataAvail = "       << buff->readPtrAvailable() << std::endl
              << " fullSpaceAvail = "  << buff->writeAvailable()
              << " spaceAvail = "      << buff->writePtrAvailable()
              << std::endl << std::endl;

    buffsize = buff->size() + bstr.length();
    std::cout << " resizing to " << buffsize << std::endl;
    
    if ( ! buff->resize(buffsize) )
        std::cout << " RESIZE FAILED " << std::endl;

    std::cout << " buffer capacity = " << buff->size() << std::endl 
              << " fullDataAvail = "   << buff->readAvailable()
              << " dataAvail = "       << buff->readPtrAvailable() << std::endl
              << " fullSpaceAvail = "  << buff->writeAvailable()
              << " spaceAvail = "      << buff->writePtrAvailable()
              << std::endl << std::endl;

    ::free(out);
    delete buff;

    return 0;
}