Exemple #1
0
//-----------------------------------------------------------------------------
// load a macro assembler file in IDA.
void load_file(linput_t *li, ushort /*neflag*/, const char * /*fileformatname*/) {
    // already read the 2 first bytes
    qlseek(li, 2);

    // initialize static variables
    qstrncpy(creator, "UNKNOWN", sizeof(creator));
    entry_point = -1;

    bool finished = false;

    while (!finished) {
        uchar record_type = 0;

        // read the record type
        if (qlread(li, &record_type, 1) != 1)
            mas_error("unable to read the record type");

        finished = process_record(li, record_type, true);
    }

#if defined(DEBUG)
    msg("MAS: reading complete\n");
#endif

    mas_write_comments();
}
Exemple #2
0
static void do_trace_mem(struct tracecmd_input *handle)
{
	struct pevent *pevent = tracecmd_get_pevent(handle);
	struct event_format *event;
	struct pevent_record *record;
	int missed_events = 0;
	int cpus;
	int cpu;
	int ret;

	ret = tracecmd_init_data(handle);
	if (ret < 0)
		die("failed to init data");

	if (ret > 0)
		die("trace-cmd mem does not work with latency traces\n");

	cpus = tracecmd_cpus(handle);

	/* Need to get any event */
	for (cpu = 0; cpu < cpus; cpu++) {
		record = tracecmd_peek_data(handle, cpu);
		if (record)
			break;
	}
	if (!record)
		die("No records found in file");

	ret = pevent_data_type(pevent, record);
	event = pevent_data_event_from_type(pevent, ret);

	common_type_field = pevent_find_common_field(event, "common_type");
	if (!common_type_field)
		die("Can't find a 'type' field?");

	update_kmalloc(pevent);
	update_kmalloc_node(pevent);
	update_kfree(pevent);
	update_kmem_cache_alloc(pevent);
	update_kmem_cache_alloc_node(pevent);
	update_kmem_cache_free(pevent);

	while ((record = tracecmd_read_next_data(handle, &cpu))) {

		/* record missed event */
		if (!missed_events && record->missed_events)
			missed_events = 1;

		process_record(pevent, record);
		free_record(record);
	}

	sort_list();
	print_list();
}
Exemple #3
0
/*=================================
 * fix_nodes -- Fix all nodes on fix list
 *  (uses list from check_nodes)
 *================================*/
static void
fix_nodes (void)
{
    if (!tofix) return;
    while (!is_empty_list(tofix)) {
        STRING key = dequeue_list(tofix);
        RECORD rec = key_to_record(key);
        strfree(&key);
        lock_record_in_cache(rec);
        process_record(rec);
        unlock_record_from_cache(rec);
    }
}
Exemple #4
0
/**
  * Entry point for C core of \b distiller diagnostic.
  */
int
main (int argc, char *argv[])
{
    if (argc != 5)
        error ("Usage: %s rec_first rec_last rec_step use_filter", argv[0]);

    int rec0 = fmax (0,           atoi (argv[1])) + 0.1,
        rec1 = fmin (INT_MAX - 3, atoi (argv[2])) + 0.1,
        step = fmax (1,           atoi (argv[3])) + 0.1,
        use_filter = atoi (argv[4]);

    // Loads units to get [r0] -> [micron] factor.
    units_load ();

    // Loads component parameters if they were defined before.
    FILE *fp = fopen ("output/markers/map.txt", "rt");
    if (fp) {
        double qDivM;
        while (1 == fscanf (fp, "%le ", &qDivM))
            open_gate (qDivM, -1);
        fclose (fp);
    }

    for (record = rec0 ; record <= rec1 ; record += step) {
        // Checks if record exists.
        if (access (IO_plasmaName (record, 0), R_OK))
            break;

        // Reopens streams for the components (new record => new file name).
        for (int i = 0 ; i < gateN ; ++i)
            open_gate (gate[i].qDivM, record);

        // Filters markers.
        process_record (use_filter);

        // Closes all open streams.
        for (int i = 0 ; i < gateN ; ++i)
            fclose (gate[i].fp);
    }

    // Saves updated "component number <=> q/M" definitions.
    fp = fopen ("output/markers/map.txt", "wt");
    for (int i = 0 ; i < gateN ; ++i)
        fprintf (fp, "%+.14le\n", gate[i].qDivM);
    fclose (fp);

    msg_send ("Done");

    return EXIT_SUCCESS;
}
Exemple #5
0
//----------------------------------------------------------------------
bool idaapi init_loader_options(linput_t *li)
{
  // already read the 2 first bytes
  qlseek(li, 2);

  bool finished = false;
  while (!finished) {
    uchar record_type = 0;
    // read the record type
    if (qlread(li, &record_type, 1) != 1)
      return false;
    finished = process_record(li, record_type, false);
  }
  return true;
}
Exemple #6
0
/** \brief Called to execute an action.
 *
 * FIXME: Needs documentation.
 */
void action_exec(keyevent_t event)
{
    if (!IS_NOEVENT(event)) {
        dprint("\n---- action_exec: start -----\n");
        dprint("EVENT: "); debug_event(event); dprintln();
#ifdef RETRO_TAPPING
        retro_tapping_counter++;
#endif
    }

#ifdef FAUXCLICKY_ENABLE
    if (IS_PRESSED(event)) {
        FAUXCLICKY_ACTION_PRESS;
    }
    if (IS_RELEASED(event)) {
        FAUXCLICKY_ACTION_RELEASE;
    }
    fauxclicky_check();
#endif

#ifdef SWAP_HANDS_ENABLE
    if (!IS_NOEVENT(event)) {
        process_hand_swap(&event);
    }
#endif

    keyrecord_t record = { .event = event };

#if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
    if (has_oneshot_layer_timed_out()) {
        clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED);
    }
    if (has_oneshot_mods_timed_out()) {
        clear_oneshot_mods();
    }
#endif

#ifndef NO_ACTION_TAPPING
    action_tapping_process(record);
#else
    process_record(&record);
    if (!IS_NOEVENT(record.event)) {
        dprint("processed: "); debug_record(record); dprintln();
    }
#endif
}
Exemple #7
0
void action_exec(keyevent_t event)
{
    if (!IS_NOEVENT(event)) {
        dprint("\n---- action_exec: start -----\n");
        dprint("EVENT: "); debug_event(event); dprintln();
    }

    keyrecord_t record = { .event = event };

#ifndef NO_ACTION_TAPPING
    action_tapping_process(record);
#else
    process_record(&record);
    if (!IS_NOEVENT(record.event)) {
        dprint("processed: "); debug_record(record); dprintln();
    }
#endif
}
Exemple #8
0
/******************************************************************************
 *                                                                            *
 * Function: node_events                                                      *
 *                                                                            *
 * Purpose: process new events received from a salve node                     *
 *                                                                            *
 * Parameters:                                                                *
 *                                                                            *
 * Return value:  SUCCEED - processed successfully                            *
 *                FAIL - an error occured                                     *
 *                                                                            *
 * Author: Alexei Vladishev                                                   *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
int	node_events(char *data)
{
	char	*s;
	int	firstline=1;
	int	nodeid=0;
	int	sender_nodeid=0;
	char	tmp[MAX_STRING_LEN];
	int	datalen;

	datalen = strlen(data);

	zabbix_log( LOG_LEVEL_DEBUG, "In node_events(len:%d)",
		datalen);

	DBbegin();
       	s=(char *)strtok(data,"\n");
	while(s!=NULL)
	{
		if(firstline == 1)
		{
/*			zabbix_log( LOG_LEVEL_WARNING, "First line [%s]", s); */
			zbx_get_field(s,tmp,1,ZBX_DM_DELIMITER);
			sender_nodeid=atoi(tmp);
			zbx_get_field(s,tmp,2,ZBX_DM_DELIMITER);
			nodeid=atoi(tmp);
			firstline=0;
			zabbix_log( LOG_LEVEL_WARNING, "NODE %d: Received events from node %d for node %d datalen %d",
					CONFIG_NODEID,
					sender_nodeid,
					nodeid,
					datalen);
		}
		else
		{
/*			zabbix_log( LOG_LEVEL_WARNING, "Got line [%s]", s); */
			process_record(nodeid, s);
		}

       		s=(char *)strtok(NULL,"\n");
	}
	DBcommit();
	return SUCCEED;
}
Exemple #9
0
/**
 * monitor_tbufs - monitor the contents of tbufs
 */
