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
[email protected]
Computer Scientist
High Performance Systems Division
Lawrence Livermore National Laboratory
_______________________________________________
Freeipmi-users mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/freeipmi-users

Reply via email to