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: 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

reply via email to

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