infiniband-diags: initial port of linux ib diags
[mirror/winof/.git] / tools / infiniband_diags / src / saquery.c
1 /*\r
2  * Copyright (c) 2006,2007 The Regents of the University of California.\r
3  * Copyright (c) 2004-2008 Voltaire, Inc. All rights reserved.\r
4  * Copyright (c) 2002-2005 Mellanox Technologies LTD. All rights reserved.\r
5  * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.\r
6  *\r
7  * Produced at Lawrence Livermore National Laboratory.\r
8  * Written by Ira Weiny <weiny2@llnl.gov>.\r
9  *\r
10  * This software is available to you under a choice of one of two\r
11  * licenses.  You may choose to be licensed under the terms of the GNU\r
12  * General Public License (GPL) Version 2, available from the file\r
13  * COPYING in the main directory of this source tree, or the\r
14  * OpenIB.org BSD license below:\r
15  *\r
16  *     Redistribution and use in source and binary forms, with or\r
17  *     without modification, are permitted provided that the following\r
18  *     conditions are met:\r
19  *\r
20  *      - Redistributions of source code must retain the above\r
21  *        copyright notice, this list of conditions and the following\r
22  *        disclaimer.\r
23  *\r
24  *      - Redistributions in binary form must reproduce the above\r
25  *        copyright notice, this list of conditions and the following\r
26  *        disclaimer in the documentation and/or other materials\r
27  *        provided with the distribution.\r
28  *\r
29  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
30  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
31  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
32  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
33  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
34  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
35  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
36  * SOFTWARE.\r
37  *\r
38  */\r
39 \r
40 #if defined(_WIN32) || defined(_WIN64)\r
41 \r
42 #include <windows.h>\r
43 #include <winsock2.h>\r
44 #include <ws2tcpip.h> \r
45 #include <complib/cl_debug.h>\r
46 #include <opensm/osm_log.h>\r
47 #include <vendor/osm_vendor_api.h>\r
48 #include <vendor/osm_vendor_sa_api.h>\r
49 #include <opensm/osm_mad_pool.h>\r
50 \r
51 #else\r
52 \r
53 #include <unistd.h>\r
54 #include <stdio.h>\r
55 #include <sys/types.h>\r
56 #include <sys/socket.h>\r
57 #include <arpa/inet.h>\r
58 #include <assert.h>\r
59 #include <ctype.h>\r
60 #include <string.h>\r
61 \r
62 #define _GNU_SOURCE\r
63 #include <getopt.h>\r
64 #include <infiniband/opensm/osm_log.h>\r
65 #include <infiniband/vendor/osm_vendor_api.h>\r
66 #include <infiniband/vendor/osm_vendor_sa_api.h>\r
67 #include <infiniband/opensm/osm_mad_pool.h>\r
68 #include <infiniband/complib/cl_debug.h>\r
69 #include <infiniband/complib/cl_nodenamemap.h>\r
70 \r
71 #endif\r
72 \r
73 #include "ibdiag_common.h"\r
74 \r
75 struct query_cmd {\r
76         const char *name, *alias;\r
77         ib_net16_t query_type;\r
78         const char *usage;\r
79         int (*handler)(const struct query_cmd *q, osm_bind_handle_t bind_handle,\r
80                        int argc, char *argv[]);\r
81 };\r
82 \r
83 char *argv0 = "saquery";\r
84 \r
85 static char *node_name_map_file = NULL;\r
86 static nn_map_t *node_name_map = NULL;\r
87 static ib_net64_t smkey = OSM_DEFAULT_SA_KEY;\r
88 \r
89 /**\r
90  * Declare some globals because I don't want this to be too complex.\r
91  */\r
92 #define MAX_PORTS (8)\r
93 #define DEFAULT_SA_TIMEOUT_MS (1000)\r
94 osmv_query_res_t   result;\r
95 osm_log_t          log_osm;\r
96 osm_mad_pool_t     mad_pool;\r
97 osm_vendor_t      *vendor = NULL;\r
98 int                osm_debug = 0;\r
99 uint32_t           sa_timeout_ms = DEFAULT_SA_TIMEOUT_MS;\r
100 char              *sa_hca_name = NULL;\r
101 uint32_t           sa_port_num = 0;\r
102 \r
103 enum {\r
104         ALL,\r
105         LID_ONLY,\r
106         UNIQUE_LID_ONLY,\r
107         GUID_ONLY,\r
108         ALL_DESC,\r
109         NAME_OF_LID,\r
110         NAME_OF_GUID,\r
111 } node_print_desc = ALL;\r
112 \r
113 char              *requested_name = NULL;\r
114 ib_net16_t         requested_lid = 0;\r
115 int                requested_lid_flag = 0;\r
116 ib_net64_t         requested_guid = 0;\r
117 int                requested_guid_flag = 0;\r
118 \r
119 /**\r
120  * Call back for the various record requests.\r
121  */\r
122 static void\r
123 query_res_cb(osmv_query_res_t *res)\r
124 {\r
125         result = *res;\r
126 }\r
127 \r
128 static void\r
129 print_node_desc(ib_node_record_t *node_record)\r
130 {\r
131         ib_node_info_t *p_ni = &(node_record->node_info);\r
132         ib_node_desc_t *p_nd = &(node_record->node_desc);\r
133 \r
134         if (p_ni->node_type == IB_NODE_TYPE_CA)\r
135         {\r
136                 printf("%6d  \"%s\"\n",\r
137                        cl_ntoh16(node_record->lid),\r
138                        clean_nodedesc((char *)p_nd->description));\r
139         }\r
140 }\r
141 \r
142 static void\r
143 print_node_record(ib_node_record_t *node_record)\r
144 {\r
145         ib_node_info_t *p_ni = NULL;\r
146         ib_node_desc_t *p_nd = NULL;\r
147         char *name;\r
148 \r
149         p_ni = &(node_record->node_info);\r
150         p_nd = &(node_record->node_desc);\r
151 \r
152         switch (node_print_desc) {\r
153         case LID_ONLY:\r
154         case UNIQUE_LID_ONLY:\r
155                 printf("%d\n", cl_ntoh16(node_record->lid));\r
156                 return;\r
157         case GUID_ONLY:\r
158                 printf("0x%016" PRIx64 "\n", cl_ntoh64(p_ni->port_guid));\r
159                 return;\r
160         case NAME_OF_LID:\r
161         case NAME_OF_GUID:\r
162                 name = remap_node_name(node_name_map,\r
163                                           cl_ntoh64(p_ni->node_guid),\r
164                                           (char *)p_nd->description);\r
165                 printf("%s\n", name);\r
166                 free(name);\r
167                 return;\r
168         case ALL:\r
169         default:\r
170                 break;\r
171         }\r
172 \r
173         printf("NodeRecord dump:\n"\r
174                "\t\tlid.....................0x%X\n"\r
175                "\t\treserved................0x%X\n"\r
176                "\t\tbase_version............0x%X\n"\r
177                "\t\tclass_version...........0x%X\n"\r
178                "\t\tnode_type...............%s\n"\r
179                "\t\tnum_ports...............0x%X\n"\r
180                "\t\tsys_guid................0x%016" PRIx64 "\n"\r
181                "\t\tnode_guid...............0x%016" PRIx64 "\n"\r
182                "\t\tport_guid...............0x%016" PRIx64 "\n"\r
183                "\t\tpartition_cap...........0x%X\n"\r
184                "\t\tdevice_id...............0x%X\n"\r
185                "\t\trevision................0x%X\n"\r
186                "\t\tport_num................0x%X\n"\r
187                "\t\tvendor_id...............0x%X\n"\r
188                "\t\tNodeDescription.........%s\n"\r
189                "",\r
190                cl_ntoh16(node_record->lid),\r
191                cl_ntoh16(node_record->resv),\r
192                p_ni->base_version,\r
193                p_ni->class_version,\r
194                ib_get_node_type_str( p_ni->node_type ),\r
195                p_ni->num_ports,\r
196                cl_ntoh64( p_ni->sys_guid ),\r
197                cl_ntoh64( p_ni->node_guid ),\r
198                cl_ntoh64( p_ni->port_guid ),\r
199                cl_ntoh16( p_ni->partition_cap ),\r
200                cl_ntoh16( p_ni->device_id ),\r
201                cl_ntoh32( p_ni->revision ),\r
202                ib_node_info_get_local_port_num( p_ni ),\r
203                cl_ntoh32( ib_node_info_get_vendor_id( p_ni )),\r
204                clean_nodedesc((char *)node_record->node_desc.description)\r
205                );\r
206 }\r
207 \r
208 static void dump_path_record(void *data)\r
209 {\r
210         char gid_str[INET6_ADDRSTRLEN];\r
211         char gid_str2[INET6_ADDRSTRLEN];\r
212         ib_path_rec_t *p_pr = data;\r
213         printf("PathRecord dump:\n"\r
214                "\t\tservice_id..............0x%016" PRIx64 "\n"\r
215                "\t\tdgid....................%s\n"\r
216                "\t\tsgid....................%s\n"\r
217                "\t\tdlid....................0x%X\n"\r
218                "\t\tslid....................0x%X\n"\r
219                "\t\thop_flow_raw............0x%X\n"\r
220                "\t\ttclass..................0x%X\n"\r
221                "\t\tnum_path_revers.........0x%X\n"\r
222                "\t\tpkey....................0x%X\n"\r
223                "\t\tqos_class...............0x%X\n"\r
224                "\t\tsl......................0x%X\n"\r
225                "\t\tmtu.....................0x%X\n"\r
226                "\t\trate....................0x%X\n"\r
227                "\t\tpkt_life................0x%X\n"\r
228                "\t\tpreference..............0x%X\n"\r
229                "\t\tresv2...................0x%X\n"\r
230                "\t\tresv3...................0x%X\n"\r
231                "",\r
232                cl_ntoh64( p_pr->service_id ),\r
233                inet_ntop(AF_INET6, p_pr->dgid.raw, gid_str, sizeof gid_str),\r
234                inet_ntop(AF_INET6, p_pr->sgid.raw, gid_str2, sizeof gid_str2),\r
235                cl_ntoh16( p_pr->dlid ),\r
236                cl_ntoh16( p_pr->slid ),\r
237                cl_ntoh32( p_pr->hop_flow_raw ),\r
238                p_pr->tclass,\r
239                p_pr->num_path,\r
240                cl_ntoh16( p_pr->pkey ),\r
241                ib_path_rec_qos_class( p_pr ),\r
242                ib_path_rec_sl( p_pr ),\r
243                p_pr->mtu,\r
244                p_pr->rate,\r
245                p_pr->pkt_life,\r
246                p_pr->preference,\r
247                *(uint32_t*)&p_pr->resv2,\r
248                *((uint16_t*)&p_pr->resv2 + 2)\r
249                );\r
250 }\r
251 \r
252 static void dump_class_port_info(void *data)\r
253 {\r
254         char   gid_str[INET6_ADDRSTRLEN];\r
255         char   gid_str2[INET6_ADDRSTRLEN];\r
256         ib_class_port_info_t *class_port_info = data;\r
257 \r
258         printf("SA ClassPortInfo:\n"\r
259                "\t\tBase version.............%d\n"\r
260                "\t\tClass version............%d\n"\r
261                "\t\tCapability mask..........0x%04X\n"\r
262                "\t\tCapability mask 2........0x%08X\n"\r
263                "\t\tResponse time value......0x%02X\n"\r
264                "\t\tRedirect GID.............%s\n"\r
265                "\t\tRedirect TC/SL/FL........0x%08X\n"\r
266                "\t\tRedirect LID.............0x%04X\n"\r
267                "\t\tRedirect PKey............0x%04X\n"\r
268                "\t\tRedirect QP..............0x%08X\n"\r
269                "\t\tRedirect QKey............0x%08X\n"\r
270                "\t\tTrap GID.................%s\n"\r
271                "\t\tTrap TC/SL/FL............0x%08X\n"\r
272                "\t\tTrap LID.................0x%04X\n"\r
273                "\t\tTrap PKey................0x%04X\n"\r
274                "\t\tTrap HL/QP...............0x%08X\n"\r
275                "\t\tTrap QKey................0x%08X\n"\r
276                "",\r
277                class_port_info->base_ver,\r
278                class_port_info->class_ver,\r
279                cl_ntoh16(class_port_info->cap_mask),\r
280                ib_class_cap_mask2(class_port_info),\r
281                ib_class_resp_time_val(class_port_info),\r
282                inet_ntop(AF_INET6, &(class_port_info->redir_gid), gid_str,\r
283                         sizeof gid_str),\r
284                cl_ntoh32(class_port_info->redir_tc_sl_fl),\r
285                cl_ntoh16(class_port_info->redir_lid),\r
286                cl_ntoh16(class_port_info->redir_pkey),\r
287                cl_ntoh32(class_port_info->redir_qp),\r
288                cl_ntoh32(class_port_info->redir_qkey),\r
289                inet_ntop(AF_INET6, &(class_port_info->trap_gid), gid_str2,\r
290                         sizeof gid_str2),\r
291                cl_ntoh32(class_port_info->trap_tc_sl_fl),\r
292                cl_ntoh16(class_port_info->trap_lid),\r
293                cl_ntoh16(class_port_info->trap_pkey),\r
294                cl_ntoh32(class_port_info->trap_hop_qp),\r
295                cl_ntoh32(class_port_info->trap_qkey)\r
296               );\r
297 }\r
298 \r
299 static void dump_portinfo_record(void *data)\r
300 {\r
301         ib_portinfo_record_t *p_pir = data;\r
302         const ib_port_info_t * const p_pi = &p_pir->port_info;\r
303 \r
304         printf("PortInfoRecord dump:\n"\r
305                "\t\tEndPortLid..............0x%X\n"\r
306                "\t\tPortNum.................0x%X\n"\r
307                "\t\tbase_lid................0x%X\n"\r
308                "\t\tmaster_sm_base_lid......0x%X\n"\r
309                "\t\tcapability_mask.........0x%X\n"\r
310                "",\r
311                cl_ntoh16(p_pir->lid),\r
312                p_pir->port_num,\r
313                cl_ntoh16( p_pi->base_lid ),\r
314                cl_ntoh16( p_pi->master_sm_base_lid ),\r
315                cl_ntoh32( p_pi->capability_mask )\r
316                );\r
317 }\r
318 \r
319 static void dump_multicast_group_record(void *data)\r
320 {\r
321         char   gid_str[INET6_ADDRSTRLEN];\r
322         ib_member_rec_t *p_mcmr = data;\r
323         uint8_t sl;\r
324         ib_member_get_sl_flow_hop(p_mcmr->sl_flow_hop, &sl, NULL, NULL);\r
325         printf("MCMemberRecord group dump:\n"\r
326                "\t\tMGID....................%s\n"\r
327                "\t\tMlid....................0x%X\n"\r
328                "\t\tMtu.....................0x%X\n"\r
329                "\t\tpkey....................0x%X\n"\r
330                "\t\tRate....................0x%X\n"\r
331                "\t\tSL......................0x%X\n"\r
332                "",\r
333                inet_ntop(AF_INET6, p_mcmr->mgid.raw, gid_str, sizeof gid_str),\r
334                cl_ntoh16( p_mcmr->mlid ),\r
335                p_mcmr->mtu,\r
336                cl_ntoh16( p_mcmr->pkey ),\r
337                p_mcmr->rate,\r
338                sl\r
339                );\r
340 }\r
341 \r
342 static void dump_multicast_member_record(void *data)\r
343 {\r
344         char   gid_str[INET6_ADDRSTRLEN];\r
345         char   gid_str2[INET6_ADDRSTRLEN];\r
346         ib_member_rec_t *p_mcmr = data;\r
347         uint16_t mlid = cl_ntoh16( p_mcmr->mlid );\r
348         int      i = 0;\r
349         char *node_name = "<unknown>";\r
350 \r
351         /* go through the node records searching for a port guid which matches\r
352          * this port gid interface id.\r
353          * This gives us a node name to print, if available.\r
354          */\r
355         for (i = 0; i < result.result_cnt; i++) {\r
356                 ib_node_record_t *nr = osmv_get_query_node_rec(result.p_result_madw, i);\r
357                 if (nr->node_info.port_guid == p_mcmr->port_gid.unicast.interface_id) {\r
358                         node_name = clean_nodedesc((char *)nr->node_desc.description);\r
359                         break;\r
360                 }\r
361         }\r
362 \r
363         if (requested_name) {\r
364                 if (strtol(requested_name, NULL, 0) == mlid) {\r
365                         printf("\t\tPortGid.................%s (%s)\n",\r
366                                 inet_ntop(AF_INET6, p_mcmr->port_gid.raw,\r
367                                         gid_str, sizeof gid_str),\r
368                                node_name\r
369                               );\r
370                 }\r
371         } else {\r
372                 printf("MCMemberRecord member dump:\n"\r
373                        "\t\tMGID....................%s\n"\r
374                        "\t\tMlid....................0x%X\n"\r
375                        "\t\tPortGid.................%s\n"\r
376                        "\t\tScopeState..............0x%X\n"\r
377                        "\t\tProxyJoin...............0x%X\n"\r
378                        "\t\tNodeDescription.........%s\n"\r
379                        "",\r
380                        inet_ntop(AF_INET6, p_mcmr->mgid.raw, gid_str,\r
381                                 sizeof gid_str),\r
382                        cl_ntoh16( p_mcmr->mlid ),\r
383                        inet_ntop(AF_INET6, p_mcmr->port_gid.raw,\r
384                                 gid_str2, sizeof gid_str2),\r
385                        p_mcmr->scope_state,\r
386                        p_mcmr->proxy_join,\r
387                        node_name\r
388                       );\r
389         }\r
390 }\r
391 \r
392 static void dump_service_record(void *data)\r
393 {\r
394         char   gid_str[INET6_ADDRSTRLEN];\r
395         char buf_service_key[35];\r
396         char buf_service_name[65];\r
397         ib_service_record_t *p_sr = data;\r
398 \r
399         sprintf(buf_service_key,\r
400                 "0x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",\r
401                 p_sr->service_key[0],\r
402                 p_sr->service_key[1],\r
403                 p_sr->service_key[2],\r
404                 p_sr->service_key[3],\r
405                 p_sr->service_key[4],\r
406                 p_sr->service_key[5],\r
407                 p_sr->service_key[6],\r
408                 p_sr->service_key[7],\r
409                 p_sr->service_key[8],\r
410                 p_sr->service_key[9],\r
411                 p_sr->service_key[10],\r
412                 p_sr->service_key[11],\r
413                 p_sr->service_key[12],\r
414                 p_sr->service_key[13],\r
415                 p_sr->service_key[14],\r
416                 p_sr->service_key[15]);\r
417         strncpy(buf_service_name, (char *)p_sr->service_name, 64);\r
418         buf_service_name[64] = '\0';\r
419 \r
420         printf("ServiceRecord dump:\n"\r
421                "\t\tServiceID...............0x%016" PRIx64 "\n"\r
422                "\t\tServiceGID..............%s\n"\r
423                "\t\tServiceP_Key............0x%X\n"\r
424                "\t\tServiceLease............0x%X\n"\r
425                "\t\tServiceKey..............%s\n"\r
426                "\t\tServiceName.............%s\n"\r
427                "\t\tServiceData8.1..........0x%X\n"\r
428                "\t\tServiceData8.2..........0x%X\n"\r
429                "\t\tServiceData8.3..........0x%X\n"\r
430                "\t\tServiceData8.4..........0x%X\n"\r
431                "\t\tServiceData8.5..........0x%X\n"\r
432                "\t\tServiceData8.6..........0x%X\n"\r
433                "\t\tServiceData8.7..........0x%X\n"\r
434                "\t\tServiceData8.8..........0x%X\n"\r
435                "\t\tServiceData8.9..........0x%X\n"\r
436                "\t\tServiceData8.10.........0x%X\n"\r
437                "\t\tServiceData8.11.........0x%X\n"\r
438                "\t\tServiceData8.12.........0x%X\n"\r
439                "\t\tServiceData8.13.........0x%X\n"\r
440                "\t\tServiceData8.14.........0x%X\n"\r
441                "\t\tServiceData8.15.........0x%X\n"\r
442                "\t\tServiceData8.16.........0x%X\n"\r
443                "\t\tServiceData16.1.........0x%X\n"\r
444                "\t\tServiceData16.2.........0x%X\n"\r
445                "\t\tServiceData16.3.........0x%X\n"\r
446                "\t\tServiceData16.4.........0x%X\n"\r
447                "\t\tServiceData16.5.........0x%X\n"\r
448                "\t\tServiceData16.6.........0x%X\n"\r
449                "\t\tServiceData16.7.........0x%X\n"\r
450                "\t\tServiceData16.8.........0x%X\n"\r
451                "\t\tServiceData32.1.........0x%X\n"\r
452                "\t\tServiceData32.2.........0x%X\n"\r
453                "\t\tServiceData32.3.........0x%X\n"\r
454                "\t\tServiceData32.4.........0x%X\n"\r
455                "\t\tServiceData64.1.........0x%016" PRIx64 "\n"\r
456                "\t\tServiceData64.2.........0x%016" PRIx64 "\n"\r
457                "",\r
458                cl_ntoh64( p_sr->service_id ),\r
459                inet_ntop(AF_INET6, p_sr->service_gid.raw, gid_str,\r
460                         sizeof gid_str),\r
461                cl_ntoh16( p_sr->service_pkey ),\r
462                cl_ntoh32( p_sr->service_lease ),\r
463                buf_service_key,\r
464                buf_service_name,\r
465                p_sr->service_data8[0], p_sr->service_data8[1],\r
466                p_sr->service_data8[2], p_sr->service_data8[3],\r
467                p_sr->service_data8[4], p_sr->service_data8[5],\r
468                p_sr->service_data8[6], p_sr->service_data8[7],\r
469                p_sr->service_data8[8], p_sr->service_data8[9],\r
470                p_sr->service_data8[10], p_sr->service_data8[11],\r
471                p_sr->service_data8[12], p_sr->service_data8[13],\r
472                p_sr->service_data8[14], p_sr->service_data8[15],\r
473                cl_ntoh16( p_sr->service_data16[0] ),\r
474                cl_ntoh16( p_sr->service_data16[1] ),\r
475                cl_ntoh16( p_sr->service_data16[2] ),\r
476                cl_ntoh16( p_sr->service_data16[3] ),\r
477                cl_ntoh16( p_sr->service_data16[4] ),\r
478                cl_ntoh16( p_sr->service_data16[5] ),\r
479                cl_ntoh16( p_sr->service_data16[6] ),\r
480                cl_ntoh16( p_sr->service_data16[7] ),\r
481                cl_ntoh32( p_sr->service_data32[0] ),\r
482                cl_ntoh32( p_sr->service_data32[1] ),\r
483                cl_ntoh32( p_sr->service_data32[2] ),\r
484                cl_ntoh32( p_sr->service_data32[3] ),\r
485                cl_ntoh64( p_sr->service_data64[0] ),\r
486                cl_ntoh64( p_sr->service_data64[1] )\r
487               );\r
488 }\r
489 \r
490 static void dump_inform_info_record(void *data)\r
491 {\r
492         char   gid_str[INET6_ADDRSTRLEN];\r
493         char   gid_str2[INET6_ADDRSTRLEN];\r
494         ib_inform_info_record_t *p_iir = data;\r
495         uint32_t qpn;\r
496         uint8_t  resp_time_val;\r
497 \r
498         ib_inform_info_get_qpn_resp_time(p_iir->inform_info.g_or_v.generic.qpn_resp_time_val, &qpn, &resp_time_val);\r
499 \r
500         if (p_iir->inform_info.is_generic) {\r
501                 printf("InformInfoRecord dump:\n"\r
502                        "\t\tRID\n"\r
503                        "\t\tSubscriberGID...........%s\n"\r
504                        "\t\tSubscriberEnum..........0x%X\n"\r
505                        "\t\tInformInfo dump:\n"\r
506                        "\t\tgid.....................%s\n"\r
507                        "\t\tlid_range_begin.........0x%X\n"\r
508                        "\t\tlid_range_end...........0x%X\n"\r
509                        "\t\tis_generic..............0x%X\n"\r
510                        "\t\tsubscribe...............0x%X\n"\r
511                        "\t\ttrap_type...............0x%X\n"\r
512                        "\t\ttrap_num................%u\n"\r
513                        "\t\tqpn.....................0x%06X\n"\r
514                        "\t\tresp_time_val...........0x%X\n"\r
515                        "\t\tnode_type...............0x%06X\n"\r
516                        "",\r
517                        inet_ntop(AF_INET6, p_iir->subscriber_gid.raw, gid_str,\r
518                                 sizeof gid_str),\r
519                        cl_ntoh16( p_iir->subscriber_enum ),\r
520                        inet_ntop(AF_INET6, p_iir->inform_info.gid.raw, gid_str2,\r
521                                 sizeof gid_str2),\r
522                        cl_ntoh16( p_iir->inform_info.lid_range_begin ),\r
523                        cl_ntoh16( p_iir->inform_info.lid_range_end ),\r
524                        p_iir->inform_info.is_generic,\r
525                        p_iir->inform_info.subscribe,\r
526                        cl_ntoh16( p_iir->inform_info.trap_type ),\r
527                        cl_ntoh16( p_iir->inform_info.g_or_v.generic.trap_num ),\r
528                        cl_ntoh32( qpn ),\r
529                        resp_time_val,\r
530                        cl_ntoh32(ib_inform_info_get_prod_type( &p_iir->inform_info ))\r
531                       );\r
532         } else {\r
533                 printf("InformInfoRecord dump:\n"\r
534                        "\t\tRID\n"\r
535                        "\t\tSubscriberGID...........%s\n"\r
536                        "\t\tSubscriberEnum..........0x%X\n"\r
537                        "\t\tInformInfo dump:\n"\r
538                        "\t\tgid.....................%s\n"\r
539                        "\t\tlid_range_begin.........0x%X\n"\r
540                        "\t\tlid_range_end...........0x%X\n"\r
541                        "\t\tis_generic..............0x%X\n"\r
542                        "\t\tsubscribe...............0x%X\n"\r
543                        "\t\ttrap_type...............0x%X\n"\r
544                        "\t\tdev_id..................0x%X\n"\r
545                        "\t\tqpn.....................0x%06X\n"\r
546                        "\t\tresp_time_val...........0x%X\n"\r
547                        "\t\tvendor_id...............0x%06X\n"\r
548                        "",\r
549                        inet_ntop(AF_INET6, p_iir->subscriber_gid.raw, gid_str,\r
550                                 sizeof gid_str),\r
551                        cl_ntoh16( p_iir->subscriber_enum ),\r
552                        inet_ntop(AF_INET6, p_iir->inform_info.gid.raw,\r
553                                 gid_str2, sizeof gid_str2),\r
554                        cl_ntoh16( p_iir->inform_info.lid_range_begin ),\r
555                        cl_ntoh16( p_iir->inform_info.lid_range_end ),\r
556                        p_iir->inform_info.is_generic,\r
557                        p_iir->inform_info.subscribe,\r
558                        cl_ntoh16( p_iir->inform_info.trap_type ),\r
559                        cl_ntoh16( p_iir->inform_info.g_or_v.vend.dev_id ),\r
560                        cl_ntoh32( qpn ),\r
561                        resp_time_val,\r
562                        cl_ntoh32(ib_inform_info_get_prod_type( &p_iir->inform_info ))\r
563                       );\r
564         }\r
565 }\r
566 \r
567 static void dump_one_link_record(void *data)\r
568 {\r
569         ib_link_record_t *lr = data;\r
570         printf("LinkRecord dump:\n"\r
571                "\t\tFromLID....................%u\n"\r
572                "\t\tFromPort...................%u\n"\r
573                "\t\tToPort.....................%u\n"\r
574                "\t\tToLID......................%u\n",\r
575                cl_ntoh16(lr->from_lid), lr->from_port_num,\r
576                lr->to_port_num, cl_ntoh16(lr->to_lid));\r
577 }\r
578 \r
579 static void dump_one_slvl_record(void *data)\r
580 {\r
581         ib_slvl_table_record_t *slvl = data;\r
582         ib_slvl_table_t *t = &slvl->slvl_tbl;\r
583         printf("SL2VLTableRecord dump:\n"\r
584                "\t\tLID........................%u\n"\r
585                "\t\tInPort.....................%u\n"\r
586                "\t\tOutPort....................%u\n"\r
587                "\t\tSL: 0| 1| 2| 3| 4| 5| 6| 7| 8| 9|10|11|12|13|14|15|\n"\r
588                "\t\tVL:%2u|%2u|%2u|%2u|%2u|%2u|%2u|%2u|%2u|%2u|%2u|%2u|%2u"\r
589                "|%2u|%2u|%2u|\n",\r
590                cl_ntoh16(slvl->lid), slvl->in_port_num, slvl->out_port_num,\r
591                ib_slvl_table_get(t, 0), ib_slvl_table_get(t, 1),\r
592                ib_slvl_table_get(t, 2), ib_slvl_table_get(t, 3),\r
593                ib_slvl_table_get(t, 4), ib_slvl_table_get(t, 5),\r
594                ib_slvl_table_get(t, 6), ib_slvl_table_get(t, 7),\r
595                ib_slvl_table_get(t, 8), ib_slvl_table_get(t, 9),\r
596                ib_slvl_table_get(t, 10), ib_slvl_table_get(t, 11),\r
597                ib_slvl_table_get(t, 12), ib_slvl_table_get(t, 13),\r
598                ib_slvl_table_get(t, 14), ib_slvl_table_get(t, 15));\r
599 }\r
600 \r
601 static void dump_one_vlarb_record(void *data)\r
602 {\r
603         ib_vl_arb_table_record_t *vlarb = data;\r
604         ib_vl_arb_element_t *e = vlarb->vl_arb_tbl.vl_entry;\r
605         int i;\r
606         printf("VLArbTableRecord dump:\n"\r
607                "\t\tLID........................%u\n"\r
608                "\t\tPort.......................%u\n"\r
609                "\t\tBlock......................%u\n",\r
610                cl_ntoh16(vlarb->lid), vlarb->port_num, vlarb->block_num);\r
611         for (i = 0; i < 32 ; i += 16) {\r
612                 printf("\t\tVL    :%2u|%2u|%2u|%2u|%2u|%2u|%2u|%2u|"\r
613                        "%2u|%2u|%2u|%2u|%2u|%2u|%2u|%2u|",\r
614                        e[i + 0].vl, e[i + 1].vl, e[i + 2].vl, e[i + 3].vl,\r
615                        e[i + 4].vl, e[i + 5].vl, e[i + 6].vl, e[i + 7].vl,\r
616                        e[i + 8].vl, e[i + 9].vl, e[i + 10].vl, e[i + 11].vl,\r
617                        e[i + 12].vl, e[i + 13].vl, e[i + 14].vl, e[i + 15].vl);\r
618                 printf("\n\t\tWeight:%2u|%2u|%2u|%2u|%2u|%2u|%2u|%2u|"\r
619                        "%2u|%2u|%2u|%2u|%2u|%2u|%2u|%2u|",\r
620                        e[i + 0].weight, e[i + 1].weight, e[i + 2].weight,\r
621                        e[i + 3].weight, e[i + 4].weight, e[i + 5].weight,\r
622                        e[i + 6].weight, e[i + 7].weight, e[i + 8].weight,\r
623                        e[i + 9].weight, e[i + 10].weight, e[i + 11].weight,\r
624                        e[i + 12].weight, e[i + 13].weight, e[i + 14].weight,\r
625                        e[i + 15].weight);\r
626                 printf("\n");\r
627         }\r
628 }\r
629 \r
630 static void dump_one_pkey_tbl_record(void *data)\r
631 {\r
632         ib_pkey_table_record_t *pktr = data;\r
633         ib_net16_t *p = pktr->pkey_tbl.pkey_entry;\r
634         int i;\r
635         printf("PKeyTableRecord dump:\n"\r
636                "\t\tLID........................%u\n"\r
637                "\t\tPort.......................%u\n"\r
638                "\t\tBlock......................%u\n"\r
639                "\t\tPKey Table:\n",\r
640                cl_ntoh16(pktr->lid), pktr->port_num, pktr->block_num);\r
641         for (i = 0; i < 32 ; i += 8)\r
642                 printf("\t\t0x%04x 0x%04x 0x%04x 0x%04x"\r
643                        " 0x%04x 0x%04x 0x%04x 0x%04x\n",\r
644                        cl_ntoh16(p[i + 0]), cl_ntoh16(p[i + 1]),\r
645                        cl_ntoh16(p[i + 2]), cl_ntoh16(p[i + 3]),\r
646                        cl_ntoh16(p[i + 4]), cl_ntoh16(p[i + 5]),\r
647                        cl_ntoh16(p[i + 6]), cl_ntoh16(p[i + 7]));\r
648         printf("\n");\r
649 }\r
650 \r
651 static void dump_one_lft_record(void *data)\r
652 {\r
653         ib_lft_record_t *lftr = data;\r
654         unsigned block = cl_ntoh16(lftr->block_num);\r
655         int i;\r
656         printf("LFT Record dump:\n"\r
657                "\t\tLID........................%u\n"\r
658                "\t\tBlock......................%u\n"\r
659                "\t\tLFT:\n\t\tLID\tPort Number\n",\r
660                cl_ntoh16(lftr->lid), block);\r
661         for (i = 0; i < 64 ; i++)\r
662                 printf("\t\t%u\t%u\n", block*64 + i, lftr->lft[i]);\r
663         printf("\n");\r
664 }\r
665 \r
666 static void dump_one_mft_record(void *data)\r
667 {\r
668         ib_mft_record_t *mftr = data;\r
669         unsigned position = cl_ntoh16(mftr->position_block_num) >> 12;\r
670         unsigned block = cl_ntoh16(mftr->position_block_num) &\r
671                          IB_MCAST_BLOCK_ID_MASK_HO;\r
672         int i;\r
673         printf("MFT Record dump:\n"\r
674                "\t\tLID........................%u\n"\r
675                "\t\tPosition...................%u\n"\r
676                "\t\tBlock......................%u\n"\r
677                 "\t\tMFT:\n\t\tMLID\tPort Mask\n",\r
678                cl_ntoh16(mftr->lid), position, block);\r
679         for (i = 0; i < IB_MCAST_BLOCK_SIZE; i++)\r
680                 printf("\t\t0x%x\t0x%x\n", IB_LID_MCAST_START_HO + block*64 + i,\r
681                        cl_ntoh16(mftr->mft[i]));\r
682         printf("\n");\r
683 }\r
684 static void dump_results(osmv_query_res_t *r, void (*dump_func)(void *))\r
685 {\r
686         int i;\r
687         for (i = 0; i < r->result_cnt; i++) {\r
688                 void *data = osmv_get_query_result(r->p_result_madw, i);\r
689                 dump_func(data);\r
690         }\r
691 }\r
692 \r
693 static void\r
694 return_mad(void)\r
695 {\r
696         /*\r
697          * Return the IB query MAD to the pool as necessary.\r
698          */\r
699         if (result.p_result_madw != NULL) {\r
700                 osm_mad_pool_put(&mad_pool, result.p_result_madw);\r
701                 result.p_result_madw = NULL;\r
702         }\r
703 }\r
704 \r
705 /**\r
706  * Get any record(s)\r
707  */\r
708 static ib_api_status_t\r
709 get_any_records(osm_bind_handle_t bind_handle,\r
710                 ib_net16_t attr_id, ib_net32_t attr_mod, ib_net64_t comp_mask,\r
711                 void *attr, ib_net16_t attr_offset,\r
712                 ib_net64_t sm_key)\r
713 {\r
714         ib_api_status_t   status;\r
715         osmv_query_req_t  req;\r
716         osmv_user_query_t user;\r
717 \r
718         memset(&req, 0, sizeof(req));\r
719         memset(&user, 0, sizeof(user));\r
720 \r
721         user.attr_id = attr_id;\r
722         user.attr_offset = attr_offset;\r
723         user.attr_mod = attr_mod;\r
724         user.comp_mask = comp_mask;\r
725         user.p_attr = attr;\r
726 \r
727         req.query_type = OSMV_QUERY_USER_DEFINED;\r
728         req.timeout_ms = sa_timeout_ms;\r
729         req.retry_cnt = 1;\r
730         req.flags = OSM_SA_FLAGS_SYNC;\r
731         req.query_context = NULL;\r
732         req.pfn_query_cb = query_res_cb;\r
733         req.p_query_input = &user;\r
734         req.sm_key = sm_key;\r
735 \r
736         if ((status = osmv_query_sa(bind_handle, &req)) != IB_SUCCESS) {\r
737                 fprintf(stderr, "Query SA failed: %s\n",\r
738                         ib_get_err_str(status));\r
739                 return status;\r
740         }\r
741 \r
742         if (result.status != IB_SUCCESS) {\r
743                 fprintf(stderr, "Query result returned: %s\n",\r
744                         ib_get_err_str(result.status));\r
745                 return result.status;\r
746         }\r
747 \r
748         return status;\r
749 }\r
750 \r
751 /**\r
752  * Get all the records available for requested query type.\r
753  */\r
754 static ib_api_status_t\r
755 get_all_records(osm_bind_handle_t bind_handle,\r
756                 ib_net16_t query_id,\r
757                 ib_net16_t attr_offset,\r
758                 int trusted)\r
759 {\r
760         return get_any_records(bind_handle, query_id, 0, 0, NULL, attr_offset,\r
761                                trusted ? smkey : 0);\r
762 }\r
763 \r
764 /**\r
765  * return the lid from the node descriptor (name) supplied\r
766  */\r
767 static ib_api_status_t\r
768 get_lid_from_name(osm_bind_handle_t bind_handle, const char *name, ib_net16_t *lid)\r
769 {\r
770         int               i = 0;\r
771         ib_node_record_t *node_record = NULL;\r
772         ib_node_info_t   *p_ni = NULL;\r
773         ib_net16_t        attr_offset = ib_get_attr_offset(sizeof(*node_record));\r
774         ib_api_status_t   status;\r
775 \r
776         status = get_all_records(bind_handle, IB_MAD_ATTR_NODE_RECORD, attr_offset, 0);\r
777         if (status != IB_SUCCESS)\r
778                 return (status);\r
779 \r
780         for (i = 0; i < result.result_cnt; i++) {\r
781                 node_record = osmv_get_query_node_rec(result.p_result_madw, i);\r
782                 p_ni = &(node_record->node_info);\r
783                 if (name && strncmp(name, (char *)node_record->node_desc.description,\r
784                                     sizeof(node_record->node_desc.description)) == 0) {\r
785                         *lid = cl_ntoh16(node_record->lid);\r
786                         break;\r
787                 }\r
788         }\r
789         return_mad();\r
790         return (status);\r
791 }\r
792 \r
793 static ib_net16_t\r
794 get_lid(osm_bind_handle_t bind_handle, const char * name)\r
795 {\r
796         ib_net16_t rc_lid = 0;\r
797 \r
798         if (!name)\r
799                 return(0);\r
800         if (isalpha(name[0]))\r
801                 assert(get_lid_from_name(bind_handle, name, &rc_lid) == IB_SUCCESS);\r
802         else\r
803                 rc_lid = atoi(name);\r
804         if (rc_lid == 0)\r
805                 fprintf(stderr, "Failed to find lid for \"%s\"\n", name);\r
806         return (rc_lid);\r
807 }\r
808 \r
809 static int parse_lid_and_ports(osm_bind_handle_t bind_handle,\r
810                                char *str, int *lid, int *port1, int *port2)\r
811 {\r
812         char *p, *e;\r
813 \r
814         if (port1) *port1 = -1;\r
815         if (port2) *port2 = -1;\r
816 \r
817         p = strchr(str, '/');\r
818         if (p) *p = '\0';\r
819         if (lid)\r
820                 *lid = get_lid(bind_handle, str);\r
821 \r
822         if (!p)\r
823                 return 0;\r
824         str = p + 1;\r
825         p = strchr(str, '/');\r
826         if (p) *p = '\0';\r
827         if (port1) {\r
828                 *port1 = strtoul(str, &e, 0);\r
829                 if (e == str)\r
830                         *port1 = -1;\r
831         }\r
832 \r
833         if (!p)\r
834                 return 0;\r
835         str = p + 1;\r
836         if (port2) {\r
837                 *port2 = strtoul(str, &e, 0);\r
838                 if (e == str)\r
839                         *port2 = -1;\r
840         }\r
841 \r
842         return 0;\r
843 }\r
844 \r
845 /*\r
846  * Get the portinfo records available with IsSM or IsSMdisabled CapabilityMask bit on.\r
847  */\r
848 static ib_api_status_t\r
849 get_issm_records(osm_bind_handle_t bind_handle, ib_net32_t capability_mask)\r
850 {\r
851         ib_portinfo_record_t attr;\r
852 \r
853         memset( &attr, 0, sizeof ( attr ) );\r
854         attr.port_info.capability_mask = capability_mask;\r
855 \r
856         return get_any_records(bind_handle, IB_MAD_ATTR_PORTINFO_RECORD,\r
857                                cl_hton32(1 << 31), IB_PIR_COMPMASK_CAPMASK,\r
858                                &attr,\r
859                                ib_get_attr_offset(sizeof(ib_portinfo_record_t)),\r
860                                0);\r
861 }\r
862 \r
863 static ib_api_status_t\r
864 print_node_records(osm_bind_handle_t bind_handle)\r
865 {\r
866         int               i = 0;\r
867         ib_node_record_t *node_record = NULL;\r
868         ib_net16_t        attr_offset = ib_get_attr_offset(sizeof(*node_record));\r
869         ib_api_status_t   status;\r
870 \r
871         status  = get_all_records(bind_handle, IB_MAD_ATTR_NODE_RECORD, attr_offset, 0);\r
872         if (status != IB_SUCCESS)\r
873                 return (status);\r
874 \r
875         if (node_print_desc == ALL_DESC) {\r
876                 printf("   LID \"name\"\n");\r
877                 printf("================\n");\r
878         }\r
879         for (i = 0; i < result.result_cnt; i++) {\r
880                 node_record = osmv_get_query_node_rec(result.p_result_madw, i);\r
881                 if (node_print_desc == ALL_DESC) {\r
882                         print_node_desc(node_record);\r
883                 } else if (node_print_desc == NAME_OF_LID) {\r
884                         if (requested_lid == cl_ntoh16(node_record->lid)) {\r
885                                 print_node_record(node_record);\r
886                         }\r
887                 } else if (node_print_desc == NAME_OF_GUID) {\r
888                         ib_node_info_t *p_ni = &(node_record->node_info);\r
889 \r
890                         if (requested_guid == cl_ntoh64(p_ni->port_guid)) {\r
891                                 print_node_record(node_record);\r
892                         }\r
893                 } else {\r
894                         if (!requested_name ||\r
895                             (strncmp(requested_name,\r
896                                      (char *)node_record->node_desc.description,\r
897                                      sizeof(node_record->node_desc.description)) == 0)) {\r
898                                 print_node_record(node_record);\r
899                                 if (node_print_desc == UNIQUE_LID_ONLY) {\r
900                                         return_mad();\r
901                                         exit(0);\r
902                                 }\r
903                         }\r
904                 }\r
905         }\r
906         return_mad();\r
907         return (status);\r
908 }\r
909 \r
910 static ib_api_status_t\r
911 get_print_path_rec_lid(osm_bind_handle_t bind_handle,\r
912                        ib_net16_t src_lid,\r
913                        ib_net16_t dst_lid)\r
914 {\r
915         osmv_query_req_t      req;\r
916         osmv_lid_pair_t       lid_pair;\r
917         ib_api_status_t       status;\r
918 \r
919         lid_pair.src_lid = cl_hton16(src_lid);\r
920         lid_pair.dest_lid = cl_hton16(dst_lid);\r
921 \r
922         memset( &req, 0, sizeof( req ) );\r
923 \r
924         req.query_type = OSMV_QUERY_PATH_REC_BY_LIDS;\r
925         req.timeout_ms = sa_timeout_ms;\r
926         req.retry_cnt = 1;\r
927         req.flags = OSM_SA_FLAGS_SYNC;\r
928         req.query_context = NULL;\r
929         req.pfn_query_cb = query_res_cb;\r
930         req.p_query_input = (void *)&lid_pair;\r
931         req.sm_key = 0;\r
932 \r
933         if ((status = osmv_query_sa(bind_handle, &req)) != IB_SUCCESS) {\r
934                 fprintf(stderr, "ERROR: Query SA failed: %s\n",\r
935                         ib_get_err_str(status));\r
936                 return (status);\r
937         }\r
938         if (result.status != IB_SUCCESS) {\r
939                 fprintf(stderr, "ERROR: Query result returned: %s\n",\r
940                         ib_get_err_str(result.status));\r
941                 return (result.status);\r
942         }\r
943         status = result.status;\r
944         dump_results(&result, dump_path_record);\r
945         return_mad();\r
946         return (status);\r
947 }\r
948 \r
949 static ib_api_status_t\r
950 get_print_path_rec_gid(osm_bind_handle_t bind_handle,\r
951                        const ib_gid_t *src_gid,\r
952                        const ib_gid_t *dst_gid)\r
953 {\r
954         osmv_query_req_t      req;\r
955         osmv_gid_pair_t       gid_pair;\r
956         ib_api_status_t       status;\r
957 \r
958         gid_pair.src_gid = *src_gid;\r
959         gid_pair.dest_gid = *dst_gid;\r
960 \r
961         memset( &req, 0, sizeof( req ) );\r
962 \r
963         req.query_type = OSMV_QUERY_PATH_REC_BY_GIDS;\r
964         req.timeout_ms = sa_timeout_ms;\r
965         req.retry_cnt = 1;\r
966         req.flags = OSM_SA_FLAGS_SYNC;\r
967         req.query_context = NULL;\r
968         req.pfn_query_cb = query_res_cb;\r
969         req.p_query_input = (void *)&gid_pair;\r
970         req.sm_key = 0;\r
971 \r
972         if ((status = osmv_query_sa(bind_handle, &req)) != IB_SUCCESS) {\r
973                 fprintf(stderr, "ERROR: Query SA failed: %s\n",\r
974                         ib_get_err_str(status));\r
975                 return (status);\r
976         }\r
977         if (result.status != IB_SUCCESS) {\r
978                 fprintf(stderr, "ERROR: Query result returned: %s\n",\r
979                         ib_get_err_str(result.status));\r
980                 return (result.status);\r
981         }\r
982         status = result.status;\r
983         dump_results(&result, dump_path_record);\r
984         return_mad();\r
985         return (status);\r
986 }\r
987 \r
988 static ib_api_status_t\r
989 get_print_class_port_info(osm_bind_handle_t bind_handle)\r
990 {\r
991         osmv_query_req_t      req;\r
992         ib_api_status_t       status;\r
993 \r
994         memset( &req, 0, sizeof( req ) );\r
995 \r
996         req.query_type = OSMV_QUERY_CLASS_PORT_INFO;\r
997         req.timeout_ms = sa_timeout_ms;\r
998         req.retry_cnt = 1;\r
999         req.flags = OSM_SA_FLAGS_SYNC;\r
1000         req.query_context = NULL;\r
1001         req.pfn_query_cb = query_res_cb;\r
1002         req.p_query_input = NULL;\r
1003         req.sm_key = 0;\r
1004 \r
1005         if ((status = osmv_query_sa(bind_handle, &req)) != IB_SUCCESS) {\r
1006                 fprintf(stderr, "ERROR: Query SA failed: %s\n",\r
1007                         ib_get_err_str(status));\r
1008                 return (status);\r
1009         }\r
1010         if (result.status != IB_SUCCESS) {\r
1011                 fprintf(stderr, "ERROR: Query result returned: %s\n",\r
1012                         ib_get_err_str(result.status));\r
1013                 return (result.status);\r
1014         }\r
1015         status = result.status;\r
1016         dump_results(&result, dump_class_port_info);\r
1017         return_mad();\r
1018         return (status);\r
1019 }\r
1020 \r
1021 static ib_api_status_t\r
1022 print_path_records(osm_bind_handle_t bind_handle)\r
1023 {\r
1024         ib_net16_t attr_offset = ib_get_attr_offset(sizeof(ib_path_rec_t));\r
1025         ib_api_status_t status;\r
1026 \r
1027         status = get_all_records(bind_handle, IB_MAD_ATTR_PATH_RECORD, attr_offset, 0);\r
1028         if (status != IB_SUCCESS)\r
1029                 return (status);\r
1030 \r
1031         dump_results(&result, dump_path_record);\r
1032         return_mad();\r
1033         return (status);\r
1034 }\r
1035 \r
1036 static ib_api_status_t\r
1037 print_portinfo_records(osm_bind_handle_t bind_handle)\r
1038 {\r
1039         ib_api_status_t       status;\r
1040 \r
1041         /* First, get IsSM records */\r
1042         status = get_issm_records(bind_handle, IB_PORT_CAP_IS_SM);\r
1043         if (status != IB_SUCCESS)\r
1044                 return (status);\r
1045 \r
1046         printf("IsSM ports\n");\r
1047         dump_results(&result, dump_portinfo_record);\r
1048         return_mad();\r
1049 \r
1050         /* Now, get IsSMdisabled records */\r
1051         status = get_issm_records(bind_handle, IB_PORT_CAP_SM_DISAB);\r
1052         if (status != IB_SUCCESS)\r
1053                 return (status);\r
1054 \r
1055         printf("\nIsSMdisabled ports\n");\r
1056         dump_results(&result, dump_portinfo_record);\r
1057         return_mad();\r
1058 \r
1059         return (status);\r
1060 }\r
1061 \r
1062 static ib_api_status_t\r
1063 print_multicast_member_records(osm_bind_handle_t bind_handle)\r
1064 {\r
1065         osmv_query_res_t  mc_group_result;\r
1066         ib_api_status_t   status;\r
1067 \r
1068         status = get_all_records(bind_handle, IB_MAD_ATTR_MCMEMBER_RECORD,\r
1069                                  ib_get_attr_offset(sizeof(ib_member_rec_t)), 1);\r
1070         if (status != IB_SUCCESS)\r
1071                 return (status);\r
1072 \r
1073         mc_group_result = result;\r
1074 \r
1075         status  = get_all_records(bind_handle, IB_MAD_ATTR_NODE_RECORD,\r
1076                                   ib_get_attr_offset(sizeof(ib_node_record_t)), 0);\r
1077         if (status != IB_SUCCESS)\r
1078                 goto return_mc;\r
1079 \r
1080         dump_results(&mc_group_result, dump_multicast_member_record);\r
1081         return_mad();\r
1082 \r
1083 return_mc:\r
1084         /* return_mad for the mc_group_result */\r
1085         if (mc_group_result.p_result_madw != NULL) {\r
1086                 osm_mad_pool_put(&mad_pool, mc_group_result.p_result_madw);\r
1087                 mc_group_result.p_result_madw = NULL;\r
1088         }\r
1089 \r
1090         return (status);\r
1091 }\r
1092 \r
1093 static ib_api_status_t\r
1094 print_multicast_group_records(osm_bind_handle_t bind_handle)\r
1095 {\r
1096         ib_api_status_t   status;\r
1097 \r
1098         status = get_all_records(bind_handle, IB_MAD_ATTR_MCMEMBER_RECORD,\r
1099                                  ib_get_attr_offset(sizeof(ib_member_rec_t)), 0);\r
1100         if (status != IB_SUCCESS)\r
1101                 return (status);\r
1102 \r
1103         dump_results(&result, dump_multicast_group_record);\r
1104         return_mad();\r
1105         return (status);\r
1106 }\r
1107 \r
1108 static ib_api_status_t\r
1109 print_service_records(osm_bind_handle_t bind_handle)\r
1110 {\r
1111         ib_net16_t attr_offset = ib_get_attr_offset(sizeof(ib_service_record_t));\r
1112         ib_api_status_t status;\r
1113 \r
1114         status = get_all_records(bind_handle, IB_MAD_ATTR_SERVICE_RECORD, attr_offset, 0);\r
1115         if (status != IB_SUCCESS)\r
1116                 return (status);\r
1117 \r
1118         dump_results(&result, dump_service_record);\r
1119         return_mad();\r
1120         return (status);\r
1121 }\r
1122 \r
1123 static ib_api_status_t\r
1124 print_inform_info_records(osm_bind_handle_t bind_handle)\r
1125 {\r
1126         ib_net16_t attr_offset = ib_get_attr_offset(sizeof(ib_inform_info_record_t));\r
1127         ib_api_status_t status;\r
1128 \r
1129         status = get_all_records(bind_handle, IB_MAD_ATTR_INFORM_INFO_RECORD, attr_offset, 0);\r
1130         if (status != IB_SUCCESS)\r
1131                 return (status);\r
1132 \r
1133         dump_results(&result, dump_inform_info_record);\r
1134         return_mad();\r
1135         return (status);\r
1136 }\r
1137 \r
1138 static ib_api_status_t\r
1139 print_link_records(osm_bind_handle_t bind_handle, int argc, char *argv[])\r
1140 {\r
1141         ib_link_record_t lr;\r
1142         ib_net64_t comp_mask = 0;\r
1143         int from_lid = 0, to_lid = 0, from_port = -1, to_port = -1;\r
1144         ib_api_status_t status;\r
1145 \r
1146         if (argc > 0)\r
1147                 parse_lid_and_ports(bind_handle, argv[0],\r
1148                                     &from_lid, &from_port, NULL);\r
1149 \r
1150         if (argc > 1)\r
1151                 parse_lid_and_ports(bind_handle, argv[1],\r
1152                                     &to_lid, &to_port, NULL);\r
1153 \r
1154         memset(&lr, 0, sizeof(lr));\r
1155 \r
1156         if (from_lid > 0) {\r
1157                 lr.from_lid = cl_hton16(from_lid);\r
1158                 comp_mask |= IB_LR_COMPMASK_FROM_LID;\r
1159         }\r
1160         if (from_port >= 0) {\r
1161                 lr.from_port_num = from_port;\r
1162                 comp_mask |= IB_LR_COMPMASK_FROM_PORT;\r
1163         }\r
1164         if (to_lid > 0) {\r
1165                 lr.to_lid = cl_hton16(to_lid);\r
1166                 comp_mask |= IB_LR_COMPMASK_TO_LID;\r
1167         }\r
1168         if (to_port >= 0) {\r
1169                 lr.to_port_num = to_port;\r
1170                 comp_mask |= IB_LR_COMPMASK_TO_PORT;\r
1171         }\r
1172 \r
1173         status = get_any_records(bind_handle, IB_MAD_ATTR_LINK_RECORD, 0,\r
1174                                  comp_mask, &lr,\r
1175                                  ib_get_attr_offset(sizeof(lr)), 0);\r
1176         if (status != IB_SUCCESS)\r
1177                 return status;\r
1178 \r
1179         dump_results(&result, dump_one_link_record);\r
1180         return_mad();\r
1181         return status;\r
1182 }\r
1183 \r
1184 static int\r
1185 print_sl2vl_records(const struct query_cmd *q, osm_bind_handle_t bind_handle,\r
1186                     int argc, char *argv[])\r
1187 {\r
1188         ib_slvl_table_record_t slvl;\r
1189         ib_net64_t comp_mask = 0;\r
1190         int lid = 0, in_port = -1, out_port = -1;\r
1191         ib_api_status_t status;\r
1192 \r
1193         if (argc > 0)\r
1194                 parse_lid_and_ports(bind_handle, argv[0],\r
1195                                     &lid, &in_port, &out_port);\r
1196 \r
1197         memset(&slvl, 0, sizeof(slvl));\r
1198 \r
1199         if (lid > 0) {\r
1200                 slvl.lid = cl_hton16(lid);\r
1201                 comp_mask |= IB_SLVL_COMPMASK_LID;\r
1202         }\r
1203         if (in_port >= 0) {\r
1204                 slvl.in_port_num = in_port;\r
1205                 comp_mask |= IB_SLVL_COMPMASK_IN_PORT;\r
1206         }\r
1207         if (out_port >= 0) {\r
1208                 slvl.out_port_num = out_port;\r
1209                 comp_mask |= IB_SLVL_COMPMASK_OUT_PORT;\r
1210         }\r
1211 \r
1212         status = get_any_records(bind_handle, IB_MAD_ATTR_SLVL_RECORD, 0,\r
1213                                  comp_mask, &slvl,\r
1214                                  ib_get_attr_offset(sizeof(slvl)), 0);\r
1215         if (status != IB_SUCCESS)\r
1216                 return status;\r
1217 \r
1218         dump_results(&result, dump_one_slvl_record);\r
1219         return_mad();\r
1220         return status;\r
1221 }\r
1222 \r
1223 static int\r
1224 print_vlarb_records(const struct query_cmd *q, osm_bind_handle_t bind_handle,\r
1225                     int argc, char *argv[])\r
1226 {\r
1227         ib_vl_arb_table_record_t vlarb;\r
1228         ib_net64_t comp_mask = 0;\r
1229         int lid = 0, port = -1, block = -1;\r
1230         ib_api_status_t status;\r
1231 \r
1232         if (argc > 0)\r
1233                 parse_lid_and_ports(bind_handle, argv[0],\r
1234                                     &lid, &port, &block);\r
1235 \r
1236         memset(&vlarb, 0, sizeof(vlarb));\r
1237 \r
1238         if (lid > 0) {\r
1239                 vlarb.lid = cl_hton16(lid);\r
1240                 comp_mask |= IB_VLA_COMPMASK_LID;\r
1241         }\r
1242         if (port >= 0) {\r
1243                 vlarb.port_num = port;\r
1244                 comp_mask |= IB_VLA_COMPMASK_OUT_PORT;\r
1245         }\r
1246         if (block >= 0) {\r
1247                 vlarb.block_num = block;\r
1248                 comp_mask |= IB_VLA_COMPMASK_BLOCK;\r
1249         }\r
1250 \r
1251         status = get_any_records(bind_handle, IB_MAD_ATTR_VLARB_RECORD, 0,\r
1252                                  comp_mask, &vlarb,\r
1253                                  ib_get_attr_offset(sizeof(vlarb)), 0);\r
1254         if (status != IB_SUCCESS)\r
1255                 return status;\r
1256 \r
1257         dump_results(&result, dump_one_vlarb_record);\r
1258         return_mad();\r
1259         return status;\r
1260 }\r
1261 \r
1262 static int\r
1263 print_pkey_tbl_records(const struct query_cmd *q, osm_bind_handle_t bind_handle,\r
1264                        int argc, char *argv[])\r
1265 {\r
1266         ib_pkey_table_record_t pktr;\r
1267         ib_net64_t comp_mask = 0;\r
1268         int lid = 0, port = -1, block = -1;\r
1269         ib_api_status_t status;\r
1270 \r
1271         if (argc > 0)\r
1272                 parse_lid_and_ports(bind_handle, argv[0],\r
1273                                     &lid, &port, &block);\r
1274 \r
1275         memset(&pktr, 0, sizeof(pktr));\r
1276 \r
1277         if (lid > 0) {\r
1278                 pktr.lid = cl_hton16(lid);\r
1279                 comp_mask |= IB_PKEY_COMPMASK_LID;\r
1280         }\r
1281         if (port >= 0) {\r
1282                 pktr.port_num = port;\r
1283                 comp_mask |= IB_PKEY_COMPMASK_PORT;\r
1284         }\r
1285         if (block >= 0) {\r
1286                 pktr.block_num = block;\r
1287                 comp_mask |= IB_PKEY_COMPMASK_BLOCK;\r
1288         }\r
1289 \r
1290         status = get_any_records(bind_handle, IB_MAD_ATTR_PKEY_TBL_RECORD, 0,\r
1291                                  comp_mask, &pktr,\r
1292                                  ib_get_attr_offset(sizeof(pktr)), smkey);\r
1293         if (status != IB_SUCCESS)\r
1294                 return status;\r
1295 \r
1296         dump_results(&result, dump_one_pkey_tbl_record);\r
1297         return_mad();\r
1298         return status;\r
1299 }\r
1300 \r
1301 static int\r
1302 print_lft_records(const struct query_cmd *q, osm_bind_handle_t bind_handle,\r
1303                   int argc, char *argv[])\r
1304 {\r
1305         ib_lft_record_t lftr;\r
1306         ib_net64_t comp_mask = 0;\r
1307         int lid = 0, block = -1;\r
1308         ib_api_status_t status;\r
1309 \r
1310         if (argc > 0)\r
1311                 parse_lid_and_ports(bind_handle, argv[0],\r
1312                                     &lid, &block, NULL);\r
1313 \r
1314         memset(&lftr, 0, sizeof(lftr));\r
1315 \r
1316         if (lid > 0) {\r
1317                 lftr.lid = cl_hton16(lid);\r
1318                 comp_mask |= IB_LFTR_COMPMASK_LID;\r
1319         }\r
1320         if (block >= 0) {\r
1321                 lftr.block_num = cl_hton16(block);\r
1322                 comp_mask |= IB_LFTR_COMPMASK_BLOCK;\r
1323         }\r
1324 \r
1325         status = get_any_records(bind_handle, IB_MAD_ATTR_LFT_RECORD, 0,\r
1326                                  comp_mask, &lftr,\r
1327                                  ib_get_attr_offset(sizeof(lftr)), 0);\r
1328         if (status != IB_SUCCESS)\r
1329                 return status;\r
1330 \r
1331         dump_results(&result, dump_one_lft_record);\r
1332         return_mad();\r
1333         return status;\r
1334 }\r
1335 \r
1336 static int\r
1337 print_mft_records(const struct query_cmd *q, osm_bind_handle_t bind_handle,\r
1338                   int argc, char *argv[])\r
1339 {\r
1340         ib_mft_record_t mftr;\r
1341         ib_net64_t comp_mask = 0;\r
1342         int lid = 0, block = -1, position = -1;\r
1343         ib_api_status_t status;\r
1344 \r
1345         if (argc > 0)\r
1346                 parse_lid_and_ports(bind_handle, argv[0],\r
1347                                    &lid, &position, &block);\r
1348 \r
1349         memset(&mftr, 0, sizeof(mftr));\r
1350 \r
1351         if (lid > 0) {\r
1352                 mftr.lid = cl_hton16(lid);\r
1353                 comp_mask |= IB_MFTR_COMPMASK_LID;\r
1354         }\r
1355         if (position >= 0) {\r
1356                 mftr.position_block_num = cl_hton16(position << 12);\r
1357                 comp_mask |= IB_MFTR_COMPMASK_POSITION;\r
1358         }\r
1359         if (block >= 0) {\r
1360                 mftr.position_block_num |= cl_hton16(block & IB_MCAST_BLOCK_ID_MASK_HO);\r
1361                 comp_mask |= IB_MFTR_COMPMASK_BLOCK;\r
1362         }\r
1363 \r
1364         status = get_any_records(bind_handle, IB_MAD_ATTR_MFT_RECORD, 0,\r
1365                                  comp_mask, &mftr,\r
1366                                  ib_get_attr_offset(sizeof(mftr)), 0);\r
1367         if (status != IB_SUCCESS)\r
1368                 return status;\r
1369 \r
1370         dump_results(&result, dump_one_mft_record);\r
1371         return_mad();\r
1372         return status;\r
1373 }\r
1374 \r
1375 static osm_bind_handle_t\r
1376 get_bind_handle(void)\r
1377 {\r
1378         uint32_t           i = 0;\r
1379         uint64_t           port_guid = (uint64_t)-1;\r
1380         osm_bind_handle_t  bind_handle;\r
1381         ib_api_status_t    status;\r
1382         ib_port_attr_t     attr_array[MAX_PORTS];\r
1383         uint32_t           num_ports = MAX_PORTS;\r
1384         uint32_t           ca_name_index = 0;\r
1385 \r
1386         complib_init();\r
1387 \r
1388         osm_log_construct(&log_osm);\r
1389         if ((status = osm_log_init_v2(&log_osm, TRUE, 0x0001, NULL,\r
1390                                       0, TRUE)) != IB_SUCCESS) {\r
1391                 fprintf(stderr, "Failed to init osm_log: %s\n",\r
1392                         ib_get_err_str(status));\r
1393                 exit(-1);\r
1394         }\r
1395         osm_log_set_level(&log_osm, OSM_LOG_NONE);\r
1396         if (osm_debug)\r
1397                 osm_log_set_level(&log_osm, OSM_LOG_DEFAULT_LEVEL);\r
1398 \r
1399         vendor = osm_vendor_new(&log_osm, sa_timeout_ms);\r
1400         osm_mad_pool_construct(&mad_pool);\r
1401         if ((status = osm_mad_pool_init(&mad_pool)) != IB_SUCCESS) {\r
1402                 fprintf(stderr, "Failed to init mad pool: %s\n",\r
1403                         ib_get_err_str(status));\r
1404                 exit(-1);\r
1405         }\r
1406 \r
1407         if ((status = osm_vendor_get_all_port_attr(vendor, attr_array, &num_ports)) != IB_SUCCESS) {\r
1408                 fprintf(stderr, "Failed to get port attributes: %s\n",\r
1409                         ib_get_err_str(status));\r
1410                 exit(-1);\r
1411         }\r
1412 \r
1413         for (i = 0; i < num_ports; i++) {\r
1414                 if (i > 1 && cl_ntoh64(attr_array[i].port_guid)\r
1415                                 != (cl_ntoh64(attr_array[i-1].port_guid) + 1))\r
1416                         ca_name_index++;\r
1417                 if (sa_port_num && sa_port_num != attr_array[i].port_num)\r
1418                         continue;\r
1419                 if (sa_hca_name\r
1420                  && strcmp(sa_hca_name, vendor->ca_names[ca_name_index]) != 0)\r
1421                         continue;\r
1422                 if (attr_array[i].link_state == IB_LINK_ACTIVE) {\r
1423                         port_guid = attr_array[i].port_guid;\r
1424                         break;\r
1425                 }\r
1426         }\r
1427 \r
1428         if (port_guid == (uint64_t)-1) {\r
1429                 fprintf(stderr, "Failed to find active port, check port status with \"ibstat\"\n");\r
1430                 exit(-1);\r
1431         }\r
1432 \r
1433         bind_handle = osmv_bind_sa(vendor, &mad_pool, port_guid);\r
1434 \r
1435         if (bind_handle == OSM_BIND_INVALID_HANDLE) {\r
1436                 fprintf(stderr, "Failed to bind to SA\n");\r
1437                 exit(-1);\r
1438         }\r
1439         return (bind_handle);\r
1440 }\r
1441 \r
1442 static void\r
1443 clean_up(void)\r
1444 {\r
1445         osm_mad_pool_destroy(&mad_pool);\r
1446         osm_vendor_delete(&vendor);\r
1447 }\r
1448 \r
1449 static const struct query_cmd query_cmds[] = {\r
1450         { "ClassPortInfo", "CPI", IB_MAD_ATTR_CLASS_PORT_INFO, },\r
1451         { "NodeRecord", "NR", IB_MAD_ATTR_NODE_RECORD, },\r
1452         { "PortInfoRecord", "PIR", IB_MAD_ATTR_PORTINFO_RECORD, },\r
1453         { "SL2VLTableRecord", "SL2VL", IB_MAD_ATTR_SLVL_RECORD,\r
1454           "[[lid]/[in_port]/[out_port]]",\r
1455            print_sl2vl_records },\r
1456         { "PKeyTableRecord", "PKTR", IB_MAD_ATTR_PKEY_TBL_RECORD,\r
1457           "[[lid]/[port]/[block]]",\r
1458            print_pkey_tbl_records },\r
1459         { "VLArbitrationTableRecord", "VLAR", IB_MAD_ATTR_VLARB_RECORD,\r
1460           "[[lid]/[port]/[block]]",\r
1461            print_vlarb_records },\r
1462         { "InformInfoRecord", "IIR", IB_MAD_ATTR_INFORM_INFO_RECORD, },\r
1463         { "LinkRecord", "LR", IB_MAD_ATTR_LINK_RECORD,\r
1464           "[[from_lid]/[from_port]] [[to_lid]/[to_port]]", },\r
1465         { "ServiceRecord", "SR", IB_MAD_ATTR_SERVICE_RECORD, },\r
1466         { "PathRecord", "PR", IB_MAD_ATTR_PATH_RECORD, },\r
1467         { "MCMemberRecord", "MCMR", IB_MAD_ATTR_MCMEMBER_RECORD, },\r
1468         { "LFTRecord", "LFTR", IB_MAD_ATTR_LFT_RECORD, "[[lid]/[block]]",\r
1469           print_lft_records },\r
1470         { "MFTRecord", "MFTR", IB_MAD_ATTR_MFT_RECORD,\r
1471           "[[mlid]/[position]/[block]]",\r
1472           print_mft_records },\r
1473         { 0 }\r
1474 };\r
1475 \r
1476 static const struct query_cmd *find_query(const char *name)\r
1477 {\r
1478         const struct query_cmd *q;\r
1479         unsigned len = strlen(name);\r
1480 \r
1481         for (q = query_cmds; q->name; q++)\r
1482                 if (!strncasecmp(name, q->name, len) ||\r
1483                     (q->alias && !strncasecmp(name, q->alias, len)))\r
1484                         return q;\r
1485 \r
1486         return NULL;\r
1487 }\r
1488 \r
1489 static void\r
1490 usage(void)\r
1491 {\r
1492         const struct query_cmd *q;\r
1493 \r
1494         fprintf(stderr, "Usage: %s [-h -d -p -N] [--list | -D] [-S -I -L -l -G"\r
1495                 " -O -U -c -s -g -m --src-to-dst <src:dst> --sgid-to-dgid <src-dst> "\r
1496                 "-C <ca_name> -P <ca_port> -t(imeout) <msec>] [query-name] [<name> | <lid> | <guid>]\n",\r
1497                 argv0);\r
1498         fprintf(stderr, "   Queries node records by default\n");\r
1499         fprintf(stderr, "   -d enable debugging\n");\r
1500         fprintf(stderr, "   -p get PathRecord info\n");\r
1501         fprintf(stderr, "   -N get NodeRecord info\n");\r
1502         fprintf(stderr, "   --list | -D the node desc of the CA's\n");\r
1503         fprintf(stderr, "   -S get ServiceRecord info\n");\r
1504         fprintf(stderr, "   -I get InformInfoRecord (subscription) info\n");\r
1505         fprintf(stderr, "   -L return the Lids of the name specified\n");\r
1506         fprintf(stderr, "   -l return the unique Lid of the name specified\n");\r
1507         fprintf(stderr, "   -G return the Guids of the name specified\n");\r
1508         fprintf(stderr, "   -O return name for the Lid specified\n");\r
1509         fprintf(stderr, "   -U return name for the Guid specified\n");\r
1510         fprintf(stderr, "   -c get the SA's class port info\n");\r
1511         fprintf(stderr, "   -s return the PortInfoRecords with isSM or "\r
1512                                 "isSMdisabled capability mask bit on\n");\r
1513         fprintf(stderr, "   -g get multicast group info\n");\r
1514         fprintf(stderr, "   -m get multicast member info\n");\r
1515         fprintf(stderr, "      (if multicast group specified, list member GIDs"\r
1516                                 " only for group specified\n");\r
1517         fprintf(stderr, "      specified, for example 'saquery -m 0xC000')\n");\r
1518         fprintf(stderr, "   -x get LinkRecord info\n");\r
1519         fprintf(stderr, "   --src-to-dst get a PathRecord for <src:dst>\n"\r
1520                         "                where src and dst are either node "\r
1521                                 "names or LIDs\n");\r
1522         fprintf(stderr, "   --sgid-to-dgid get a PathRecord for <sgid-dgid>\n"\r
1523                         "                where sgid and dgid are addresses in "\r
1524                                 "IPv6 format\n");\r
1525         fprintf(stderr, "   -C <ca_name> specify the SA query HCA\n");\r
1526         fprintf(stderr, "   -P <ca_port> specify the SA query port\n");\r
1527         fprintf(stderr, "   --smkey <val> specify SM_Key value for the query."\r
1528                         " If non-numeric value \n"\r
1529                         "                 (like 'x') is specified then "\r
1530                         "saquery will prompt for a value\n");\r
1531         fprintf(stderr, "   -t | --timeout <msec> specify the SA query "\r
1532                                 "response timeout (default %u msec)\n",\r
1533                         DEFAULT_SA_TIMEOUT_MS);\r
1534         fprintf(stderr, "   --node-name-map <node-name-map> specify a node name map\n");\r
1535         fprintf(stderr, "\n   Supported query names (and aliases):\n");\r
1536         for (q = query_cmds; q->name; q++)\r
1537                 fprintf(stderr, "      %s (%s) %s\n", q->name,\r
1538                         q->alias ? q->alias : "", q->usage ? q->usage : "");\r
1539         fprintf(stderr, "\n");\r
1540 \r
1541         exit(-1);\r
1542 }\r
1543 \r
1544 int\r
1545 main(int argc, char **argv)\r
1546 {\r
1547         int                ch = 0;\r
1548         int                members = 0;\r
1549         osm_bind_handle_t  bind_handle;\r
1550         const struct query_cmd *q = NULL;\r
1551         char              *src = NULL;\r
1552         char              *dst = NULL;\r
1553         char              *sgid = NULL;\r
1554         char              *dgid = NULL;\r
1555         ib_net16_t         query_type = 0;\r
1556         ib_net16_t         src_lid;\r
1557         ib_net16_t         dst_lid;\r
1558         ib_api_status_t    status;\r
1559 \r
1560         static char const str_opts[] = "pVNDLlGOUcSIsgmxdhP:C:t:";\r
1561         static const struct option long_opts [] = {\r
1562            {"p", 0, 0, 'p'},\r
1563            {"Version", 0, 0, 'V'},\r
1564            {"N", 0, 0, 'N'},\r
1565            {"L", 0, 0, 'L'},\r
1566            {"l", 0, 0, 'l'},\r
1567            {"G", 0, 0, 'G'},\r
1568            {"O", 0, 0, 'O'},\r
1569            {"U", 0, 0, 'U'},\r
1570            {"s", 0, 0, 's'},\r
1571            {"g", 0, 0, 'g'},\r
1572            {"m", 0, 0, 'm'},\r
1573            {"x", 0, 0, 'x'},\r
1574            {"d", 0, 0, 'd'},\r
1575            {"c", 0, 0, 'c'},\r
1576            {"S", 0, 0, 'S'},\r
1577            {"I", 0, 0, 'I'},\r
1578            {"P", 1, 0, 'P'},\r
1579            {"C", 1, 0, 'C'},\r
1580            {"help", 0, 0, 'h'},\r
1581            {"list", 0, 0, 'D'},\r
1582            {"src-to-dst", 1, 0, 1},\r
1583            {"sgid-to-dgid", 1, 0, 2},\r
1584            {"timeout", 1, 0, 't'},\r
1585            {"node-name-map", 1, 0, 3},\r
1586            {"smkey", 1, 0, 4},\r
1587            { }\r
1588         };\r
1589 \r
1590         argv0 = argv[0];\r
1591 \r
1592         while ((ch = getopt_long_only(argc, argv, str_opts, long_opts, NULL)) != -1) {\r
1593                 switch (ch) {\r
1594                 case 1:\r
1595                 {\r
1596                         char *opt  = strdup(optarg);\r
1597                         char *ch = strchr(opt, ':');\r
1598                         if (!ch) {\r
1599                                 fprintf(stderr,\r
1600                                         "ERROR: --src-to-dst <node>:<node>\n");\r
1601                                 usage();\r
1602                         }\r
1603                         *ch++ = '\0';\r
1604                         if (*opt)\r
1605                                 src = strdup(opt);\r
1606                         if (*ch)\r
1607                                 dst = strdup(ch);\r
1608                         free(opt);\r
1609                         query_type = IB_MAD_ATTR_PATH_RECORD;\r
1610                         break;\r
1611                 }\r
1612                 case 2:\r
1613                 {\r
1614                         char *opt  = strdup(optarg);\r
1615                         char *tok1 = strtok(opt, "-");\r
1616                         char *tok2 = strtok(NULL, "\0");\r
1617 \r
1618                         if (tok1 && tok2) {\r
1619                                 sgid = strdup(tok1);\r
1620                                 dgid = strdup(tok2);\r
1621                         } else {\r
1622                                 fprintf(stderr,\r
1623                                         "ERROR: --sgid-to-dgid <GID>-<GID>\n");\r
1624                                 usage();\r
1625                         }\r
1626                         free(opt);\r
1627                         query_type = IB_MAD_ATTR_PATH_RECORD;\r
1628                         break;\r
1629                 }\r
1630                 case 3:\r
1631                         node_name_map_file = strdup(optarg);\r
1632                         break;\r
1633                 case 4:\r
1634                         if (!isxdigit(*optarg) &&\r
1635                             !(optarg = getpass("SM_Key: "))) {\r
1636                                 fprintf(stderr, "cannot get SM_Key\n");\r
1637                                 usage();\r
1638                         }\r
1639                         smkey = cl_hton64(strtoull(optarg, NULL, 0));\r
1640                         break;\r
1641                 case 'p':\r
1642                         query_type = IB_MAD_ATTR_PATH_RECORD;\r
1643                         break;\r
1644                 case 'V':\r
1645                         fprintf(stderr, "%s %s\n", argv0, get_build_version());\r
1646                         exit(-1);\r
1647                 case 'D':\r
1648                         node_print_desc = ALL_DESC;\r
1649                         break;\r
1650                 case 'c':\r
1651                         query_type = IB_MAD_ATTR_CLASS_PORT_INFO;\r
1652                         break;\r
1653                 case 'S':\r
1654                         query_type = IB_MAD_ATTR_SERVICE_RECORD;\r
1655                         break;\r
1656                 case 'I':\r
1657                         query_type = IB_MAD_ATTR_INFORM_INFO_RECORD;\r
1658                         break;\r
1659                 case 'N':\r
1660                         query_type = IB_MAD_ATTR_NODE_RECORD;\r
1661                         break;\r
1662                 case 'L':\r
1663                         node_print_desc = LID_ONLY;\r
1664                         break;\r
1665                 case 'l':\r
1666                         node_print_desc = UNIQUE_LID_ONLY;\r
1667                         break;\r
1668                 case 'G':\r
1669                         node_print_desc = GUID_ONLY;\r
1670                         break;\r
1671                 case 'O':\r
1672                         node_print_desc = NAME_OF_LID;\r
1673                         break;\r
1674                 case 'U':\r
1675                         node_print_desc = NAME_OF_GUID;\r
1676                         break;\r
1677                 case 's':\r
1678                         query_type = IB_MAD_ATTR_PORTINFO_RECORD;\r
1679                         break;\r
1680                 case 'g':\r
1681                         query_type = IB_MAD_ATTR_MCMEMBER_RECORD;\r
1682                         break;\r
1683                 case 'm':\r
1684                         query_type = IB_MAD_ATTR_MCMEMBER_RECORD;\r
1685                         members = 1;\r
1686                         break;\r
1687                 case 'x':\r
1688                         query_type = IB_MAD_ATTR_LINK_RECORD;\r
1689                         break;\r
1690                 case 'd':\r
1691                         osm_debug = 1;\r
1692                         break;\r
1693                 case 'C':\r
1694                         sa_hca_name = optarg;\r
1695                         break;\r
1696                 case 'P':\r
1697                         sa_port_num = strtoul(optarg, NULL, 0);\r
1698                         break;\r
1699                 case 't':\r
1700                         sa_timeout_ms = strtoul(optarg, NULL, 0);\r
1701                         break;\r
1702                 case 'h':\r
1703                 default:\r
1704                         usage();\r
1705                 }\r
1706         }\r
1707         argc -= optind;\r
1708         argv += optind;\r
1709 \r
1710         if (!query_type) {\r
1711                 if (!argc || !(q = find_query(argv[0])))\r
1712                         query_type = IB_MAD_ATTR_NODE_RECORD;\r
1713                 else {\r
1714                         query_type = q->query_type;\r
1715                         argc--;\r
1716                         argv++;\r
1717                 }\r
1718         }\r
1719 \r
1720         if (argc) {\r
1721                 if (node_print_desc == NAME_OF_LID) {\r
1722                         requested_lid = (ib_net16_t)strtoul(argv[0], NULL, 0);\r
1723                         requested_lid_flag++;\r
1724                 } else if (node_print_desc == NAME_OF_GUID) {\r
1725                         requested_guid = (ib_net64_t)strtoul(argv[0], NULL, 0);\r
1726                         requested_guid_flag++;\r
1727                 } else {\r
1728                         requested_name = argv[0];\r
1729                 }\r
1730         }\r
1731 \r
1732         if ((node_print_desc == LID_ONLY ||\r
1733              node_print_desc == UNIQUE_LID_ONLY ||\r
1734              node_print_desc == GUID_ONLY) &&\r
1735              !requested_name) {\r
1736                 fprintf(stderr, "ERROR: name not specified\n");\r
1737                 usage();\r
1738         }\r
1739 \r
1740         if (node_print_desc == NAME_OF_LID && !requested_lid_flag) {\r
1741                 fprintf(stderr, "ERROR: lid not specified\n");\r
1742                 usage();\r
1743         }\r
1744 \r
1745         if (node_print_desc == NAME_OF_GUID && !requested_guid_flag) {\r
1746                 fprintf(stderr, "ERROR: guid not specified\n");\r
1747                 usage();\r
1748         }\r
1749 \r
1750         /* Note: lid cannot be 0; see infiniband spec 4.1.3 */\r
1751         if (node_print_desc == NAME_OF_LID && !requested_lid) {\r
1752                 fprintf(stderr, "ERROR: lid invalid\n");\r
1753                 usage();\r
1754         }\r
1755 \r
1756         bind_handle = get_bind_handle();\r
1757         node_name_map = open_node_name_map(node_name_map_file);\r
1758 \r
1759         switch (query_type) {\r
1760         case IB_MAD_ATTR_NODE_RECORD:\r
1761                 status = print_node_records(bind_handle);\r
1762                 break;\r
1763         case IB_MAD_ATTR_PATH_RECORD:\r
1764                 if (src && dst) {\r
1765                         src_lid = get_lid(bind_handle, src);\r
1766                         dst_lid = get_lid(bind_handle, dst);\r
1767                         printf("Path record for %s -> %s\n", src, dst);\r
1768                         if (src_lid == 0 || dst_lid == 0) {\r
1769                                 status = IB_UNKNOWN_ERROR;\r
1770                         } else {\r
1771                                 status = get_print_path_rec_lid(bind_handle, src_lid, dst_lid);\r
1772                         }\r
1773                 } else if (sgid && dgid) {\r
1774                         struct in6_addr src_addr, dst_addr;\r
1775 \r
1776                         if (inet_pton(AF_INET6, sgid, &src_addr) <= 0) {\r
1777                                 fprintf(stderr, "invalid src gid: %s\n", sgid);\r
1778                                 exit(-1);\r
1779                         }\r
1780                         if (inet_pton(AF_INET6, dgid, &dst_addr) <= 0) {\r
1781                                 fprintf(stderr, "invalid dst gid: %s\n", dgid);\r
1782                                 exit(-1);\r
1783                         }\r
1784                         status = get_print_path_rec_gid(\r
1785                                 bind_handle,\r
1786                                 (ib_gid_t *) &src_addr.s6_addr,\r
1787                                 (ib_gid_t *) &dst_addr.s6_addr);\r
1788                 } else {\r
1789                         status = print_path_records(bind_handle);\r
1790                 }\r
1791                 break;\r
1792         case IB_MAD_ATTR_CLASS_PORT_INFO:\r
1793                 status = get_print_class_port_info(bind_handle);\r
1794                 break;\r
1795         case IB_MAD_ATTR_PORTINFO_RECORD:\r
1796                 status = print_portinfo_records(bind_handle);\r
1797                 break;\r
1798         case IB_MAD_ATTR_MCMEMBER_RECORD:\r
1799                 if (members)\r
1800                         status = print_multicast_member_records(bind_handle);\r
1801                 else\r
1802                         status = print_multicast_group_records(bind_handle);\r
1803                 break;\r
1804         case IB_MAD_ATTR_SERVICE_RECORD:\r
1805                 status = print_service_records(bind_handle);\r
1806                 break;\r
1807         case IB_MAD_ATTR_INFORM_INFO_RECORD:\r
1808                 status = print_inform_info_records(bind_handle);\r
1809                 break;\r
1810         case IB_MAD_ATTR_LINK_RECORD:\r
1811                 status = print_link_records(bind_handle, argc, argv);\r
1812                 break;\r
1813         default:\r
1814                 if (q && q->handler)\r
1815                         status = q->handler(q, bind_handle, argc, argv);\r
1816                 else {\r
1817                         fprintf(stderr, "Unknown query type %d\n", query_type);\r
1818                         status = IB_UNKNOWN_ERROR;\r
1819                 }\r
1820                 break;\r
1821         }\r
1822 \r
1823         if (src)\r
1824                 free(src);\r
1825         if (dst)\r
1826                 free(dst);\r
1827         clean_up();\r
1828         close_node_name_map(node_name_map);\r
1829         return (status);\r
1830 }\r