Preparing to Send the Probe

The IP Probe code running on the MS PIC performs a series of setup operations before sending the probe to the IP Probe manager running on the target router.

The steps described here are all executed from the main() function in the ipprobe.c file.

Initially, the application calls the FreeBSD function evCreate() to create an event context.

Next, the application reads the configuration values to determine what the user asked for.

Reading the Configuration

The application uses DAX to read the configuration in the config_read() function, in the file ipprobe_config.c. (For introductory information about DAX, see Using DAX to Read Configurations.) For example, the following code reads the probe name and its parameters:

status = -1;
    while (dax_visit_container(top, &dop)) {

        if (!dax_get_stringr_by_aid(dop, PROBE_NAME,
                probe_params.name, sizeof(probe_params.name))) {
            PRINT_ERROR("Read probe name!\n");
            goto exit;
        }

        if (strcmp(probe_params.name, probe_name) == 0) {

            /* Protocol is mandatory. */
            if (!dax_get_ubyte_by_aid(dop, PROBE_PROTOCOL,
                    &probe_params.protocol)) {
                PRINT_ERROR("Read probe protocol!\n");
                goto exit;
            }

            /* The following parameters are optional. */
            dax_get_ubyte_by_aid(dop, PROBE_TOS, &probe_params.tos);
            dax_get_ushort_by_aid(dop, PROBE_SRC_PORT,
                    &probe_params.src_port);
            dax_get_ushort_by_aid(dop, PROBE_DST_PORT,
                    &probe_params.dst_port);
            dax_get_ushort_by_aid(dop, PACKET_SIZE,
                    &probe_params.packet_size);
            dax_get_ushort_by_aid(dop, PACKET_COUNT,
                    &probe_params.packet_count);
            dax_get_ushort_by_aid(dop, PACKET_INTERVAL,
                    &probe_params.packet_interval);

            status = 0;
            break;
        }
    }

Connecting to the Manager

The connect_manager() function in the file ipprobe.c opens a socket, creates a signal handler, sets timeout values, connects to the manager running on the target, and creates a pipe for the session. The following snippets show the socket creation, connection, and pipe creation:

 /* Create socket to connect to the manager on the target. */
    manager_socket = socket(AF_INET, SOCK_STREAM, 0);

...

manager_addr.sin_port = htons(manager_port);
    if (connect(manager_socket, (struct sockaddr *)&manager_addr,
            sizeof(manager_addr)) < 0) {
        if (errno == EINTR) {
            PRINT_ERROR("Connect to the manager TIMEOUT!\n");
        } else {
            PRINT_ERRORNO("Connect to the manager\n");
        }
        goto error;
    }

...

 /* Create pipe for the session. */
    manager_pipe = ipc_pipe_create(PROBE_MANAGER_PIPE_SIZE);
    if (manager_pipe == NULL) {
        PRINT_ERROR("Create manager pipe!\n");
        goto error;
    }

    if (ipc_pipe_attach_socket(manager_pipe, manager_socket)) {
        PRINT_ERROR("Attach session pipe!");
        goto error;
    }

Once it has connected to the manager, the application retrieves the socket name by calling the FreeBSD function getsockname(). It then calls the enable_responder() function, which sends a message to the manager on the target router to set up the probe responder.

The request message to start the probe is defined as follows:

typedef struct {
         u_char  protocol;  /** The IP protocol */
         u_short port;      /** The protocol port */
 } msg_start_t;

...

 msg_start_t msg_data;

The code calls functions in libjipc to add the message to the pipe and then send it:

req.type = PROBE_MANAGER_MSG_TYPE;
    req.subtype = PROBE_MANAGER_MSG_START;
    req.length = sizeof(msg_data);

    msg_data.protocol = probe_params.protocol;
    msg_data.port = probe_params.dst_port;
    if (ipc_msg_write(manager_pipe, &req, &msg_data)) {
        PRINT_ERRORNO("Write message!");
        goto exit;
    } else if(ipc_pipe_write(manager_pipe, NULL)) {
        PRINT_ERRORNO("Write pipe!");
        goto exit;
    }

It then calls ipc_msg_read() to read the acknowledgment message from the manager:

    do {
        status = ipc_pipe_read(manager_pipe);
    } while ((status < 0) && (errno == EAGAIN));

...

    status = -1;
    msg = ipc_msg_read(manager_pipe);
    if ((msg->type != PROBE_MANAGER_MSG_TYPE)
            || (msg->subtype != PROBE_MANAGER_MSG_ACK)) {
        PRINT_ERROR("Read ACK message! type: %d", msg->subtype);
        goto exit;
    }
    status = 0;

Creating Sockets for the Probe Packets

The init_probe() function calls FreeBSD functions to create a socket for the probe packet(s) and sets socket options. It then allocates a buffer for the packet(s).

Setting Timers

The application next calls FreeBSD timer functions to set up timers for packet reception of the replies from the target router. The code specifies that the receive_probe_packets() event handler is to be invoked at the timer intervals. (See Receiving Reply Packets and Calculating Statistics for more information about this handler).

Sending the Probe


2007-2009 Juniper Networks, Inc. All rights reserved. The information contained herein is confidential information of Juniper Networks, Inc., and may not be used, disclosed, distributed, modified, or copied without the prior written consent of Juniper Networks, Inc. in an express license. This information is subject to change by Juniper Networks, Inc. Juniper Networks, the Juniper Networks logo, and JUNOS are registered trademarks of Juniper Networks, Inc. in the United States and other countries. All other trademarks, service marks, registered trademarks, or registered service marks are the property of their respective owners.
Generated on Sun May 30 20:26:47 2010 for Juniper Networks Partner Solution Development Platform JUNOS SDK 10.2R1 by Doxygen 1.4.5