static int monitor_tbufs(void)
{
    int i;

    struct t_struct *tbufs;      /* Pointer to hypervisor maps */
    struct t_buf **meta;         /* pointers to the trace buffer metadata    */
    unsigned char **data;        /* pointers to the trace buffer data areas
                                  * where they are mapped into user space.   */
    unsigned long tbufs_mfn;     /* mfn of the tbufs                         */
    unsigned int  num;           /* number of trace buffers / logical CPUS   */
    unsigned long tinfo_size;    /* size of t_info metadata map              */
    unsigned long size;          /* size of a single trace buffer            */

    unsigned long data_size, rec_size;

    /* get number of logical CPUs (and therefore number of trace buffers) */
    num = get_num_cpus();

    init_current(num);
    alloc_qos_data(num);

    printf("CPU Frequency = %7.2f\n", opts.cpu_freq);
    
    /* setup access to trace buffers */
    get_tbufs(&tbufs_mfn, &tinfo_size);
    tbufs = map_tbufs(tbufs_mfn, num, tinfo_size);

    size = tbufs->t_info->tbuf_size * XC_PAGE_SIZE;

    data_size = size - sizeof(struct t_buf);

    meta = tbufs->meta;
    data = tbufs->data;

    if ( eventchn_init() < 0 )
        fprintf(stderr, "Failed to initialize event channel; "
                "Using POLL method\r\n");

    /* now, scan buffers for events */
    while ( !interrupted )
    {
        for ( i = 0; (i < num) && !interrupted; i++ )
        {
            unsigned long start_offset, end_offset, cons, prod;

            cons = meta[i]->cons;
            prod = meta[i]->prod;
            xen_rmb(); /* read prod, then read item. */

            if ( cons == prod )
                continue;

            start_offset = cons % data_size;
            end_offset = prod % data_size;

            if ( start_offset >= end_offset )
            {
                while ( start_offset != data_size )
                {
                    rec_size = process_record(
                        i, (struct t_rec *)(data[i] + start_offset));
                    start_offset += rec_size;
                }
                start_offset = 0;
            }
            while ( start_offset != end_offset )
            {
                rec_size = process_record(
                    i, (struct t_rec *)(data[i] + start_offset));
                start_offset += rec_size;
            }
            xen_mb(); /* read item, then update cons. */
            meta[i]->cons = prod;
        }

	wait_for_event();
	wakeups++;
    }

    /* cleanup */
    free(meta);
    free(data);
    /* don't need to munmap - cleanup is automatic */

    return 0;
}
Exemple #10
0
static void stream_continue(libxl__egc *egc,
                            libxl__stream_read_state *stream)
{
    STATE_AO_GC(stream->ao);

    /*
     * Must not mutually recurse with process_record().
     *
     * For records whose processing function is synchronous
     * (e.g. TOOLSTACK), process_record() does not start another async
     * operation, and a further operation should be started.
     *
     * A naive solution, which would function in general, would be for
     * process_record() to call stream_continue().  However, this
     * would allow the content of the stream to cause mutual
     * recursion, and possibly for us to fall off our stack.
     *
     * Instead, process_record() indicates with its return value
     * whether a further operation needs to start, and the
     * recursion_guard is in place to catch any code paths which get
     * this wrong.
     */
    assert(stream->recursion_guard == false);
    stream->recursion_guard = true;

    switch (stream->phase) {
    case SRS_PHASE_NORMAL:
        /*
         * Normal phase (regular migration or restore from file):
         *
         * logically:
         *   do { read_record(); process_record(); } while ( not END );
         *
         * Alternate between reading a record from the stream, and
         * processing the record.  There should never be two records
         * in the queue.
         */
        if (LIBXL_STAILQ_EMPTY(&stream->record_queue))
            setup_read_record(egc, stream);
        else {
            if (process_record(egc, stream))
                setup_read_record(egc, stream);

            /*
             * process_record() had better have consumed the one and
             * only record in the queue.
             */
            assert(LIBXL_STAILQ_EMPTY(&stream->record_queue));
        }
        break;

    case SRS_PHASE_BUFFERING: {
        /*
         * Buffering phase (checkpointed streams only):
         *
         * logically:
         *   do { read_record(); } while ( not CHECKPOINT_END );
         *
         * Read and buffer all records from the stream until a
         * CHECKPOINT_END record is encountered.  We need to peek at
         * the tail to spot the CHECKPOINT_END record, and switch to
         * the unbuffering phase.
         */
        libxl__sr_record_buf *rec = LIBXL_STAILQ_LAST(
            &stream->record_queue, libxl__sr_record_buf, entry);

        assert(stream->in_checkpoint);

        if (!rec || (rec->hdr.type != REC_TYPE_CHECKPOINT_END)) {
            setup_read_record(egc, stream);
            break;
        }

        /*
         * There are now some number of buffered records, with a
         * CHECKPOINT_END at the end. Start processing them all.
         */
        stream->phase = SRS_PHASE_UNBUFFERING;
    }
        /* FALLTHROUGH */
    case SRS_PHASE_UNBUFFERING:
        /*
         * Unbuffering phase (checkpointed streams only):
         *
         * logically:
         *   do { process_record(); } while ( not CHECKPOINT_END );
         *
         * Process all records collected during the buffering phase.
         */
        assert(stream->in_checkpoint);

        while (process_record(egc, stream))
            ; /*
               * Nothing! process_record() helpfully tells us if no specific
               * futher actions have been set up, in which case we want to go
               * ahead and process the next record.
               */
        break;

    default:
        abort();
    }

    assert(stream->recursion_guard == true);
    stream->recursion_guard = false;
}
Exemple #11
0
/** \brief Take an action and processes it.
 *
 * FIXME: Needs documentation.
 */
void process_action(keyrecord_t *record, action_t action)
{
    keyevent_t event = record->event;
#ifndef NO_ACTION_TAPPING
    uint8_t tap_count = record->tap.count;
#endif

    if (event.pressed) {
        // clear the potential weak mods left by previously pressed keys
        clear_weak_mods();
    }

#ifndef NO_ACTION_ONESHOT
    bool do_release_oneshot = false;
    // notice we only clear the one shot layer if the pressed key is not a modifier.
    if (is_oneshot_layer_active() && event.pressed && !IS_MOD(action.key.code)) {
        clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED);
        do_release_oneshot = !is_oneshot_layer_active();
    }
