infiniband-diags: initial port of linux ib diags
[mirror/winof/.git] / tools / infiniband_diags / src / ibaddr.c
1 /*\r
2  * Copyright (c) 2004-2008 Voltaire Inc.  All rights reserved.\r
3  *\r
4  * This software is available to you under a choice of one of two\r
5  * licenses.  You may choose to be licensed under the terms of the GNU\r
6  * General Public License (GPL) Version 2, available from the file\r
7  * COPYING in the main directory of this source tree, or the\r
8  * OpenIB.org BSD license below:\r
9  *\r
10  *     Redistribution and use in source and binary forms, with or\r
11  *     without modification, are permitted provided that the following\r
12  *     conditions are met:\r
13  *\r
14  *      - Redistributions of source code must retain the above\r
15  *        copyright notice, this list of conditions and the following\r
16  *        disclaimer.\r
17  *\r
18  *      - Redistributions in binary form must reproduce the above\r
19  *        copyright notice, this list of conditions and the following\r
20  *        disclaimer in the documentation and/or other materials\r
21  *        provided with the distribution.\r
22  *\r
23  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
24  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
25  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
26  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
27  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
28  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
29  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
30  * SOFTWARE.\r
31  *\r
32  */\r
33 \r
34 #if HAVE_CONFIG_H\r
35 #  include <config.h>\r
36 #endif /* HAVE_CONFIG_H */\r
37 \r
38 #include <stdio.h>\r
39 #include <stdlib.h>\r
40 #if defined(_WIN32) \r
41 #include <windows.h>\r
42 #include <winsock2.h>\r
43 #include <ws2tcpip.h> \r
44 #include "..\..\..\..\etc\user\getopt.c"\r
45 #else\r
46 #include <unistd.h>\r
47 #include <stdarg.h>\r
48 #include <getopt.h>\r
49 #include <arpa/inet.h>\r
50 #endif\r
51 \r
52 #include <infiniband/umad.h>\r
53 #include <infiniband/mad.h>\r
54 \r
55 #include "ibdiag_common.h"\r
56 \r
57 char *argv0 = "ibaddr";\r
58 \r
59 static int\r
60 ib_resolve_addr(ib_portid_t *portid, int portnum, int show_lid, int show_gid)\r
61 {\r
62         char   gid_str[INET6_ADDRSTRLEN];\r
63         uint8_t portinfo[64];\r
64         uint8_t nodeinfo[64];\r
65         uint64_t guid, prefix;\r
66         ibmad_gid_t gid;\r
67         int lmc;\r
68 \r
69         if (!smp_query(nodeinfo, portid, IB_ATTR_NODE_INFO, 0, 0))\r
70                 return -1;\r
71 \r
72         if (!smp_query(portinfo, portid, IB_ATTR_PORT_INFO, portnum, 0))\r
73                 return -1;\r
74 \r
75         mad_decode_field(portinfo, IB_PORT_LID_F, &portid->lid);\r
76         mad_decode_field(portinfo, IB_PORT_GID_PREFIX_F, &prefix);\r
77         mad_decode_field(portinfo, IB_PORT_LMC_F, &lmc);\r
78         mad_decode_field(nodeinfo, IB_NODE_PORT_GUID_F, &guid);\r
79 \r
80         mad_encode_field(gid, IB_GID_PREFIX_F, &prefix);\r
81         mad_encode_field(gid, IB_GID_GUID_F, &guid);\r
82 \r
83         if (show_gid) {\r
84                 printf("GID %s ", inet_ntop(AF_INET6, gid, gid_str,\r
85                         sizeof gid_str));\r
86         }\r
87 \r
88         if (show_lid > 0)\r
89                 printf("LID start 0x%x end 0x%x", portid->lid, portid->lid + (1 << lmc) - 1);\r
90         else if (show_lid < 0)\r
91                 printf("LID start %d end %d", portid->lid, portid->lid + (1 << lmc) - 1);\r
92         printf("\n");\r
93         return 0;\r
94 }\r
95 \r
96 static void\r
97 usage(void)\r
98 {\r
99         char *basename;\r
100 \r
101         if (!(basename = strrchr(argv0, '/')))\r
102                 basename = argv0;\r
103         else\r
104                 basename++;\r
105 \r
106         fprintf(stderr, "Usage: %s [-d(ebug) -D(irect) -G(uid) -l(id_show) -g(id_show) -s(m_port) sm_lid -C ca_name -P ca_port "\r
107                         "-t(imeout) timeout_ms -V(ersion) -h(elp)] [<lid|dr_path|guid>]\n",\r
108                         basename);\r
109         fprintf(stderr, "\tExamples:\n");\r
110         fprintf(stderr, "\t\t%s\t\t\t# local port's address\n", basename);\r
111         fprintf(stderr, "\t\t%s 32\t\t# show lid range and gid of lid 32\n", basename);\r
112         fprintf(stderr, "\t\t%s -G 0x8f1040023\t# same but using guid address\n", basename);\r
113         fprintf(stderr, "\t\t%s -l 32\t\t# show lid range only\n", basename);\r
114         fprintf(stderr, "\t\t%s -L 32\t\t# show decimal lid range only\n", basename);\r
115         fprintf(stderr, "\t\t%s -g 32\t\t# show gid address only\n", basename);\r
116         exit(-1);\r
117 }\r
118 \r
119 int __cdecl\r
120 main(int argc, char **argv)\r
121 {\r
122         int mgmt_classes[3] = {IB_SMI_CLASS, IB_SMI_DIRECT_CLASS, IB_SA_CLASS};\r
123         ib_portid_t *sm_id = 0, sm_portid = {0};\r
124         ib_portid_t portid = {0};\r
125         extern int ibdebug;\r
126         int dest_type = IB_DEST_LID;\r
127         int timeout = 0;        /* use default */\r
128         int show_lid = 0, show_gid = 0;\r
129         int port = 0;\r
130         char *ca = 0;\r
131         int ca_port = 0;\r
132 \r
133         static char str_opts[] = "C:P:t:s:dDGglLVhu";\r
134         static struct option long_opts[] = {\r
135                 { "C", 1, 0, 'C'},\r
136                 { "P", 1, 0, 'P'},\r
137                 { "debug", 0, 0, 'd'},\r
138                 { "Direct", 0, 0, 'D'},\r
139                 { "Guid", 0, 0, 'G'},\r
140                 { "gid_show", 0, 0, 'g'},\r
141                 { "lid_show", 0, 0, 'l'},\r
142                 { "Lid_show", 0, 0, 'L'},\r
143                 { "timeout", 1, 0, 't'},\r
144                 { "sm_port", 1, 0, 's'},\r
145                 { "Version", 0, 0, 'V'},\r
146                 { "help", 0, 0, 'h'},\r
147                 { "usage", 0, 0, 'u'},\r
148                 { 0 }\r
149         };\r
150 \r
151         argv0 = argv[0];\r
152 \r
153         while (1) {\r
154                 int ch = getopt_long(argc, argv, str_opts, long_opts, NULL);\r
155                 if ( ch == -1 )\r
156                         break;\r
157                 switch(ch) {\r
158                 case 'C':\r
159                         ca = optarg;\r
160                         break;\r
161                 case 'P':\r
162                         ca_port = strtoul(optarg, 0, 0);\r
163                         break;\r
164                 case 'd':\r
165                         ibdebug++;\r
166                         break;\r
167                 case 'D':\r
168                         dest_type = IB_DEST_DRPATH;\r
169                         break;\r
170                 case 'g':\r
171                         show_gid++;\r
172                         break;\r
173                 case 'G':\r
174                         dest_type = IB_DEST_GUID;\r
175                         break;\r
176                 case 'l':\r
177                         show_lid++;\r
178                         break;\r
179                 case 'L':\r
180                         show_lid = -100;\r
181                         break;\r
182                 case 's':\r
183                         if (ib_resolve_portid_str(&sm_portid, optarg, IB_DEST_LID, 0) < 0)\r
184                                 IBERROR("can't resolve SM destination port %s", optarg);\r
185                         sm_id = &sm_portid;\r
186                         break;\r
187                 case 't':\r
188                         timeout = strtoul(optarg, 0, 0);\r
189                         madrpc_set_timeout(timeout);\r
190                         break;\r
191                 case 'V':\r
192                         fprintf(stderr, "%s %s\n", argv0, get_build_version() );\r
193                         exit(-1);\r
194                 default:\r
195                         usage();\r
196                         break;\r
197                 }\r
198         }\r
199         argc -= optind;\r
200         argv += optind;\r
201 \r
202         if (argc > 1)\r
203                 port = strtoul(argv[1], 0, 0);\r
204 \r
205         if (!show_lid && !show_gid)\r
206                 show_lid = show_gid = 1;\r
207 \r
208         madrpc_init(ca, ca_port, mgmt_classes, 3);\r
209 \r
210         if (argc) {\r
211                 if (ib_resolve_portid_str(&portid, argv[0], dest_type, sm_id) < 0)\r
212                         IBERROR("can't resolve destination port %s", argv[0]);\r
213         } else {\r
214                 if (ib_resolve_self(&portid, &port, 0) < 0)\r
215                         IBERROR("can't resolve self port %s", argv[0]);\r
216         }\r
217 \r
218         if (ib_resolve_addr(&portid, port, show_lid, show_gid) < 0)\r
219                 IBERROR("can't resolve requested address");\r
220         exit(0);\r
221 }\r