freeipmi-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Freeipmi-users] rmcpping and simulated pong replies


From: Thomas Favre-Bulle
Subject: Re: [Freeipmi-users] rmcpping and simulated pong replies
Date: Fri, 04 Jun 2010 10:16:27 +0200
User-agent: Thunderbird 2.0.0.24 (X11/20100411)

Hi Al,


If the packet is ill-formed, unassemble_rmcp_pkt will return 0.
Ill-formed usually means a packet is not a correct length.

Are you adding the 6 bytes of "reserved" data at the end of the packet?
I could see how one might think it's optional, but looking at the spec,
it appears to be required.

Yes, I added the last 6 bytes of reserved data (and set them to 0) at
the end of the packet. I'm sending, along with this email, a wireshark
capture of the network traffic between two hosts (one using rmcpping
(172.16.1.1), the other running a daemon listening on port 623/udp
(172.16.3.1)).
The capture shows that pong messages are well formed (at least it
appears so). However, rmcpping doesn't seem to accept them as valid pong
replies. I believe you understand my confusion about this issue !

Below is the C function used to build and send pong packets, if
additionnal chunk of code is needed for understanding I can provide it :

void send_pong(struct in_addr ip_dst, struct in_addr ip_src, const
u_int16_t dport, const u_int8_t stag) {
    int sock, result;
    u_int16_t packet_size = sizeof(udp_header) + sizeof(rmcp_header) +
sizeof(asf_header) + sizeof(asf_pong);
    u_int8_t datagram[36];
    udp_header *udp = (udp_header*)datagram;
    rmcp_header *rmcp;
    asf_header *asf;
    asf_pong *pong;
    struct sockaddr_in sin;
    u_int32_t src,dst;

    /* Init */
    result = 0;

    /* Set destiantion IP address to a sockaddr_in struct */
    sin.sin_family = AF_INET;
    sin.sin_port = htons(dport);
    sin.sin_addr.s_addr = ip_dst.s_addr;

    /* This is used to compute the packet checksum */
    src = ip_src.s_addr;
    dst = ip_dst.s_addr;

    pmesg(10, "Source IP: %s\n", inet_ntoa(ip_src));
    pmesg(10, "Dest. IP: %s\n", inet_ntoa(ip_dst));

    /* Set buffer data to 0 */
    memset(datagram, 0, 36);

    /* UDP header */
    udp->source = htons(623);
    udp->dest = dport;
    udp->len = htons(packet_size);
    pmesg(10, "Source port: %d\n", ntohs(udp->source));
    pmesg(10, "Dest. port: %d\n", ntohs(udp->dest));
    pmesg(10, "Length: %d\n", ntohs(udp->len));

    /* RMCP header */
    rmcp = (rmcp_header*)(datagram + sizeof(udp_header));
    rmcp->rh_version = RMCP_VERSION;
    rmcp->rh_reserved = 0x00;
    rmcp->rh_seq = RMCP_SEQUENCE_NOACK;
    rmcp->rh_class = RMCP_CLASS_ASF;

    pmesg(10, "Version: %#x\n", rmcp->rh_version);
    pmesg(10, "Sequence: %#x\n", rmcp->rh_seq);
    pmesg(10, "Class: %#x\n", rmcp->rh_class);

    /* ASF header */
    asf = (asf_header*)(datagram + sizeof(udp_header) +
sizeof(rmcp_header));
    asf->asf_iana = htonl(ASF_IANA_NUMBER);
    asf->asf_type = ASF_TYPE_PONG;
    asf->asf_tag = stag;
    asf->asf_reserved = 0x00;
    asf->asf_length = 0x10;

    pmesg(10, "IANA: %#x\n", asf->asf_iana);
    pmesg(10, "Type: %#x\n", asf->asf_type);
    pmesg(10, "Tag: %#x\n", asf->asf_tag);

    /* Pong data payload */
    pong = (asf_pong*)(datagram + sizeof(udp_header) +
sizeof(rmcp_header) + sizeof(asf_header));
    pong->iana = htonl(ASF_IANA_NUMBER);
    pong->oem = 0x00000000;
    pong->sup_entities = 0x81;
    pong->sup_interact = 0x00;

    pmesg(10, "IANA: %#x\n", pong->iana);
    pmesg(10, "OEM: %#x\n", pong->oem);
    pmesg(10, "Sup.Ent.: %#x\n", pong->sup_entities);
    pmesg(10, "Sup.Int.: %#x\n", pong->sup_interact);

    /* useless... we do a memset at the beginning
    for(i = 0;i < 6;i++) {
        pong->reserved[i] = 0x00;
    }
     */

    /* UDP checksum */
    udp->check = 0;
    udp->check = udp_checksum((unsigned short *)(datagram +
sizeof(udp_header)), udp->len, src, dst);

    pmesg(10, "Checksum: %#x\n", udp->check);

    /* Open socket */
    sock = socket(PF_INET, SOCK_RAW, IPPROTO_UDP);

    /* Send packet */
    result = sendto(sock, datagram, 36, 0, (struct sockaddr *) &sin,
sizeof (sin));
    if(result < 0) {
        perror("Error sending pong\n");
    } else {
        pmesg(10, "Packet sent\n");
    }

    /* close the socket */
    close(sock);

    return;
}

--
Thomas Favre-Bulle



reply via email to

[Prev in Thread] Current Thread [Next in Thread]