#endif

    switch (action.kind.id) {
        /* Key and Mods */
        case ACT_LMODS:
        case ACT_RMODS:
            {
                uint8_t mods = (action.kind.id == ACT_LMODS) ?  action.key.mods :
                                                                action.key.mods<<4;
                if (event.pressed) {
                    if (mods) {
                        if (IS_MOD(action.key.code) || action.key.code == KC_NO) {
                            // e.g. LSFT(KC_LGUI): we don't want the LSFT to be weak as it would make it useless.
                            // This also makes LSFT(KC_LGUI) behave exactly the same as LGUI(KC_LSFT).
                            // Same applies for some keys like KC_MEH which are declared as MEH(KC_NO).
                            add_mods(mods);
                        } else {
                            add_weak_mods(mods);
                        }
                        send_keyboard_report();
                    }
                    register_code(action.key.code);
                } else {
                    unregister_code(action.key.code);
                    if (mods) {
                        if (IS_MOD(action.key.code) || action.key.code == KC_NO) {
                            del_mods(mods);
                        } else {
                            del_weak_mods(mods);
                        }
                        send_keyboard_report();
                    }
                }
            }
            break;
#ifndef NO_ACTION_TAPPING
        case ACT_LMODS_TAP:
        case ACT_RMODS_TAP:
            {
                uint8_t mods = (action.kind.id == ACT_LMODS_TAP) ?  action.key.mods :
                                                                    action.key.mods<<4;
                switch (action.layer_tap.code) {
    #ifndef NO_ACTION_ONESHOT
                    case MODS_ONESHOT:
                        // Oneshot modifier
                        if (event.pressed) {
                            if (tap_count == 0) {
                                dprint("MODS_TAP: Oneshot: 0\n");
                                register_mods(mods);
                            } else if (tap_count == 1) {
                                dprint("MODS_TAP: Oneshot: start\n");
                                set_oneshot_mods(mods);
                    #if defined(ONESHOT_TAP_TOGGLE) && ONESHOT_TAP_TOGGLE > 1
                            } else if (tap_count == ONESHOT_TAP_TOGGLE) {
                                dprint("MODS_TAP: Toggling oneshot");
                                clear_oneshot_mods();
                                set_oneshot_locked_mods(mods);
                                register_mods(mods);
                    #endif
                            } else {
                                register_mods(mods);
                            }
                        } else {
                            if (tap_count == 0) {
                                clear_oneshot_mods();
                                unregister_mods(mods);
                            } else if (tap_count == 1) {
                                // Retain Oneshot mods
                    #if defined(ONESHOT_TAP_TOGGLE) && ONESHOT_TAP_TOGGLE > 1
                                if (mods & get_mods()) {
                                    clear_oneshot_locked_mods();
                                    clear_oneshot_mods();
                                    unregister_mods(mods);
                                }
                            } else if (tap_count == ONESHOT_TAP_TOGGLE) {
                                // Toggle Oneshot Layer
                    #endif
                            } else {
                                clear_oneshot_mods();
                                unregister_mods(mods);
                            }
                        }
                        break;
    #endif
                    case MODS_TAP_TOGGLE:
                        if (event.pressed) {
                            if (tap_count <= TAPPING_TOGGLE) {
                                register_mods(mods);
                            }
                        } else {
                            if (tap_count < TAPPING_TOGGLE) {
                                unregister_mods(mods);
                            }
                        }
                        break;
                    default:
                        if (event.pressed) {
                            if (tap_count > 0) {
#ifndef IGNORE_MOD_TAP_INTERRUPT
                                if (record->tap.interrupted) {
                                    dprint("mods_tap: tap: cancel: add_mods\n");
                                    // ad hoc: set 0 to cancel tap
                                    record->tap.count = 0;
                                    register_mods(mods);
                                } else
#endif
                                {
                                    dprint("MODS_TAP: Tap: register_code\n");
                                    register_code(action.key.code);
                                }
                            } else {
                                dprint("MODS_TAP: No tap: add_mods\n");
                                register_mods(mods);
                            }
                        } else {
                            if (tap_count > 0) {
                                dprint("MODS_TAP: Tap: unregister_code\n");
                                unregister_code(action.key.code);
                            } else {
                                dprint("MODS_TAP: No tap: add_mods\n");
                                unregister_mods(mods);
                            }
                        }
                        break;
                }
            }
            break;
#endif
#ifdef EXTRAKEY_ENABLE
        /* other HID usage */
        case ACT_USAGE:
            switch (action.usage.page) {
                case PAGE_SYSTEM:
                    if (event.pressed) {
                        host_system_send(action.usage.code);
                    } else {
                        host_system_send(0);
                    }
                    break;
                case PAGE_CONSUMER:
                    if (event.pressed) {
                        host_consumer_send(action.usage.code);
                    } else {
                        host_consumer_send(0);
                    }
                    break;
            }
            break;
#endif
#ifdef MOUSEKEY_ENABLE
        /* Mouse key */
        case ACT_MOUSEKEY:
            if (event.pressed) {
                switch (action.key.code) {
                    case KC_MS_BTN1:
                        tp_buttons |= (1<<0);
                        break;
                    case KC_MS_BTN2:
                        tp_buttons |= (1<<1);
                        break;
                    case KC_MS_BTN3:
                        tp_buttons |= (1<<2);
                        break;
                    default:
                        break;
                }
                mousekey_on(action.key.code);
                mousekey_send();
            } else {
                switch (action.key.code) {
                    case KC_MS_BTN1:
                        tp_buttons &= ~(1<<0);
                        break;
                    case KC_MS_BTN2:
                        tp_buttons &= ~(1<<1);
                        break;
                    case KC_MS_BTN3:
                        tp_buttons &= ~(1<<2);
                        break;
                    default:
                        break;
                }
                mousekey_off(action.key.code);
                mousekey_send();
            }
            break;
#endif
#ifndef NO_ACTION_LAYER
        case ACT_LAYER:
            if (action.layer_bitop.on == 0) {
                /* Default Layer Bitwise Operation */
                if (!event.pressed) {
                    uint8_t shift = action.layer_bitop.part*4;
                    uint32_t bits = ((uint32_t)action.layer_bitop.bits)<<shift;
                    uint32_t mask = (action.layer_bitop.xbit) ? ~(((uint32_t)0xf)<<shift) : 0;
                    switch (action.layer_bitop.op) {
                        case OP_BIT_AND: default_layer_and(bits | mask); break;
                        case OP_BIT_OR:  default_layer_or(bits | mask);  break;
                        case OP_BIT_XOR: default_layer_xor(bits | mask); break;
                        case OP_BIT_SET: default_layer_and(mask); default_layer_or(bits); break;
                    }
                }
            } else {
                /* Layer Bitwise Operation */
                if (event.pressed ? (action.layer_bitop.on & ON_PRESS) :
                                    (action.layer_bitop.on & ON_RELEASE)) {
                    uint8_t shift = action.layer_bitop.part*4;
                    uint32_t bits = ((uint32_t)action.layer_bitop.bits)<<shift;
                    uint32_t mask = (action.layer_bitop.xbit) ? ~(((uint32_t)0xf)<<shift) : 0;
                    switch (action.layer_bitop.op) {
                        case OP_BIT_AND: layer_and(bits | mask); break;
                        case OP_BIT_OR:  layer_or(bits | mask);  break;
                        case OP_BIT_XOR: layer_xor(bits | mask); break;
                        case OP_BIT_SET: layer_and(mask); layer_or(bits); break;
                    }
                }
            }
            break;
    #ifndef NO_ACTION_TAPPING
        case ACT_LAYER_TAP:
        case ACT_LAYER_TAP_EXT:
            switch (action.layer_tap.code) {
                case 0xe0 ... 0xef:
                    /* layer On/Off with modifiers(left only) */
                    if (event.pressed) {
                        layer_on(action.layer_tap.val);
                        register_mods(action.layer_tap.code & 0x0f);
                    } else {
                        layer_off(action.layer_tap.val);
                        unregister_mods(action.layer_tap.code & 0x0f);
                    }
                    break;
                case OP_TAP_TOGGLE:
                    /* tap toggle */
                    if (event.pressed) {
                        if (tap_count < TAPPING_TOGGLE) {
                            layer_invert(action.layer_tap.val);
                        }
                    } else {
                        if (tap_count <= TAPPING_TOGGLE) {
                            layer_invert(action.layer_tap.val);
                        }
                    }
                    break;
                case OP_ON_OFF:
                    event.pressed ? layer_on(action.layer_tap.val) :
                                    layer_off(action.layer_tap.val);
                    break;
                case OP_OFF_ON:
                    event.pressed ? layer_off(action.layer_tap.val) :
                                    layer_on(action.layer_tap.val);
                    break;
                case OP_SET_CLEAR:
                    event.pressed ? layer_move(action.layer_tap.val) :
                                    layer_clear();
                    break;
            #ifndef NO_ACTION_ONESHOT
                case OP_ONESHOT:
                    // Oneshot modifier
                #if defined(ONESHOT_TAP_TOGGLE) && ONESHOT_TAP_TOGGLE > 1
                    do_release_oneshot = false;
                    if (event.pressed) {
                        del_mods(get_oneshot_locked_mods());
                        if (get_oneshot_layer_state() == ONESHOT_TOGGLED) {
                            reset_oneshot_layer();
                            layer_off(action.layer_tap.val);
                            break;
                        } else if (tap_count < ONESHOT_TAP_TOGGLE) {
                            layer_on(action.layer_tap.val);
                            set_oneshot_layer(action.layer_tap.val, ONESHOT_START);
                        }
                    } else {
                        add_mods(get_oneshot_locked_mods());
                        if (tap_count >= ONESHOT_TAP_TOGGLE) {
                            reset_oneshot_layer();
                            clear_oneshot_locked_mods();
                            set_oneshot_layer(action.layer_tap.val, ONESHOT_TOGGLED);
                        } else {
                            clear_oneshot_layer_state(ONESHOT_PRESSED);
                        }
                    }
                #else
                    if (event.pressed) {
                        layer_on(action.layer_tap.val);
                        set_oneshot_layer(action.layer_tap.val, ONESHOT_START);
                    } else {
                        clear_oneshot_layer_state(ONESHOT_PRESSED);
                        if (tap_count > 1) {
                            clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED);
                        }
                    }
                #endif
                    break;
            #endif
                default:
                    /* tap key */
                    if (event.pressed) {
                        if (tap_count > 0) {
                            dprint("KEYMAP_TAP_KEY: Tap: register_code\n");
                            register_code(action.layer_tap.code);
                        } else {
                            dprint("KEYMAP_TAP_KEY: No tap: On on press\n");
                            layer_on(action.layer_tap.val);
                        }
                    } else {
                        if (tap_count > 0) {
                            dprint("KEYMAP_TAP_KEY: Tap: unregister_code\n");
                            if (action.layer_tap.code == KC_CAPS) {
                                wait_ms(80);
                            }
                            unregister_code(action.layer_tap.code);
                        } else {
                            dprint("KEYMAP_TAP_KEY: No tap: Off on release\n");
                            layer_off(action.layer_tap.val);
                        }
                    }
                    break;
            }
            break;
    #endif
#endif
        /* Extentions */
#ifndef NO_ACTION_MACRO
        case ACT_MACRO:
            action_macro_play(action_get_macro(record, action.func.id, action.func.opt));
            break;
#endif
#ifdef BACKLIGHT_ENABLE
        case ACT_BACKLIGHT:
            if (!event.pressed) {
                switch (action.backlight.opt) {
                    case BACKLIGHT_INCREASE:
                        backlight_increase();
                        break;
                    case BACKLIGHT_DECREASE:
                        backlight_decrease();
                        break;
                    case BACKLIGHT_TOGGLE:
                        backlight_toggle();
                        break;
                    case BACKLIGHT_STEP:
                        backlight_step();
                        break;
                    case BACKLIGHT_ON:
                        backlight_level(BACKLIGHT_LEVELS);
                        break;
                    case BACKLIGHT_OFF:
                        backlight_level(0);
                        break;
                }
            }
            break;
#endif
        case ACT_COMMAND:
            break;
#ifdef SWAP_HANDS_ENABLE
        case ACT_SWAP_HANDS:
            switch (action.swap.code) {
                case OP_SH_TOGGLE:
                    if (event.pressed) {
                        swap_hands = !swap_hands;
                    }
                    break;
                case OP_SH_ON_OFF:
                    swap_hands = event.pressed;
                    break;
                case OP_SH_OFF_ON:
                    swap_hands = !event.pressed;
                    break;
                case OP_SH_ON:
                    if (!event.pressed) {
                        swap_hands = true;
                    }
                    break;
                case OP_SH_OFF:
                    if (!event.pressed) {
                        swap_hands = false;
                    }
                    break;
    #ifndef NO_ACTION_TAPPING
                case OP_SH_TAP_TOGGLE:
                    /* tap toggle */

                    if (event.pressed) {
                        if (swap_held) {
                            swap_held = false;
                        } else {
                            swap_hands = !swap_hands;
                        }
                    } else {
                        if (tap_count < TAPPING_TOGGLE) {
                            swap_hands = !swap_hands;
                        }
                    }
                    break;
                default:
                    /* tap key */
                    if (tap_count > 0) {
                        if (swap_held) {
                            swap_hands = !swap_hands; // undo hold set up in _tap_hint
                            swap_held = false;
                        }
                        if (event.pressed) {
                            register_code(action.swap.code);
                        } else {
                            unregister_code(action.swap.code);
                            *record = (keyrecord_t){}; // hack: reset tap mode
                        }
                    } else {
                        if (swap_held && !event.pressed) {
                            swap_hands = !swap_hands; // undo hold set up in _tap_hint
                            swap_held = false;
                        }
                    }
    #endif
            }
#endif
#ifndef NO_ACTION_FUNCTION
        case ACT_FUNCTION:
            action_function(record, action.func.id, action.func.opt);
            break;
#endif
        default:
            break;
    }

