#include #include #include #include #include #include #include #include #include #include #include #define OFWPATH "/dev/openfirm" #define BUFSIZE 16384 static void usage(void); void walkdev(int fd, char *name); void walknode(int fd, int nodeid, int level); void printprop(struct ofiocdesc *node, int level); int main(int argc, char *argv[]) { int ofwfd; char startnode[256]; int ch; extern char *optarg; extern int optind; strcpy(startnode, "/"); while((ch = getopt(argc, argv, "n:")) != -1) switch (ch) { case 'n': strcpy(startnode, optarg); break; case '?': default: usage(); } argc += optind; argv -= optind; ofwfd = open(OFWPATH, O_RDONLY, 0); if (ofwfd == -1) err(EXIT_FAILURE, "Couldn't open %s", OFWPATH); walkdev(ofwfd, startnode); close(ofwfd); return 0; } void walkdev(int fd, char *name) { struct ofiocdesc node; int ret; node.of_nodeid = 0; node.of_name = name; node.of_namelen = strlen(name); ret = ioctl(fd, OFIOCFINDDEVICE, &node); if (ret == -1) err(EXIT_FAILURE, "Couldn't find start node %s", name); walknode(fd, node.of_nodeid, 0); } void walknode(int fd, int nodeid, int level) { struct ofiocdesc ofc; char buf1[BUFSIZE], buf2[BUFSIZE]; char *swap; int childnodeid; int ret; ofc.of_namelen = BUFSIZE; ofc.of_name = buf1; ofc.of_buf = buf2; while (nodeid != 0) { /* Get information about the node */ ofc.of_nodeid = nodeid; strcpy(ofc.of_name, "name"); ofc.of_namelen = strlen(ofc.of_name); ofc.of_buflen = BUFSIZE; ret = ioctl(fd, OFIOCGET, &ofc); if (ret == -1) err(EXIT_FAILURE, "Couldn't get name of %x", nodeid); printf("%*sNode %s\n", level, "", ofc.of_buf); /* Get all the properties */ ofc.of_buflen = BUFSIZE; while (ioctl(fd, OFIOCNEXTPROP, &ofc) == 0) { ofc.of_buf[ofc.of_buflen] = '\0'; printf("%*s Property %-30s\n", level, "", ofc.of_buf); swap = ofc.of_name; ofc.of_name = ofc.of_buf; ofc.of_namelen = ofc.of_buflen; ofc.of_buf = swap; ofc.of_buflen = BUFSIZE; ret = ioctl(fd, OFIOCGET, &ofc); if (ret == -1) warn("Couldn't get value " "of property %s", ofc.of_name); else printprop(&ofc, level); ofc.of_buflen = BUFSIZE; } if (errno != ENOENT) err(EXIT_FAILURE, "Error getting next property"); /* Find the child pointer and walk it */ childnodeid = nodeid; ret = ioctl(fd, OFIOCGETCHILD, &childnodeid); if (ret == -1) err(EXIT_FAILURE, "Couldn't get child of %x", nodeid); if (childnodeid != 0) walknode(fd, childnodeid, level + 2); /* Find the next sibling */ ret = ioctl(fd, OFIOCGETNEXT, &nodeid); if (ret == -1) err(EXIT_FAILURE, "Couldn't get sibling of %x", nodeid); } } void printprop(struct ofiocdesc *node, int level) { int i, j; char strbuf[17]; strbuf[16] = '\0'; for (i = 0; i < node->of_buflen; i += 16) { printf("%*s", level + 2, ""); for (j = 0; j < 16; j++) { if ((j % 4) == 0) printf(" "); if (i + j < node->of_buflen) { printf("%02x", node->of_buf[i+j]); strbuf[j] = isprint(node->of_buf[i+j]) ? node->of_buf[i+j] : '.'; } else { printf(" "); strbuf[j] = ' '; } } printf(" %s\n", strbuf); } } static void usage(void) { fprintf(stderr, "usage: walkopenfirm [-n startnode]\n"); exit(1); }