Hi everybody,

I'd like to provide two patches for review and integration. The patches are in the attached.

lan-bridging.patch fixes:
- a possible crash during double-bridging over LAN
- potential mess with bridging multiple concurrent requests over LAN
- erroneous handling of the Send Message command embedded in the ipmitool's raw command-line option.

sdr-read-fix.patch fixes a crash when dumping SDRs in a file and there's an error getting an SDR. Also, algorithm of finding an optimal packet size is improved.

Regards,
Dmitry

Index: include/ipmitool/ipmi.h
===================================================================
RCS file: /cvsroot/ipmitool/ipmitool/include/ipmitool/ipmi.h,v
retrieving revision 1.31
diff -p -u -r1.31 ipmi.h
--- include/ipmitool/ipmi.h     8 Jan 2009 21:21:22 -0000       1.31
+++ include/ipmitool/ipmi.h     23 Jan 2009 13:18:26 -0000
@@ -145,6 +145,7 @@ struct ipmi_rq_entry {
        uint8_t rq_seq;
        uint8_t *msg_data;
        int msg_len;
+       int bridging_level;
        struct ipmi_rq_entry *next;
 };
 
Index: src/plugins/lan/lan.c
===================================================================
RCS file: /cvsroot/ipmitool/ipmitool/src/plugins/lan/lan.c,v
retrieving revision 1.63
diff -p -u -r1.63 lan.c
--- src/plugins/lan/lan.c       9 Jan 2009 21:55:47 -0000       1.63
+++ src/plugins/lan/lan.c       23 Jan 2009 13:18:27 -0000
@@ -572,44 +572,36 @@ ipmi_lan_poll_recv(struct ipmi_intf * in
                        if (entry) {
                                lprintf(LOG_DEBUG+2, "IPMI Request Match 
found");
                                if ((intf->target_addr != our_address) && 
bridge_possible) {
-                                       if ((rsp->data_len) &&
+                                       if ((rsp->data_len) && 
(rsp->payload.ipmi_response.netfn == 7) &&
                                            (rsp->payload.ipmi_response.cmd != 
0x34)) {
-                                               printbuf(&rsp->data[x], 
rsp->data_len-x,
-                                                        "bridge command 
response");
+                                               if (verbose > 2)
+                                                       printbuf(&rsp->data[x], 
rsp->data_len-x,
+                                                                "bridge 
command response");
                                        }
                                        /* bridged command: lose extra header */
-                                       if (rsp->payload.ipmi_response.netfn == 
7 &&
-                                               rsp->payload.ipmi_response.cmd 
== 0x34) {
+                                       if (entry->bridging_level &&
+                                           rsp->payload.ipmi_response.netfn == 
7 &&
+                                           rsp->payload.ipmi_response.cmd == 
0x34) {
+                                               entry->bridging_level--;
                                                if (rsp->data_len - x - 1 == 0) 
{
                                                        rsp = !rsp->ccode ? 
ipmi_lan_recv_packet(intf) : NULL;
-                                                       if (rsp && !rsp->ccode 
&&
-                                                               
intf->transit_addr != intf->my_addr &&
-                                                               
intf->transit_addr != 0 &&
-                                                           (rsp->data[x - 3] 
>> 2) == entry->rq_seq) {
-                                                               /* double 
bridging: remove the Send Message prologue */
-                                                               
memmove(rsp->data + x - 7, rsp->data + x,
-                                                                       
rsp->data_len - x - 1);
-                                                               rsp->data[x - 
8] -= 8;
-                                                               rsp->data_len 
-= 8;
-                                                               entry->rq_seq = 
rsp->data[x - 3] >> 2;
-                                                       }
-                                                       entry->req.msg.cmd = 
entry->req.msg.target_cmd;
+                                                       if 
(!entry->bridging_level)
+                                                               
entry->req.msg.cmd = entry->req.msg.target_cmd;
                                                        if (rsp == NULL) {
-                                                           
ipmi_req_remove_entry(entry->rq_seq, entry->req.msg.cmd);
+                                                               
ipmi_req_remove_entry(entry->rq_seq, entry->req.msg.cmd);
                                                        }
                                                        continue;
                                                } else {
-                                                   /* The bridged answer data 
are inside the incoming packet */
-                                                   char bridge_cnt =
-                                                       1 + (intf->transit_addr 
!= intf->my_addr && intf->transit_addr != 0);
-                                                   memmove(rsp->data + x - 7,
-                                                           rsp->data + x + 7 * 
(bridge_cnt - 1), 
-                                                           rsp->data_len - (x 
+ 7 * (bridge_cnt - 1)));
-                                                   rsp->data[x - 8] -= 8 * 
bridge_cnt;
-                                                   rsp->data_len -= 8 * 
bridge_cnt;
-                                                   entry->rq_seq = rsp->data[x 
- 3] >> 2;
-                                                   entry->req.msg.cmd = 
entry->req.msg.target_cmd;
-                                                   continue;
+                                                       /* The bridged answer 
data are inside the incoming packet */
+                                                       memmove(rsp->data + x - 
7,
+                                                               rsp->data + x, 
+                                                               rsp->data_len - 
x - 1);
+                                                       rsp->data[x - 8] -= 8;
+                                                       rsp->data_len -= 8;
+                                                       entry->rq_seq = 
rsp->data[x - 3] >> 2;
+                                                       if 
(!entry->bridging_level)
+                                                               
entry->req.msg.cmd = entry->req.msg.target_cmd;
+                                                       continue;
                                                }
                                        } else {
                                                //x += 
sizeof(rsp->payload.ipmi_response);
@@ -688,7 +680,6 @@ ipmi_lan_build_cmd(struct ipmi_intf * in
        struct ipmi_session * s = intf->session;
        static int curr_seq = 0;
        uint8_t our_address = intf->my_addr;
-       uint8_t bridge_request = 0;
 
        if (our_address == 0)
                our_address = IPMI_BMC_SLAVE_ADDR;
@@ -735,11 +726,12 @@ ipmi_lan_build_cmd(struct ipmi_intf * in
 
        /* message length */
        if ((intf->target_addr == our_address) || !bridge_possible) {
+               entry->bridging_level = 0;
                msg[len++] = req->msg.data_len + 7;
                cs = mp = len;
        } else {
                /* bridged request: encapsulate w/in Send Message */
-               bridge_request = 1;
+               entry->bridging_level = 1;
                msg[len++] = req->msg.data_len + 15 +
                  (intf->transit_addr != intf->my_addr && intf->transit_addr != 
0 ? 8 : 0);
                cs = mp = len;
@@ -757,6 +749,7 @@ ipmi_lan_build_cmd(struct ipmi_intf * in
                if (intf->transit_addr == intf->my_addr || intf->transit_addr 
== 0) {
                        msg[len++] = (0x40|intf->target_channel); /* Track 
request*/
                } else {
+                       entry->bridging_level++;
                                msg[len++] = (0x40|intf->transit_channel); /* 
Track request*/
                        cs = len;
                        msg[len++] = intf->transit_addr;
@@ -779,7 +772,7 @@ ipmi_lan_build_cmd(struct ipmi_intf * in
        msg[len++] = ipmi_csum(msg+cs, tmp);
        cs = len;
 
-       if (!bridge_request)
+       if (!entry->bridging_level)
                msg[len++] = IPMI_REMOTE_SWID;
        else  /* Bridged message */
                msg[len++] = intf->my_addr;
@@ -813,7 +806,7 @@ ipmi_lan_build_cmd(struct ipmi_intf * in
        msg[len++] = ipmi_csum(msg+cs, tmp);
 
        /* bridged request: 2nd checksum */
-       if (bridge_request) {
+       if (entry->bridging_level) {
                if (intf->transit_addr != intf->my_addr && intf->transit_addr 
!= 0) {
                        tmp = len - cs3;
                        msg[len++] = ipmi_csum(msg+cs3, tmp);
Index: lib/ipmi_sdr.c
===================================================================
RCS file: /cvsroot/ipmitool/ipmitool/lib/ipmi_sdr.c,v
retrieving revision 1.85
diff -p -u -r1.85 ipmi_sdr.c
--- lib/ipmi_sdr.c      9 Jan 2009 22:52:11 -0000       1.85
+++ lib/ipmi_sdr.c      23 Jan 2009 13:49:03 -0000
@@ -2679,14 +2679,21 @@ ipmi_sdr_get_record(struct ipmi_intf * i
 
                rsp = intf->sendrecv(intf, &req);
                if (rsp == NULL) {
+                   sdr_max_read_len = sdr_rq.length - 1;
+                   if (sdr_max_read_len > 0) {
+                       /* no response may happen if requests are bridged
+                          and too many bytes are requested */
+                       continue;
+                   } else {
                        free(data);
                        return NULL;
+                   }
                }
 
                switch (rsp->ccode) {
                case 0xca:
                        /* read too many bytes at once */
-                       sdr_max_read_len = (sdr_max_read_len >> 1) - 1;
+                       sdr_max_read_len = sdr_rq.length - 1;
                        continue;
                case 0xc5:
                        /* lost reservation */
@@ -3966,6 +3973,11 @@ ipmi_sdr_dump_bin(struct ipmi_intf *intf
                sdrr->length = header->length;
                sdrr->raw = ipmi_sdr_get_record(intf, header, itr);
 
+               if (sdrr->raw == NULL) {
+                   lprintf(LOG_ERR, "ipmitool: cannot obtain SDR record %04x", 
header->id);
+                   return -1;
+               }
+
                if (sdr_list_head == NULL)
                        sdr_list_head = sdrr;
                else
------------------------------------------------------------------------------
This SF.net email is sponsored by:
SourcForge Community
SourceForge wants to tell your story.
http://p.sf.net/sfu/sf-spreadtheword
_______________________________________________
Ipmitool-devel mailing list
Ipmitool-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ipmitool-devel

Reply via email to