The function imap_fetchbody() seems uncapable of getting subordinate parts of a message/rfc822-part. I had problems with getting an attachment that was forwarded in such a part, because the object given by imap_fetchstructure() would assume that the part was represented by the string "2.1.2.1.2". 
So I wrote this set of functions which parses the raw message-body and creates an array with the struture corresponding to the structure given by imap_fetchstructure(). The function mail_fetchpart() (see below) will work on the array and return even those parts that I could not get with imap_fetchbody().
Example usage of this function: mail_fetchpart($mbox, 2, "2.1.2.1.2");
Note: If the message does not contain multiple pars, the body of the message can be accessed by the part-string "1".
I have more functions for parsing and decoding messages, just email me.
    // get the body of a part of a message according to the
    // string in $part
    function mail_fetchpart($mbox, $msgNo, $part) {
        $parts = mail_fetchparts($mbox, $msgNo);
        
        $partNos = explode(".", $part);
        
        $currentPart = $parts;
        while(list ($key, $val) = each($partNos)) {
            $currentPart = $currentPart[$val];
        }
        
        if ($currentPart != "") return $currentPart;
          else return false;
    }
    // splits a message given in the body if it is
    // a mulitpart mime message and returns the parts,
    // if no parts are found, returns false
    function mail_mimesplit($header, $body) {
        $parts = array();
        
        $PN_EREG_BOUNDARY = "Content-Type:(.*)boundary=\"([^\"]+)\"";
        if (eregi ($PN_EREG_BOUNDARY, $header, $regs)) {
            $boundary = $regs[2];
            $delimiterReg = "([^\r\n]*)$boundary([^\r\n]*)";
            if (eregi ($delimiterReg, $body, $results)) {
                $delimiter = $results[0];
                $parts = explode($delimiter, $body);
                $parts = array_slice ($parts, 1, -1);
            }
            
            return $parts;
        } else {
            return false;
        }    
        
        
    }
    // returns an array with all parts that are
    // subparts of the given part
    // if no subparts are found, return the body of 
    // the current part
    function mail_mimesub($part) {
        $i = 1;
        $headDelimiter = "\r\n\r\n";
        $delLength = strlen($headDelimiter);
    
        // get head & body of the current part
        $endOfHead = strpos( $part, $headDelimiter);
        $head = substr($part, 0, $endOfHead);
        $body = substr($part, $endOfHead + $delLength, strlen($part));
        
        // check whether it is a message according to rfc822
        if (stristr($head, "Content-Type: message/rfc822")) {
            $part = substr($part, $endOfHead + $delLength, strlen($part));
            $returnParts[1] = mail_mimesub($part);
            return $returnParts;
        // if no message, get subparts and call function recursively
        } elseif ($subParts = mail_mimesplit($head, $body)) {
            // got more subparts
            while (list ($key, $val) = each($subParts)) {
                $returnParts[$i] = mail_mimesub($val);
                $i++;
            }            
            return $returnParts;
        } else {
            return $body;
        }
    }
    // get an array with the bodies all parts of an email
    // the structure of the array corresponds to the 
    // structure that is available with imap_fetchstructure
    function mail_fetchparts($mbox, $msgNo) {
        $parts = array();
        $header = imap_fetchheader($mbox,$msgNo);
        $body = imap_body($mbox,$msgNo, FT_INTERNAL);
        
        $i = 1;
        
        if ($newParts = mail_mimesplit($header, $body)) {
            while (list ($key, $val) = each($newParts)) {
                $parts[$i] = mail_mimesub($val);
                $i++;                
            }
        } else {
            $parts[$i] = $body;
        }
        return $parts;
        
    }