#ifndef NO_ACTION_LAYER
    // if this event is a layer action, update the leds
    switch (action.kind.id) {
        case ACT_LAYER:
        #ifndef NO_ACTION_TAPPING
        case ACT_LAYER_TAP:
        case ACT_LAYER_TAP_EXT:
        #endif
            led_set(host_keyboard_leds());
            break;
        default:
            break;
    }
#endif

#ifndef NO_ACTION_TAPPING
  #ifdef RETRO_TAPPING
  if (!is_tap_key(record->event.key)) {
    retro_tapping_counter = 0;
  } else {
    if (event.pressed) {
        if (tap_count > 0) {
          retro_tapping_counter = 0;
        } else {

        }
    } else {
      if (tap_count > 0) {
        retro_tapping_counter = 0;
      } else {
        if (retro_tapping_counter == 2) {
          register_code(action.layer_tap.code);
          unregister_code(action.layer_tap.code);
        }
        retro_tapping_counter = 0;
      }
    }
  }
  #endif
#endif

#ifndef NO_ACTION_ONESHOT
    /* Because we switch layers after a oneshot event, we need to release the
     * key before we leave the layer or no key up event will be generated.
     */
    if (do_release_oneshot && !(get_oneshot_layer_state() & ONESHOT_PRESSED )   ) {
        record->event.pressed = false;
        layer_on(get_oneshot_layer());
        process_record(record);
        layer_off(get_oneshot_layer());
    }
