Example #1
0
//!
//! Log-printing function without a specific log level. It is essentially printf() that will go verbatim,
//! with just timestamp as prefix and at any log level, into the current log or stdout, if no log was open.
//!
//! @param[in] format the format of the log message
//! @param[in] ... the variable argument part filling the format
//!
//! @return 0 on success. If negative, error with vsnprintf() or if 1 means error with log_line()
//!
//! @todo Chuck to evaluate if we cannot standardize the error code returned.
//!
//! @see log_line()
//!
int logprintf(const char *format, ...)
{
    char buf[LOGLINEBUF];

    // start with current timestamp
    int offset = fill_timestamp(buf, sizeof(buf));

    // append the log message passed via va_list
    va_list ap;
    va_start(ap, format);
    int rc = vsnprintf(buf + offset, sizeof(buf) - offset - 1, format, ap);
    va_end(ap);
    if (rc < 0)
        return rc;

    return log_line(buf);
}
Example #2
0
//!
//! Log-printing function without a specific log level. It is essentially printf() that will go verbatim,
//! with just timestamp as prefix and at any log level, into the current log or stdout, if no log was open.
//!
//! @param[in] format the format of the log message
//! @param[in] ... the variable argument part filling the format
//!
//! @return 0 on success. If negative, error with vsnprintf() or if 1 means error with log_line()
//!
//! @see log_line()
//!
//! @todo Evaluate if we cannot standardize the error code returned.
//!
int logprintf(const char *format, ...)
{
    int rc = -1;
    int offset = -1;
    char buf[LOGLINEBUF] = "";
    va_list ap = { {0} };

    // start with current timestamp
    offset = fill_timestamp(buf, sizeof(buf));

    // append the log message passed via va_list
    va_start(ap, format);
    {
        rc = vsnprintf(buf + offset, sizeof(buf) - offset - 1, format, ap);
    }
    va_end(ap);

    if (rc < 0)
        return (rc);
    return (log_line(buf));
}
Example #3
0
static void 
send_faked_ack(tc_user_t *u)
{
    tc_ip_header_t   *ip_header;
    tc_tcp_header_t  *tcp_header;
    unsigned char    *p, frame[FAKE_FRAME_LEN];

    memset(frame, 0, FAKE_FRAME_LEN);
    p = frame + ETHERNET_HDR_LEN;
    ip_header  = (tc_ip_header_t *) p;
    tcp_header = (tc_tcp_header_t *) (p + IP_HEADER_LEN);

    ip_header->version  = 4;
    ip_header->ihl      = IP_HEADER_LEN/4;
    ip_header->frag_off = htons(IP_DF); 
    ip_header->ttl      = 64; 
    ip_header->protocol = IPPROTO_TCP;
    ip_header->saddr    = u->src_addr;
    ip_header->daddr    = u->dst_addr;
    tcp_header->source  = u->src_port;
    tcp_header->dest    = u->dst_port;
    tcp_header->seq     = u->exp_seq;
    tcp_header->ack_seq = u->exp_ack_seq;
    tcp_header->window  = htons(65535); 
    tcp_header->ack     = 1;
    if (u->state.timestamped) {
        ip_header->tot_len  = htons(FAKE_IP_TS_DATAGRAM_LEN);
        tcp_header->doff    = TCP_HEADER_DOFF_TS_VALUE;
        fill_timestamp(u, tcp_header);
    } else {
        ip_header->tot_len  = htons(FAKE_MIN_IP_DATAGRAM_LEN);
        tcp_header->doff    = TCP_HEADER_DOFF_MIN_VALUE;
    }

    process_packet(u, frame);
}
Example #4
0
//!
//! Main log-printing function, which will dump a line into a log, with a prefix appropriate for
//! the log level, given that the log level is above the threshold.
//!
//! @param[in] func the caller function name (i.e. __FUNCTION__)
//! @param[in] file the file in which the caller function reside (i.e. __FILE__)
//! @param[in] line the line at which this function was called (i.e. __LINE__)
//! @param[in] level the log level for this message
//! @param[in] format the format string of the message
//! @param[in] ... the variable argument part of the format
//!
//! @return 0 on success, -1 on failure with this function or 1 if log_line() failed.
//!
//! @see log_line()
//!
//! @pre \li The func field must not be null if the prefix spec contains 'm'.
//!      \li The file field must not be null if the prefix spec contains 'F'.
//!      \li The log level must be valid and greather than or equal to the configured log level
//!      \li The format string must not be null.
//!
//! @post If the given level if greater or equal to the configured log level, the message will be
//!       printed into our log file or syslog.
//!
//! @todo evaluate if we cannot standardize the error code returned.
//!
int logprintfl(const char *func, const char *file, int line, log_level_e level, const char *format, ...)
{
    int rc = -1;
    int left = 0;
    int size = 0;
    int offset = 0;
    char *s = NULL;
    char c = '\0';
    char cn = '\0';
    boolean custom_spec = FALSE;
    char buf[LOGLINEBUF] = "";
    va_list ap = { {0} };
    const char *prefix_spec = NULL;

    // return if level is invalid or below the threshold
    if (level < log_level) {
        return (0);
    }

    if ((level < 0) || (level > EUCA_LOG_OFF)) {
        // unexpected log level
        return (-1);
    }

    if (strcmp(log_custom_prefix, USE_STANDARD_PREFIX) == 0) {
        prefix_spec = log_level_prefix[log_level];
        custom_spec = FALSE;
    } else {
        prefix_spec = log_custom_prefix;
        custom_spec = TRUE;
    }

    // go over prefix format for the log level (defined in log.h or custom)
    for (; *prefix_spec != '\0'; prefix_spec++) {
        s = buf + offset;
        if ((left = sizeof(buf) - offset - 1) < 1) {
            // not enough room in internal buffer for a prefix
            return -1;
        }
        // see if we have a formatting character or a regular one
        c = prefix_spec[0];
        cn = prefix_spec[1];
        if ((c != '%')                 // not a special formatting char
            || (c == '%' && cn == '%') // formatting char, escaped
            || (c == '%' && cn == '\0')) {  // formatting char at the end
            s[0] = c;
            s[1] = '\0';
            offset++;
            if ((c == '%') && (cn == '%')) {
                // swallow the one extra '%' in input
                prefix_spec++;
            }
            continue;
        }
        // move past the '%' to the formatting char
        prefix_spec++;

        size = 0;
        switch (*prefix_spec) {
        case 'T':
            // timestamp
            size = fill_timestamp(s, left);
            break;

        case 'L':{
                // log-level
                char l[6];
                euca_strncpy(l, log_level_names[level], 6); // we want hard truncation
                size = snprintf(s, left, "%5s", l);
                break;
            }

        case 'p':{
                // process ID
                char p[11];
                snprintf(p, sizeof(p), "%010d", getpid());  // 10 chars is enough for max 32-bit unsigned integer
                size = print_field_truncated(&prefix_spec, s, left, p);
                break;
            }

        case 't':{
                // thread ID
                char t[21];
                snprintf(t, sizeof(t), "%020d", (pid_t) syscall(SYS_gettid));   // 20 chars is enough for max 64-bit unsigned integer
                size = print_field_truncated(&prefix_spec, s, left, t);
                break;
            }

        case 'm':
            // method
            size = print_field_truncated(&prefix_spec, s, left, func);
            break;

        case 'F':{
                // file-and-line
                char file_and_line[64];
                snprintf(file_and_line, sizeof(file_and_line), "%s:%d", file, line);
                size = print_field_truncated(&prefix_spec, s, left, file_and_line);
                break;
            }

        case 's':{
                // max RSS of the process
                struct rusage u;
                bzero(&u, sizeof(struct rusage));
                getrusage(RUSAGE_SELF, &u);

                // unfortunately, many fields in 'struct rusage' aren't supported on Linux (notably: ru_ixrss, ru_idrss, ru_isrss)
                char size_str[64];
                snprintf(size_str, sizeof(size_str), "%05ld", u.ru_maxrss / 1024);
                size = print_field_truncated(&prefix_spec, s, left, size_str);
                break;
            }

        case '?':
            // not supported currently
            s[0] = '?';
            s[1] = '\0';
            size = 1;
            break;

        default:
            s[0] = *prefix_spec;
            s[1] = '\0';
            size = 1;
            break;
        }

        if (size < 0) {
            // something went wrong in the snprintf()s above
            logprintf("error in prefix construction in logprintfl()\n");
            return -1;
        }
        offset += size;
    }

    // add a space between the prefix and the message proper
    if ((offset > 0) && ((sizeof(buf) - offset - 1) > 0)) {
        buf[offset++] = ' ';
        buf[offset] = '\0';
    }
    // append the log message passed via va_list
    va_start(ap, format);
    {
        rc = vsnprintf(buf + offset, sizeof(buf) - offset - 1, format, ap);
    }
    va_end(ap);
    if (rc < 0)
        return (rc);

    if (syslog_facility != -1) {
        // log to syslog, at the appropriate level: euca DEBUG, TRACE, and EXTREME use syslog's DEBUG
        int l = LOG_DEBUG;
        if (level == EUCA_LOG_ERROR)
            l = LOG_ERR;
        else if (level == EUCA_LOG_WARN)
            l = LOG_WARNING;
        else if (level == EUCA_LOG_INFO)
            l = LOG_INFO;

        if (custom_spec)
            syslog(l, buf);
        else
            syslog(l, buf + offset);
    }

    return (log_line(buf));
}
Example #5
0
// Main log-printing function, which will dump a line into
// a log, with a prefix appropriate for the log level, given
// that the log level is above the threshold.
int logprintfl (int level, const char *format, ...)
{
    // return if level is invalid or below the threshold
    if (level < log_level) {
        return 0;
    } else if (level < 0 || level > EUCAOFF) {
        return -1; // unexpected log level
    }

    char buf [LOGLINEBUF];
    int offset = 0;

    // go over prefix format for the log level (defined in log.h)
    for (char * prefix_spec = (strlen(log_custom_prefix) > 0) ? log_custom_prefix : log_level_prefix [log_level];
         * prefix_spec != '\0'; 
         prefix_spec++) { 
        
        char * s = buf + offset;
        int left = sizeof (buf) - offset - 1;
        if (left < 1) {
            return -1; // not enough room in internal buffer for a prefix
        }
        
        int size = 0;
        switch (* prefix_spec) {
        case 'T': // timestamp
            size = fill_timestamp (s, left);
            break;

        case 'L': { // log-level
            char l [6];
            safe_strncpy (l, log_level_names [level], 6); // we want hard truncation
            size = snprintf (s, left, "%5s", l);
            break;
        }
        case 'p': { // process ID
            char p [11];
            snprintf (p, sizeof (p), "%010d", getpid()); // 10 chars is enough for max 32-bit unsigned integer
            size = print_field_truncated (&prefix_spec, s, left, p);
            break;
        }
        case 't': { // thread ID
            char t [21];
            snprintf (t, sizeof (t), "%020d", (pid_t) syscall (SYS_gettid)); // 20 chars is enough for max 64-bit unsigned integer
            size = print_field_truncated (&prefix_spec, s, left, t);
            break;
        }
        case 'm': // method
            size = print_field_truncated (&prefix_spec, s, left, _log_curr_method);
            break;

        case 'F': { // file-and-line
            char file_and_line [64];
            snprintf (file_and_line, sizeof (file_and_line), "%s:%d", _log_curr_file, _log_curr_line);
            size = print_field_truncated (&prefix_spec, s, left, file_and_line);
            break;
        }
        case '?':
            s [0] = '?'; // not supported currently
            s [1] = '\0';
            size = 1;
            break;

        default:
            s [0] = * prefix_spec;
            s [1] = '\0';
            size = 1;
        }
        
        if (size < 0) {
            logprintf ("error in prefix construction in logprintfl()\n");
            return -1; // something went wrong in the snprintf()s above
        }
        offset += size;
    }
    
    // append the log message passed via va_list
    va_list ap;
    va_start(ap, format);
    int rc = vsnprintf (buf + offset, sizeof (buf) - offset - 1, format, ap);
    va_end(ap);
    if (rc<0)
        return rc;
    
    return log_line (buf);
}