[Top][All Lists]
[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