#endif
}
Exemple #12
0
void process_record_nocache(keyrecord_t *record)
{
    process_record(record);
}
Exemple #13
0
void process_record_nocache(keyrecord_t *record)
{
    disable_action_cache = true;
    process_record(record);
    disable_action_cache = false;
}
/******************************************************************************
 *                                                                            *
 * Function: node_history                                                     *
 *                                                                            *
 * Purpose: process new history received from a slave node                    *
 *                                                                            *
 * Parameters:                                                                *
 *                                                                            *
 * Return value:  SUCCEED - processed successfully                            *
 *                FAIL - an error occurred                                    *
 *                                                                            *
 * Author: Alexei Vladishev                                                   *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
int	node_history(char *data, size_t datalen)
{
	const char		*r;
	char			*newline = NULL;
	char			*pos;
	int			sender_nodeid = 0, nodeid = 0, firstline = 1, events = 0, history = 0, acknowledges = 0;
	const ZBX_TABLE		*table_sync = NULL, *table = NULL;
	int			res = SUCCEED;

	char			*sql1 = NULL, *sql2 = NULL, *sql3 = NULL;
	size_t			sql1_alloc, sql2_alloc, sql3_alloc;
	size_t			sql1_offset, sql2_offset, sql3_offset;

	zbx_vector_uint64_t	ack_eventids;

	assert(data);

	zabbix_log(LOG_LEVEL_DEBUG, "In node_history()");

	buffer_alloc = 4 * ZBX_KIBIBYTE;
	sql1_alloc = 32 * ZBX_KIBIBYTE;
	sql2_alloc = 32 * ZBX_KIBIBYTE;
	sql3_alloc = 32 * ZBX_KIBIBYTE;
	tmp_alloc = 4 * ZBX_KIBIBYTE;

	buffer = zbx_malloc(buffer, buffer_alloc);
	sql1 = zbx_malloc(sql1, sql1_alloc);
	sql2 = zbx_malloc(sql2, sql2_alloc);
	sql3 = zbx_malloc(sql3, sql3_alloc);
	tmp = zbx_malloc(tmp, tmp_alloc);

	zbx_vector_uint64_create(&ack_eventids);

	DBbegin();

	for (r = data; *r != '\0' && res == SUCCEED;)
	{
		if (NULL != (newline = strchr(r, '\n')))
			*newline = '\0';

		if (1 == firstline)
		{
			zbx_get_next_field(&r, &buffer, &buffer_alloc, ZBX_DM_DELIMITER); /* constant 'History' */
			zbx_get_next_field(&r, &buffer, &buffer_alloc, ZBX_DM_DELIMITER); /* sender_nodeid */
			sender_nodeid=atoi(buffer);
			zbx_get_next_field(&r, &buffer, &buffer_alloc, ZBX_DM_DELIMITER); /* nodeid */
			nodeid=atoi(buffer);
			zbx_get_next_field(&r, &buffer, &buffer_alloc, ZBX_DM_DELIMITER); /* tablename */

			if (FAIL == is_direct_slave_node(sender_nodeid))
			{
				zabbix_log(LOG_LEVEL_ERR, "NODE %d: Received data from node %d"
							" that is not a direct slave node",
						CONFIG_NODEID, sender_nodeid);
				res = FAIL;
			}

			if (FAIL == is_slave_node(CONFIG_NODEID, nodeid))
			{
				zabbix_log(LOG_LEVEL_ERR, "NODE %d: Received history for unknown slave node %d",
						CONFIG_NODEID, nodeid);
				res = FAIL;
			}

			table = DBget_table(buffer);
			if (NULL != table && 0 == (table->flags & (ZBX_HISTORY | ZBX_HISTORY_SYNC)))
				table = NULL;

			if (NULL != table && 0 != (table->flags & ZBX_HISTORY_SYNC))
			{
				table_sync = table;
				if (NULL != (pos = strstr(buffer, "_sync")))
				{
					*pos = '\0';
					table = DBget_table(buffer);
				}
			}

			if (NULL == table)
			{
				zabbix_log(LOG_LEVEL_ERR, "NODE %d: Invalid received data: unknown tablename \"%s\"",
						CONFIG_NODEID, buffer);
				res = FAIL;
			}
			else
			{
				if (0 == strcmp(table->table, "events"))
					events = 1;

				if (0 == strncmp(table->table, "history", 7))
					history = 1;

				if (0 == strcmp(table->table, "acknowledges"))
					acknowledges = 1;
			}

			if (NULL != newline)
			{
				zabbix_log(LOG_LEVEL_WARNING, "NODE %d: Received %s from node %d for node %d datalen " ZBX_FS_SIZE_T,
						CONFIG_NODEID, buffer, sender_nodeid, nodeid, (zbx_fs_size_t)datalen);
			}
			firstline = 0;
			sql1_offset = 0;
			sql2_offset = 0;
			sql3_offset = 0;
		}
		else if (NULL != table)
		{
			if (events)
			{
				res = process_record_event(sender_nodeid, nodeid, table, r);
			}
			else
			{
				res = process_record(&sql1, &sql1_alloc, &sql1_offset, sender_nodeid,
						nodeid, table, r, newline ? 0 : 1, acknowledges, &ack_eventids);

				if (SUCCEED == res && 0 != history)
				{
					res = process_items(&sql2, &sql2_alloc, &sql2_offset, sender_nodeid,
							nodeid, table, r, newline ? 0 : 1);
				}

				if (SUCCEED == res && NULL != table_sync && 0 != CONFIG_MASTER_NODEID)
				{
					res = process_record(&sql3, &sql3_alloc, &sql3_offset, sender_nodeid,
							nodeid, table_sync, r, newline ? 0 : 1, 0, NULL);
				}
			}
		}

		if (newline != NULL)
		{
			*newline = '\n';
			r = newline + 1;
		}
		else
			break;
	}

	if (SUCCEED == res)
		DBcommit();
	else
		DBrollback();

	zbx_vector_uint64_destroy(&ack_eventids);

	zbx_free(tmp);
	zbx_free(sql1);
	zbx_free(sql2);
	zbx_free(sql3);
	zbx_free(buffer);

	return res;
}
Exemple #15
0
void process_simple_msnms_client_request(struct Seaper *seap, struct NetFrame *frame, const unsigned char *px, unsigned length)
{
	unsigned offset=0;
	unsigned char cmd[16] = "";
	unsigned i;
	unsigned eol=0;

	/*Find out length of the command line */
	for (eol=0; eol<length && px[eol] != '\n'; eol++)
		;

	skip_whitespace(px, length, &offset);

	/* get command */
	i=0;
	while (offset < length && px[offset] != '\n' && !isspace(px[offset])) {
		if (i<sizeof(cmd)-1) {
			cmd[i++] = px[offset];
			cmd[i] = '\0';
		}
		offset++;
	}
	skip_whitespace(px, length, &offset);

	SAMPLE("MSN-MSGR", "command", REC_SZ, cmd, -1);

	switch (CMD(cmd)) {
    case 0x56455200: /* "VER" */
		while (offset < eol) {
			unsigned parm = offset;
			unsigned parm_length = get_parm(px, length, &offset);

			if (is_number(px+parm, parm_length))
				continue;

			if (equals(px+parm, parm_length, "CVR0"))
				continue;


			/* Syntax:
			 * VER <TrID> <protocol> <protocol> .... 
			 *
			 *	Indicates a list of protocols supported
			 *
			 *  Examples:
			 *		VER 0 MSNP8 CVR0
			 *		VER 0 MSNP8 MYPROTOCOL CVR0
			 */
			process_record(seap,
				"ID-IP",	REC_FRAMESRC,	frame, -1,
				"app",		REC_SZ,			"MSN-MSGR",		-1,
				"ver",		REC_PRINTABLE,	px+parm, parm_length,
				0);
		}				

		break;
    case 0x4e4c4e00: /* "NLN" */
		break;
    case 0x514e4700: /* "QNG" */
		break;
    case 0x43565200: /* "CVR" */
/*
    *  The first parameter is hexadecimal number specifying your locale ID (e.g. "0x0409" For U.S. English).
    * The second parameter is your OS type (e.g. "win" for Windows).
    * The third parameter is your OS version (e.g. "4.10" for Windows 98).
    * The fourth parameter is the architecture of your computer (e.g. "i386" for Intel-comaptible PCs of type 386 or above).
    * The fifth parameter is your client name (e.g. "MSMSGR" for the official MSN Messenger client).
    * The sixth parameter is your client version (e.g. "6.0.0602").
    * The seventh parameter is always "MSMSGS" in the official client. Your guess about what this means is as good as mine.
    * The eighth parameter is your passport.
*/
		{
			unsigned trid, trid_length;
			unsigned localid, localid_length;
			unsigned ostype, ostype_length;
			unsigned osver, osver_length;
			unsigned arch, arch_length;
			unsigned clientname, clientname_length;
			unsigned clientver, clientver_length;
			unsigned msmsgs, msmsgs_length;
			unsigned passport, passport_length;

			trid = offset;
			trid_length = get_parm(px, length, &offset);
			
			localid=offset;
			localid_length = get_parm(px, length, &offset);
			
			ostype=offset;
			ostype_length = get_parm(px, length, &offset);
			
			osver=offset;
			osver_length = get_parm(px, length, &offset);
			
			arch=offset;
			arch_length = get_parm(px, length, &offset);
			
			clientname=offset;
			clientname_length = get_parm(px, length, &offset);
			
			clientver=offset;
			clientver_length = get_parm(px, length, &offset);
			
			msmsgs=offset;
			msmsgs_length = get_parm(px, length, &offset);
			
			passport=offset;
			passport_length = get_parm(px, length, &offset);
			
			process_record(seap,
				"ID-IP",	REC_FRAMESRC,	frame, -1,
				"Passport",	REC_PRINTABLE,	px+passport, passport_length,
				0);

			process_record(seap,
				"proto",	REC_SZ,			"MSN-MSGR", -1,
				"ip",		REC_FRAMESRC,	frame, -1,
				"localid",	REC_PRINTABLE, px+localid, localid_length,
				0);
			process_record(seap,
				"proto",	REC_SZ,			"MSN-MSGR", -1,
				"ip",		REC_FRAMESRC,	frame, -1,
				"ostype",	REC_PRINTABLE, px+ostype, ostype_length,
				0);
			process_record(seap,
				"proto",	REC_SZ,			"MSN-MSGR", -1,
				"ip",		REC_FRAMESRC,	frame, -1,
				"osver",	REC_PRINTABLE	, px+osver, osver_length,
				0);
			process_record(seap,
				"proto",	REC_SZ,			"MSN-MSGR", -1,
				"ip",		REC_FRAMESRC,	frame, -1,
				"arch",		REC_PRINTABLE	, px+arch, arch_length,
				0);
			process_record(seap,
				"proto",	REC_SZ,			"MSN-MSGR", -1,
				"ip",		REC_FRAMESRC,	frame, -1,
				"clientname",	REC_PRINTABLE, px+clientname, clientname_length,
				0);
			process_record(seap,
				"proto",	REC_SZ,			"MSN-MSGR", -1,
				"ip",		REC_FRAMESRC,	frame, -1,
				"clientver",REC_PRINTABLE, px+clientver, clientver_length,
				0);
			process_record(seap,
				"proto",	REC_SZ,			"MSN-MSGR", -1,
				"ip",		REC_FRAMESRC,	frame, -1,
				"msmsgs",	REC_PRINTABLE, px+msmsgs, msmsgs_length,
				0);
			process_record(seap,
				"proto",	REC_SZ,			"MSN-MSGR", -1,
				"ip",		REC_FRAMESRC,	frame, -1,
				"passport",	REC_PRINTABLE, px+passport, passport_length,
				0);

		}				
		break;
    case 0x55535200: /* "USR" */
	/*After receiving the response to CVR, you must send the USR command. It has a TrID.
    * The first parameter is the authentication system (always TWN).
    * The second parameter is always the letter I (standing for initiating authentication).
    * The third parameter is the account name that you want to log on with.
	*/
		{
			unsigned trid, trid_length;
			unsigned twn, twn_length;
			unsigned ii, ii_length;
			unsigned username, username_length;

			trid = offset;
			trid_length = get_parm(px, length, &offset);
			
			twn = offset;
			twn_length = get_parm(px, length, &offset);

			ii = offset;
			ii_length = get_parm(px, length, &offset);

			username = offset;
			username_length = get_parm(px, length, &offset);

			process_record(seap,
				"proto",	REC_SZ,			"MSN-MSGR", -1,
				"ip",		REC_FRAMESRC,	frame, -1,
				"username",	REC_PRINTABLE, px+username, username_length,
				0);
			process_record(seap,
				"ID-IP",	REC_FRAMESRC,	frame, -1,
				"MSN-username",	REC_PRINTABLE,	px+username, username_length,
				0);
		}				
		break;
    case 0x4d534700: /* "MSG" */
    case 0x58465200: /* "XFR" */
	default:
		FRAMERR(frame, "msn-ms: unknown commanded from client: %.*s\n", length, px);
	}


	
}
Exemple #16
0
bool resolver::parse_message(msg& msg)
{
	if ((size_t) (msg.end - msg.data) <= sizeof(header)) {
		return false;
	}

	if (!parse_header(msg)) {
		return false;
	}

	if (msg.h->ancount == 0) {
		return false;
	}

	if (!find_first_record(msg)) {
		return false;
	}

	dns_entry entry;
	entry.name = msg.name;
	entry.namelen = msg.namelen;

	red_black_tree<dns_entry>::iterator it;
	if (!_M_cache.find(entry, it)) {
		// Name not found in the cache.
		return false;
	}

	dns_entry* e = it.data;

	msg.narecords = 0;
	msg.cnamelen = 0;

	for (unsigned short i = msg.h->ancount; (msg.ptr < msg.end) && (i > 0); i--) {
		rr rr;
		if (!find_next_record(msg, rr)) {
			return false;
		}

		if (!process_record(msg, rr)) {
			return false;
		}
	}

	time_t now = time(NULL);

	if (msg.narecords == 1) {
		// If not the original request...
		if (e->cnamelen > 0) {
			// The domain name of the original request is in e->cname.
			red_black_tree<dns_entry>::iterator itcname;
			if (!find(e->cname, e->cnamelen, itcname)) {
				_M_cache.erase(it);
				return false;
			}

			_M_cache.erase(it);

			e = itcname.data;
		}

		struct address* addr = msg.arecords;

		e->address.addr = addr->addr;
		e->address.expire = now + addr->expire;
		e->address.preference = addr->preference;

		e->addresses = &e->address;
		e->naddresses = 1;

		e->status = STATUS_VALID;

		return true;
	} else if (msg.narecords > 1) {
		// If not the original request...
		if (e->cnamelen > 0) {
			// The domain name of the original request is in e->cname.
			red_black_tree<dns_entry>::iterator itcname;
			if (!find(e->cname, e->cnamelen, itcname)) {
				_M_cache.erase(it);
				return false;
			}

			_M_cache.erase(it);

			e = itcname.data;
		}

		if ((e->addresses = (struct address*) malloc(msg.narecords * sizeof(struct address))) == NULL) {
			_M_cache.erase(it);
			return false;
		}

		struct address* addr = msg.arecords;
		for (unsigned short i = 0; i < msg.narecords; i++, addr++) {
			e->addresses[i].addr = addr->addr;
			e->addresses[i].expire = now + addr->expire;
			e->addresses[i].preference = addr->preference;
		}

		e->naddresses = msg.narecords;

		e->status = STATUS_VALID;

		return true;
	} else if (msg.cnamelen > 0) {
		dns_entry* ecname;

		// If not the original request...
		if (e->cnamelen > 0) {
			// The domain name of the original request is in e->cname.
			char* cname = e->cname;
			unsigned short cnamelen = e->cnamelen;

			red_black_tree<dns_entry>::iterator itcname;
			if (!find(cname, cnamelen, itcname)) {
				_M_cache.erase(it);
				return false;
			}

			e->cnamelen = 0;

			_M_cache.erase(it);

			if (++itcname.data->recursion > MAX_RECURSION) {
				_M_cache.erase(itcname);
				free(cname);
				return false;
			}

			if (!add_to_cache(msg.cname, msg.cnamelen, (rr_type) msg.type, &itcname)) {
				_M_cache.erase(itcname);
				free(cname);
				return false;
			}

			ecname = itcname.data;
			ecname->cname = cname;
			ecname->cnamelen = cnamelen;
		} else {
			red_black_tree<dns_entry>::iterator itcname;
			if (!add_to_cache(msg.cname, msg.cnamelen, (rr_type) msg.type, &itcname)) {
				_M_cache.erase(it);
				return false;
			}

			ecname = itcname.data;
			if ((ecname->cname = (char*) malloc(msg.namelen)) == NULL) {
				_M_cache.erase(itcname);
				_M_cache.erase(it);
				return false;
			}

			memcpy(ecname->cname, msg.name, msg.namelen);
			ecname->cnamelen = msg.namelen;
		}

		return make_request(ecname->name, ecname->namelen, (rr_type) ecname->type, true);
	} else {
		return false;
	}
}
Exemple #17
0
static void do_trace_hist(struct tracecmd_input *handle)
{
	struct pevent *pevent = tracecmd_get_pevent(handle);
	struct event_format *event;
	struct pevent_record *record;
	int cpus;
	int cpu;
	int ret;

	ret = tracecmd_init_data(handle);
	if (ret < 0)
		die("failed to init data");

	if (ret > 0)
		die("trace-cmd hist does not work with latency traces\n");

	cpus = tracecmd_cpus(handle);

	/* Need to get any event */
	for (cpu = 0; cpu < cpus; cpu++) {
		record = tracecmd_peek_data(handle, cpu);
		if (record)
			break;
	}
	if (!record)
		die("No records found in file");

	ret = pevent_data_type(pevent, record);
	event = pevent_data_event_from_type(pevent, ret);

	long_size = tracecmd_long_size(handle);

	common_type_field = pevent_find_common_field(event, "common_type");
	if (!common_type_field)
		die("Can't find a 'type' field?");

	common_pid_field = pevent_find_common_field(event, "common_pid");
	if (!common_pid_field)
		die("Can't find a 'pid' field?");

	update_sched_wakeup(pevent);
	update_sched_wakeup_new(pevent);
	update_sched_switch(pevent);
	update_function(pevent);
	update_function_graph_entry(pevent);
	update_function_graph_exit(pevent);
	update_kernel_stack(pevent);

	for (cpu = 0; cpu < cpus; cpu++) {
		for (;;) {
			struct pevent_record *record;

			record = tracecmd_read_data(handle, cpu);
			if (!record)
				break;

			/* If we missed events, just flush out the current stack */
			if (record->missed_events)
				flush_stack();

			process_record(pevent, record);
			free_record(record);
		}
	}

	if (current_pid >= 0)
		save_call_chain(current_pid, ips, ips_idx, 0);
	if (pending_pid >= 0)
		save_call_chain(pending_pid, pending_ips, pending_ips_idx, 1);

	save_stored_stacks();

	sort_chains();
	print_chains(pevent);
}
Exemple #18
0
void process_dhcp(struct Seaper *seap, struct NetFrame *frame, const unsigned char *px, unsigned length)
{
	unsigned offset;
	struct DHCP dhcp;

	memset(&dhcp, 0, sizeof(dhcp));
	if (length < 200) {
		FRAMERR(frame, "dhcp: frame too short\n");
		return;
	}

	dhcp.op = px[0];
	dhcp.hardware_type = px[1];
	dhcp.hardware_address_length = px[2];
	dhcp.hops = px[3];

	dhcp.transaction_id = ex32be(px+4);
	dhcp.seconds_elapsed = ex16be(px+8);
	dhcp.flags = ex16be(px+10);

	dhcp.ciaddr = ex32be(px+12);
	dhcp.yiaddr = ex32be(px+16);
	dhcp.siaddr = ex32be(px+20);
	dhcp.giaddr = ex32be(px+24);

	memcpy(dhcp.chaddr, px+28, 16);
	dhcp.chaddr[16] = '\0';

	memcpy(dhcp.sname, px+28+16, 64);
	dhcp.sname[64] = '\0';

	memcpy(dhcp.file, px+28+16+64, 128);
	dhcp.file[128] = '\0';

	offset = 28+16+64+128;

	if (offset+4 > length)
		return;

	if (memcmp(px+offset, "\x63\x82\x53\x63", 4) != 0)
		return;
	offset += 4;

	/* Process special options */
	dhcp.msg = dhcp_number(px, length, 53);
	switch (dhcp.msg) {
	case 8: /* inform */
		/* Process vendor specific information */
		{
			const unsigned char *spec;
			unsigned spec_length;
			const unsigned char *id;
			unsigned id_length;

			dhcp_get_option(px, length, 43, &spec, &spec_length);
			dhcp_get_option(px, length, 60, &id, &id_length);

			if (spec_length && id_length) {
				process_record(seap,
					"application",	REC_PRINTABLE, id, id_length,
					"info",			REC_PRINTABLE, spec, spec_length,
					0);
			}
		}
	}



	process_dhcp_options(seap, frame, px, length, offset, &dhcp);

	if (dhcp.overload_filename)
		process_dhcp_options(seap, frame, px, 28+16+64+128, 28+16+64, &dhcp);
	if (dhcp.overload_servername)
		process_dhcp_options(seap, frame, px, 28+16+64, 28+16, &dhcp);

	SAMPLE("BOOTP", "type",	REC_UNSIGNED, &dhcp.op,	sizeof(dhcp.op));
	switch (dhcp.op) {
	case 1: /*BOOTP request */
		break;
	case 2: /*BOOTP reply*/ 
		switch (dhcp.msg) {
		case 2:
			break;
		case 5: /*ack*/
			break;
		case 6: /*DHCP NACK*/
			{
				const unsigned char *dst_mac;
				unsigned src_ip;

				if (dhcp.hardware_address_length != 6) {
					FRAMERR(frame, "dhcp: expected hardware address length = 6, found length = %d\n", dhcp.hardware_address_length);
					break;
				}
				if (memcmp(dhcp.chaddr, "\0\0\0\0\0\0", 6) == 0) {
					FRAMERR(frame, "dhcp: expected hardware address, but found [00:00:00:00:00:00]\n");
					break;
				} else
					dst_mac = &dhcp.chaddr[0];

				if (dhcp.server_identifier)
					src_ip = dhcp.server_identifier;
				else if (dhcp.siaddr)
					src_ip = dhcp.siaddr;
				else
					src_ip = frame->src_ipv4;

				process_record(seap,
					"proto",	REC_SZ,			"DHCP",		-1,
					"op",		REC_SZ,			"NACK",		-1,
					"src.ip",	REC_IPv4,		&src_ip,	sizeof(src_ip),
					"dst.mac",	REC_MACADDR,	dst_mac,	6,
					0);
			}
			break;
		case 8:
			break;
		default:
			FRAMERR(frame, "dhcp: unknown dhcp msg type %d\n", dhcp.msg);
			break;
		}
		break;
	default:
			FRAMERR(frame, "dhcp: unknown bootp op code %d\n", dhcp.op);
		break;

	}

}
Exemple #19
0
void process_dhcp_options(struct Seaper *seap, struct NetFrame *frame, const unsigned char *px, unsigned length, unsigned offset, struct DHCP *dhcp)
{
	seap;
	while (offset < length) {
		unsigned tag;
		unsigned len;

		tag = px[offset++];
		if (tag == 0xFF)
			break; /*end of list*/
		if (tag == 0x00)
			continue; /*padding*/

		if (offset >= length) {
			FRAMERR(frame, "dhcp: option too short\n");
			break;
		}
		len = px[offset++];
		if (offset >= length) {
			FRAMERR(frame, "dhcp: option too short\n");
			break;
		}

		SAMPLE("DHCP", "tag",	REC_UNSIGNED, &tag,	sizeof(tag));

		switch (tag) {
		case 1: /*0x01 - Subnet tag */
			break;
		case 3: /*Router */
			if (len !=  4)
				FRAMERR(frame, "dhcp: abnormal length, tag=%d, len=%d\n", tag, len);
			else {
				unsigned ip = ex32be(px+offset);
				process_record(seap,
					"proto",	REC_SZ,			"DHCP",		-1,
					"server",	REC_FRAMESRC,	frame, -1, 
					"op",		REC_SZ,			"offer",-1,
					"router",	REC_IPv4,		&ip,	sizeof(ip),
					0);
			}
			break;
		case 6: /*DNS server*/
			{
				unsigned i;
				for (i=0; i<len; i+=4) {
					unsigned ip = ex32be(px+offset+i);
					process_record(seap,
						"proto",	REC_SZ,			"DHCP",		-1,
						"server",	REC_FRAMESRC,	frame, -1,
						"op",		REC_SZ,			"offer",-1,
						"dns-server",REC_IPv4,		&ip,	sizeof(ip),
						0);
				}
			}
			break;
		case 12: /*0x0c - Hostname */
			if (len ==  0)
				FRAMERR(frame, "dhcp: abnormal length, tag=%d, len=%d\n", tag, len);
			else
				process_record(seap,
					"ID-MAC",	REC_MACADDR,	dhcp->chaddr,	6,
					"proto",	REC_SZ,			"DHCP",		-1,
					"op",		REC_SZ,			"Hostname",-1,
					"hostname",	REC_PRINTABLE,	px+offset,	len,
					0);
			break;
		case 15: /*0x0f - Domain Name */
			if (len ==  0)
				FRAMERR(frame, "dhcp: abnormal length, tag=%d, len=%d\n", tag, len);
			else
				process_record(seap,
					"proto",	REC_SZ,			"DHCP",		-1,
					"server",	REC_FRAMESRC,	frame, -1,
					"op",		REC_SZ,			"offer",-1,
					"domainname",	REC_PRINTABLE,	px+offset,	len,
					0);
			break;
		case 31: /*perform router discovery*/
			{
				unsigned discovery=0;
				unsigned i;
				for (i=0; i<len; i++)
					discovery = discovery*10 + px[offset+i];
				process_record(seap,
					"proto",	REC_SZ,			"DHCP",		-1,
					"server",	REC_FRAMESRC,	frame, -1,
					"op",		REC_SZ,			"offer",-1,
					"discovery",REC_UNSIGNED,	&discovery,	sizeof(discovery),
					0);
			}
			break;
		case 53: /*0x35 - DHCP message type*/
			if (len != 1) {
				FRAMERR(frame, "dhcp: abnormal length, tag=%d, len=%d\n", tag, len);
				break;
			}
			dhcp->msg = px[offset];

			switch (dhcp->msg) {
			case 1: /*discover*/
			case 2: /*offer*/
			case 3: /*request*/
			case 5: /*ack*/
			case 6: /*nak*/
			case 7: /* release */
			case 8: /*inform*/
				SAMPLE("DHCP", "msg",	REC_UNSIGNED, &dhcp->msg,	sizeof(dhcp->msg));
				break;
			default:
				FRAMERR(frame, "dhcp: ungknown msg type %d\n", dhcp->msg);
			}
			break;
		case 55: /* 0x37 - Parameter Request List */
			if (len == 0)
				FRAMERR(frame, "dhcp: abnormal length, tag=%d, len=%d\n", tag, len);
			break;
		case 0x36: /* Server Identifier*/
			if (len != 4) {
				FRAMERR(frame, "dhcp: abnormal option length\n");
				break;
			}
			dhcp->server_identifier = ex32be(px+offset);
			break;
		case 43: /* vendor info*/
			if (len ==  0)
				FRAMERR(frame, "dhcp: abnormal length, tag=%d, len=%d\n", tag, len);
			else
				process_record(seap,
					"ID-MAC",	REC_MACADDR,	dhcp->chaddr,	6,
					"proto",	REC_SZ,			"DHCP",		-1,
					"op",		REC_SZ,			"Vendor-Info",-1,
					"info",	REC_PRINTABLE,	px+offset,	len,
					0);
			break;
		case 60: /* 0x3c - Vendor class identifier */
			if (len ==  0)
				FRAMERR(frame, "dhcp: abnormal length, tag=%d, len=%d\n", tag, len);
			else
				process_record(seap,
					"ID-MAC",	REC_MACADDR,	dhcp->chaddr,	6,
					"proto",	REC_SZ,			"DHCP",		-1,
					"op",		REC_SZ,			"Vendor-ID",-1,
					"vendor",	REC_PRINTABLE,	px+offset,	len,
					0);
			break;
		case 61: /* 0x3d - Client identifier */
			if (len < 2)
				FRAMERR(frame, "dhcp: abnormal length, tag=%d, len=%d\n", tag, len);
			else {
				const unsigned char *clientid = px+offset+1;
				switch (px[offset]) {
				case 0:
					break;
				case 1:
					if (len != 7)
						FRAMERR(frame, "dhcp: abnormal length, tag=%d, len=%d\n", tag, len);
					else {
						if (memcmp(dhcp->chaddr, "\0\0\0\0\0\0", 6) == 0) {
							FRAMERR(frame, "untested code path\n");
							memcpy(dhcp->chaddr, clientid, 6);
							dhcp->hardware_type = 1;
							dhcp->hardware_address_length = 6;
						}
						else if (memcmp(dhcp->chaddr, clientid, 6) != 0) {
							FRAMERR(frame, "untested code path\n");
							process_record(seap,
								"ID-MAC",	REC_MACADDR,	dhcp->chaddr,	6,
								"proto",	REC_SZ,			"DHCP",		-1,
								"op",		REC_SZ,			"Client-ID",-1,
								"new.mac",	REC_MACADDR,	clientid,	6,
								0);
						}
					}
				}
			}
			break;
		case 50: /* 0x32 - Request IP */
			if (len != 4)
				FRAMERR(frame, "dhcp: abnormal length, tag=%d, len=%d\n", tag, len);
			else {
				unsigned ip_address = ex32be(px+offset);
				process_record(seap,
					"ID-MAC",	REC_MACADDR,	dhcp->chaddr,	6,
					"proto",	REC_SZ,			"DHCP",		-1,
					"op",		REC_SZ,			"Request-IP",-1,
					"ip",		REC_IPv4,		&ip_address,	sizeof(ip_address),
					0);
			}
			break;
		case 51: /* IP address lease time */
			if (len !=  4)
				FRAMERR(frame, "dhcp: abnormal length, tag=%d, len=%d\n", tag, len);
			else {
				unsigned lease_time = ex32be(px+offset);
				process_record(seap,
					"proto",	REC_SZ,			"DHCP",		-1,
					"server",	REC_FRAMESRC,	frame, -1,
					"op",		REC_SZ,			"offer",-1,
					"leasetime",REC_UNSIGNED,	&lease_time,	sizeof(lease_time),
					0);
			}
			break;
		case 52: /* Option Overload */
			if (len != 1)
				FRAMERR(frame, "dhcp: abnormal length, tag=%d, len=%d\n", tag, len);
			else {
				if (px[offset] & 1)
					dhcp->overload_filename = 1;
				if (px[offset] & 2)
					dhcp->overload_servername = 1;
			}
			break;
		case 57: /* Mac DHCP message size, used by diskless clients to report 1500 so they don't have to reassemble?*/
			break;
		case 81:
			if (len < 4)
				FRAMERR(frame, "dhcp: abnormal length, tag=%d, len=%d\n", tag, len);
			else {
				const char *name = (const char*)px+offset+3;
				unsigned name_length = len-3;

				process_record(seap,
					"ID-MAC",	REC_MACADDR,	dhcp->chaddr,	6,
					"proto",	REC_SZ,			"DHCP",		-1,
					"op",		REC_SZ,			"FQDN", -1,
					"fqdn",		REC_PRINTABLE,	name, name_length,
					0);
				
				if (dhcp->op != 1)
					FRAMERR(frame, "implement this code path\n");
			}
			break;

		case 116: /*0x74 - Auto-configure */
			if (len != 1) {
				FRAMERR(frame, "dhcp: abnormal option length\n");
				break;
			}
			switch (px[offset]) {
			case 0: dhcp->rfc2563_auto_configure = 2; break;
			case 1: dhcp->rfc2563_auto_configure = 1; break;
			default:
				FRAMERR(frame, "dhcp: bad value, tag=%d, len=%d\n", tag, len);
			}
			break;
		case 44: /* netbios over tcp/ip server */
			break;
		default:
			FRAMERR(frame, "dhcp: tag: unknown %d (0x%02x)\n", tag, tag);
			break;
		}


		offset += len;
	}
}
/**
 * monitor_tbufs - monitor the contents of tbufs
 */
