[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Freeipmi-users] rmcpping and simulated pong replies
From: |
Al Chu |
Subject: |
Re: [Freeipmi-users] rmcpping and simulated pong replies |
Date: |
Fri, 04 Jun 2010 10:18:21 -0700 |
Hi Thomas,
It appears you're building the UDP header into your packet responses.
You don't appear to be doing raw sockets, so the UDP header is
unnecessary and likely making the packet invalid.
I made the attached mini-server to test rmcpping against, and this
worked. Note that I used a non-ipmi port for testing (quickly
recompiled rmcpping to use the non-default port).
Al
On Fri, 2010-06-04 at 01:16 -0700, Thomas Favre-Bulle wrote:
> 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
>
>
--
Albert Chu
address@hidden
Computer Scientist
High Performance Systems Division
Lawrence Livermore National Laboratory