int monitor_tbufs(void)
{
    int i;
    extern int process_record(int, struct t_rec *);
    extern void alloc_qos_data(int ncpu);

    void *tbufs_mapped;          /* pointer to where the tbufs are mapped    */
    struct t_buf **meta;         /* pointers to the trace buffer metadata    */
    char         **data;         /* pointers to the trace buffer data areas
                                  * where they are mapped into user space.   */
    unsigned long tbufs_mfn;     /* mfn of the tbufs                         */
    unsigned int  num;           /* number of trace buffers / logical CPUS   */
    unsigned long size;          /* size of a single trace buffer            */

    unsigned long data_size, rec_size;

    /* get number of logical CPUs (and therefore number of trace buffers) */
    num = get_num_cpus();

    init_current(num);
    alloc_qos_data(num);

    printf("CPU Frequency = %7.2f\n", opts.cpu_freq);
    
    /* setup access to trace buffers */
    get_tbufs(&tbufs_mfn, &size);

    tbufs_mapped = map_tbufs(tbufs_mfn, num, size);

    data_size = size - sizeof(struct t_buf);

    /* build arrays of convenience ptrs */
    meta  = init_bufs_ptrs (tbufs_mapped, num, size);
    data  = (char **)init_rec_ptrs(meta, num);

    if ( eventchn_init() < 0 )
        fprintf(stderr, "Failed to initialize event channel; "
                "Using POLL method\r\n");

    /* now, scan buffers for events */
    while ( !interrupted )
    {
        for ( i = 0; (i < num) && !interrupted; i++ )
        {
            while ( meta[i]->cons != meta[i]->prod )
            {
                rmb(); /* read prod, then read item. */
                rec_size = process_record(
                    i, (struct t_rec *)(data[i] + meta[i]->cons % data_size));
                mb(); /* read item, then update cons. */
                meta[i]->cons += rec_size;
            }
        }

	wait_for_event();
	wakeups++;
    }

    /* cleanup */
    free(meta);
    free(data);
    /* don't need to munmap - cleanup is automatic */

    return 0;
}
Exemple #21
0
int process_telemetry(char *host, int port, unsigned char *buf,
		      char *match, char *netcode, int rec_size)
{
  struct sockaddr_in sin;
  struct hostent *hp;
  int sock, count, optval, i;
  int bufpop;

  /*
   * Translate the hostname into an internet address
   */
  hp = gethostbyname(host);
  if(hp == 0) {
    lprintf(0, "%s: unknown host",host);
    exit(1);
  }

  /*
   * We now create a socket which will be used for our connection.
   */
  sock = socket(AF_INET, SOCK_STREAM, 0);
  if(sock < 0) {
    lprintf(0, "Couldn't open local socket - %s",
	    strerror(errno));
    return 1;
  }

  /*
   *  Before we attempt a connect, we fill up the "sockaddr_in" structure
   */
  memcpy((char *)&sin.sin_addr, hp->h_addr , hp->h_length);
  sin.sin_family      = AF_INET;
  sin.sin_port        = htons(port);
  /*
   *  Now attempt to connect to the remote host .....
   */
  if(connect(sock, (struct sockaddr *) &sin, sizeof(sin)) < 0) {
    lprintf(0, "Couldn't connect to server %s - %s",host,
	    strerror(errno));
    return 2;
  }

  /* if 1+ verbose flag(s) given report the connection */
  lprintf(1, "Connected to %s:%d", host,port);

  /* Turn on keepalive on socket so we won't hang if it gets stuck */
  optval = 1;
  i = setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (char *) &optval, sizeof(int));
  
  if ( i == -1 ) 
    lprintf(1, "Couldn't set keepalive on socket %s",
	    strerror(errno));

  bufpop = 0;

  while ( 1 ) {

    /*
     * Read from the network
     */
    count = recv(sock, &buf[bufpop], 256, 0);

    if(count < 0) {
      lprintf(0, "Read error from server - %s", strerror(errno));
      return 3;
    }
    if (count==0) {
      lprintf(1, "EOF (zero byte count) received");
      break;
    }
    
    bufpop += count;

    while (bufpop>=rec_size) {

      process_record((char *) buf, match, netcode, rec_size);
      bufpop -= rec_size;
      if (bufpop>0)
	memcpy(buf,&buf[rec_size],bufpop);
    }

    /*
     * Continue the loop
     */
  }

  close(sock);

  return(0);
}
ph_stats_t*
ph_stats_new(capture_file *cf)
{
	ph_stats_t	*ps;
	guint32		framenum;
	frame_data	*frame;
	guint		tot_packets, tot_bytes;
	progdlg_t	*progbar = NULL;
	gboolean	stop_flag;
	int		count;
	float		progbar_val;
	GTimeVal	start_time;
	gchar		status_str[100];
	int		progbar_nextstep;
	int		progbar_quantum;

	if (!cf) return NULL;

	/* Initialize the data */
	ps = g_new(ph_stats_t, 1);
	ps->tot_packets = 0;
	ps->tot_bytes = 0;
	ps->stats_tree = g_node_new(NULL);
	ps->first_time = 0.0;
	ps->last_time = 0.0;

	/* Update the progress bar when it gets to this value. */
	progbar_nextstep = 0;
	/* When we reach the value that triggers a progress bar update,
	   bump that value by this amount. */
	progbar_quantum = cf->count/N_PROGBAR_UPDATES;
	/* Count of packets at which we've looked. */
	count = 0;
	/* Progress so far. */
	progbar_val = 0.0f;

	stop_flag = FALSE;
	g_get_current_time(&start_time);

	tot_packets = 0;
	tot_bytes = 0;

	for (framenum = 1; framenum <= cf->count; framenum++) {
		frame = frame_data_sequence_find(cf->frames, framenum);

		/* Create the progress bar if necessary.
		   We check on every iteration of the loop, so that
		   it takes no longer than the standard time to create
		   it (otherwise, for a large file, we might take
		   considerably longer than that standard time in order
		   to get to the next progress bar step). */
		if (progbar == NULL)
			progbar = delayed_create_progress_dlg(
			    cf->window, "Computing",
			    "protocol hierarchy statistics",
			    TRUE, &stop_flag, &start_time, progbar_val);

		/* Update the progress bar, but do it only N_PROGBAR_UPDATES
		   times; when we update it, we have to run the GTK+ main
		   loop to get it to repaint what's pending, and doing so
		   may involve an "ioctl()" to see if there's any pending
		   input from an X server, and doing that for every packet
		   can be costly, especially on a big file. */
		if (count >= progbar_nextstep) {
			/* let's not divide by zero. I should never be started
			 * with count == 0, so let's assert that
			 */
			g_assert(cf->count > 0);

			progbar_val = (gfloat) count / cf->count;

			if (progbar != NULL) {
				g_snprintf(status_str, sizeof(status_str),
					"%4u of %u frames", count, cf->count);
				update_progress_dlg(progbar, progbar_val, status_str);
			}

			progbar_nextstep += progbar_quantum;
		}

		if (stop_flag) {
			/* Well, the user decided to abort the statistics.
			   computation process  Just stop. */
			break;
		}

		/* Skip frames that are hidden due to the display filter.
		   XXX - should the progress bar count only packets that
		   passed the display filter?  If so, it should
		   probably do so for other loops (see "file.c") that
		   look only at those packets. */
		if (frame->flags.passed_dfilter) {

			if (frame->flags.has_ts) {
				if (tot_packets == 0) {
					double cur_time = nstime_to_sec(&frame->abs_ts);
					ps->first_time = cur_time;
					ps->last_time = cur_time;
				}
			}

			/* we don't care about colinfo */
			if (!process_record(cf, frame, NULL, ps)) {
				/*
				 * Give up, and set "stop_flag" so we
				 * just abort rather than popping up
				 * the statistics window.
				 */
				stop_flag = TRUE;
				break;
			}

			tot_packets++;
			tot_bytes += frame->pkt_len;
		}

		count++;
	}

	/* We're done calculating the statistics; destroy the progress bar
	   if it was created. */
	if (progbar != NULL)
		destroy_progress_dlg(progbar);

	if (stop_flag) {
		/*
		 * We quit in the middle; throw away the statistics
		 * and return NULL, so our caller doesn't pop up a
		 * window with the incomplete statistics.
		 */
		ph_stats_free(ps);
		return NULL;
	}

	ps->tot_packets = tot_packets;
	ps->tot_bytes = tot_bytes;

	return ps;
}
Exemple #23
0
_SUB int process_telemetry(char *host, int port)
{
  struct sockaddr_in sin;
  struct hostent *hp, *gethostbyname();
  int fd, count, optval, i;

  if (verbose)
    fprintf(stderr,"[Connecting to remote host: %s (port %d) blocksize %d]\n",
	    host,port,seed_size);

  /*
   * Translate the hostname into an internet address
   */
  hp = gethostbyname(host);
  if(hp == 0) {
    fprintf(stderr, "%s: unknown host\n",host);
    exit(1);
  }
  /*
   * We now create a socket which will be used for our connection.
   */
  fd = socket(AF_INET, SOCK_STREAM, 0);
  if(fd < 0) {
    fprintf(stderr,"Couldn't open socket on client socket - %s\n",
	    strerror(errno));
    return(1);
  }

  /*
   *  Before we attempt a connect, we fill up the "sockaddr_in" structure
   */
  memcpy((char *)&sin.sin_addr, hp->h_addr , hp->h_length);
  sin.sin_family      = AF_INET;
  sin.sin_port        = htons(port);
  /*
   *  Now attempt to connect to the remote host .....
   */
  if(connect(fd, (struct sockaddr *) &sin, sizeof(sin)) < 0) {
    fprintf(stderr,"Couldn't connect to server %s - %s\n",host,
	    strerror(errno));
    return(2);
  }

  if (verbose)
    fprintf(stderr,"Connected to remote host %s port %d (%s)\n",
	    host,port,hp->h_name);
  fflush(stderr);

  /* Turn on keepalive on socket so we won't hang if it gets stuck */

  optval = 1;
  i = setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (char *) &optval, sizeof(int));
  
  if (i==(-1)) 
    fprintf(stderr,"Couldn't set keepalive on client socket - ignored - %s\n",
	    strerror(errno));

  bufpop = 0;

  for (;;) {

    /*
     * Read from the network
     */
    count = recv(fd, &buf[bufpop], 256, 0);
    if(count < 0) {
      /* Unable to read from the terminal */
      fprintf(stderr,"Read error from server - %s\n",
	      strerror(errno));
      return(3);
    }
    if (count==0) {
      if (verbose)
	fprintf(stderr,"[End of file]\n");
      break;
    }
	
    bufpop += count;

    while (bufpop>=seed_size) {

      process_record((char *) buf);
      bufpop -= seed_size;
      if (bufpop>0)
	memcpy(buf,&buf[seed_size],bufpop);
    }

    /*
     * Continue the loop
     */
  }                  

  close(fd);

  return(0);
}
Exemple #24
0
void process_simple_msnms_server_response(struct Seaper *seap, struct NetFrame *frame, const unsigned char *px, unsigned length)
{
	unsigned offset=0;
	unsigned char cmd[16] = "";
	unsigned i;
	unsigned eol=0;

	/*Find out length of the command line */
	for (eol=0; eol<length && px[eol] != '\n'; eol++)
		;

	skip_whitespace(px, length, &offset);

	/* get command */
	i=0;
	while (offset < length && px[offset] != '\n' && !isspace(px[offset])) {
		if (i<sizeof(cmd)-1) {
			cmd[i++] = px[offset];
			cmd[i] = '\0';
		}
		offset++;
	}
	skip_whitespace(px, length, &offset);

	SAMPLE("MSN-MSGR", "command", REC_SZ, cmd, -1);

	switch (CMD(cmd)) {
    case 0x56455200: /* "VER" */
		while (offset < eol) {
			unsigned parm = offset;
			unsigned parm_length = get_parm(px, length, &offset);

			if (is_number(px+parm, parm_length))
				continue;

			if (equals(px+parm, parm_length, "CVR0"))
				continue;


			/* Syntax:
			 * VER <TrID> <protocol> <protocol> .... 
			 *
			 *	Indicates a list of protocols supported
			 *
			 *  Examples:
			 *		VER 0 MSNP8 CVR0
			 *		VER 0 MSNP8 MYPROTOCOL CVR0
			 */
			process_record(seap,
				"ID-IP",	REC_FRAMESRC,	frame, -1,
				"app",		REC_SZ,			"MSN-MSGR",		-1,
				"ver",		REC_PRINTABLE,	px+parm, parm_length,
				0);
		}				

		break;
    case 0x4e4c4e00: /* "NLN" */
		{
			unsigned state, state_length;
			unsigned handle, handle_length;
			unsigned friendly, friendly_length;

			state = offset;
			state_length = get_parm(px, length, &offset);

			handle = offset;
			handle_length = get_parm(px, length, &offset);

			friendly = offset;
			friendly_length = get_parm(px, length, &offset);

			process_record(seap,
				"proto",	REC_SZ,			"MSN-MSGR", -1,
				"ip",		REC_FRAMEDST,	frame, -1,
				"friend",	REC_PRINTABLE,	px+handle, handle_length,
				"name",		REC_PRINTABLE,	px+friendly, friendly_length,
				"state",	REC_PRINTABLE,	px+state, state_length,
				0);
		}				
		break;
    case 0x514e4700: /* "QNG" */
			process_record(seap,
				"proto",	REC_SZ,			"MSN-MSGR", -1,
				"ip",		REC_FRAMEDST,	frame, -1,
				0);
		break;
    case 0x43565200: /* "CVR" */
		break;
    case 0x55535200: /* "USR" */
		break;
    case 0x4d534700: /* "MSG" */
    case 0x58465200: /* "XFR" */
	default:
		FRAMERR(frame, "msn-ms: unknown commanded from client: %.*s\n", length, px);
	}


	
}