1 martin 1.14 //%LICENSE////////////////////////////////////////////////////////////////
|
2 martin 1.15 //
|
3 martin 1.14 // Licensed to The Open Group (TOG) under one or more contributor license
4 // agreements. Refer to the OpenPegasusNOTICE.txt file distributed with
5 // this work for additional information regarding copyright ownership.
6 // Each contributor licenses this file to you under the OpenPegasus Open
7 // Source License; you may not use this file except in compliance with the
8 // License.
|
9 martin 1.15 //
|
10 martin 1.14 // Permission is hereby granted, free of charge, to any person obtaining a
11 // copy of this software and associated documentation files (the "Software"),
12 // to deal in the Software without restriction, including without limitation
13 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
14 // and/or sell copies of the Software, and to permit persons to whom the
15 // Software is furnished to do so, subject to the following conditions:
|
16 martin 1.15 //
|
17 martin 1.14 // The above copyright notice and this permission notice shall be included
18 // in all copies or substantial portions of the Software.
|
19 martin 1.15 //
|
20 martin 1.14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
21 martin 1.15 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
22 martin 1.14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23 // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
24 // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25 // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26 // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
27 martin 1.15 //
|
28 martin 1.14 //////////////////////////////////////////////////////////////////////////
|
29 tony 1.1 //
30 //%/////////////////////////////////////////////////////////////////////////////
31
32 #include "PegasusSLPWrapper.h"
33
34 PEGASUS_NAMESPACE_BEGIN
35
|
36 kumpf 1.10 static void _extractAttributes(
37 const String &attrList,
38 Array<Attribute> &attrArray)
|
39 tony 1.2 {
|
40 kumpf 1.10 Uint32 posAttrKey=0, posEqual=0;
|
41 tony 1.2
|
42 kumpf 1.10 posAttrKey = attrList.find(PEG_SLP_ATTR_BEGIN);
43 while (posAttrKey != PEG_NOT_FOUND && (posAttrKey+1) < attrList.size())
|
44 tony 1.2 {
|
45 kumpf 1.10 posEqual = attrList.find(posEqual+1, PEG_SLP_ATTR_END);
46 String attrKey(
47 attrList.subString((posAttrKey+1), (posEqual-posAttrKey-1)));
|
48 tony 1.2
|
49 kumpf 1.10 attrArray.append(Attribute(attrKey));
50
51 // ATTN: skip over anything in value that is a '(', '=', ')', or ','?
52 posAttrKey = attrList.find(posAttrKey+1, PEG_SLP_ATTR_BEGIN);
|
53 tony 1.2 }
54 }
55
|
56 tony 1.1 CIMServerDiscoveryRep::CIMServerDiscoveryRep()
57 {
58 }
59
60 CIMServerDiscoveryRep::~CIMServerDiscoveryRep()
61 {
62 }
63
|
64 kumpf 1.10 /**
65 PegasusSLP supports return of attributes piggybacked on the srvReply,
66 other implementations may not
|
67 david.dillard 1.4 */
|
68 kumpf 1.10 static BOOL _lookup_attrs(
69 const String &save_url,
70 Array<Attribute>& attribs,
71 const SLPClientOptions* options)
|
72 david.dillard 1.4 {
73 struct slp_client *client = NULL;
74 lslpMsg responses, *attrReplyEntry;
|
75 kumpf 1.10
|
76 david.dillard 1.8 const char *scopes;
77 const char *spi;
78 char *iface;
79 char *addr;
80 const char *type;
81 const char *predicate;
|
82 david.dillard 1.4 int16 port;
83 BOOL dir_agent;
|
84 kumpf 1.10
|
85 david.dillard 1.8 char* tags = (char*)NULL;
|
86 david.dillard 1.4 int16 converge=(int16)0;
|
87 kumpf 1.10 if (0==save_url.size())
88 {
|
89 david.dillard 1.4 /* Pilot error */
90 return FALSE;
91 }
92
93 char* url=strdup((const char*)save_url.getCString());
94 if (url == NULL)
95 {
96 return FALSE;
97 }
98
|
99 kumpf 1.10 if ((SLPClientOptions*)NULL == options)
100 {
|
101 david.dillard 1.4 addr = NULL;
102 iface = NULL;
103 port = 427;
104 scopes = "DEFAULT";
105 spi="DSA";
106 type = "service:wbem";
107 predicate = NULL;
108 dir_agent = FALSE;
|
109 kumpf 1.10 }
110 else
111 {
|
112 david.dillard 1.4 scopes = (char*)options->scopes;
113 spi = (char*)options->spi;
114 iface = options->local_interface;
115 addr = options->target_address;
116 type = options->service_type;
117 predicate = options->predicate;
118 port = options->target_port;
119 dir_agent = options->use_directory_agent==true?1:0;
120 }
121 /* largely cut-and-paste from slp_attrreq.cpp
122 * with gratuitous reformatting
123 */
|
124 kumpf 1.10 if (NULL != (client = create_slp_client(
|
125 david.dillard 1.4 addr,
126 iface,
127 port,
128 spi,
129 scopes,
|
130 kumpf 1.10 FALSE,
|
131 venkat.puvvada 1.12 dir_agent,
132 0 // Service type, we are not SA.
133 )))
|
134 kumpf 1.10 {
|
135 venkat.puvvada 1.12 if (slp_is_loop_back_addr(addr))
|
136 kumpf 1.10 {
|
137 david.dillard 1.4 client->local_attr_req(client, url, scopes, tags);
|
138 kumpf 1.10 }
139 else if (converge)
140 {
|
141 david.dillard 1.4 client->_convergence = converge ;
142 client->converge_attr_req(client, url, scopes, tags);
|
143 kumpf 1.10 }
144 else
145 {
|
146 venkat.puvvada 1.12 if (!addr)
|
147 kumpf 1.10 {
|
148 venkat.puvvada 1.12 client->converge_attr_req(client, url, scopes, tags);
|
149 kumpf 1.10 }
150 else
151 {
|
152 venkat.puvvada 1.12 #ifdef PEGASUS_ENABLE_IPV6
153 SOCKADDR_IN6 ip6;
|
154 kumpf 1.16 #endif
|
155 venkat.puvvada 1.12 SOCKADDR_IN ip4;
156 void *target = 0;
157
158 if (slp_is_valid_ip4_addr(addr))
159 {
160 ip4.sin_port = htons(port);
161 ip4.sin_family = AF_INET;
162 ip4.sin_addr.s_addr = inet_addr(addr);
163 target = &ip4;
164 }
165 #ifdef PEGASUS_ENABLE_IPV6
166 else
167 {
168 memset(&ip6, 0, sizeof(ip6));
169 ip6.sin6_port = htons(port);
170 ip6.sin6_family = AF_INET6;
171 slp_pton(AF_INET6, addr, &ip6.sin6_addr);
172 target = &ip6;
173 }
174 #endif
175 if(target)
176 venkat.puvvada 1.12 {
177 client->unicast_attr_req(
178 client,
179 url,
180 scopes,
181 tags,
182 (SOCKADDR*)target);
183 }
|
184 david.dillard 1.4 }
|
185 venkat.puvvada 1.12 }
|
186 david.dillard 1.4
187 responses.isHead = TRUE;
188 responses.next = responses.prev = &responses;
189
190 client->get_response(client, &responses);
|
191 kumpf 1.10 while (!_LSLP_IS_EMPTY(&responses))
192 {
|
193 david.dillard 1.4 attrReplyEntry = responses.next;
|
194 kumpf 1.10 if (attrReplyEntry->type == attrRep)
195 {
196 if (attrReplyEntry->msg.attrRep.attrListLen > 0)
197 {
|
198 david.dillard 1.4 String attrString = attrReplyEntry->msg.attrRep.attrList;
199 _extractAttributes(attrString,attribs);
200 }
|
201 kumpf 1.10 } /* if we got an attr reply */
|
202 david.dillard 1.4 _LSLP_UNLINK(attrReplyEntry);
203 lslpDestroySLPMsg(attrReplyEntry, LSLP_DESTRUCTOR_DYNAMIC);
|
204 kumpf 1.10 } /* while traversing response list */
|
205 david.dillard 1.4
206 destroy_slp_client(client);
207
|
208 kumpf 1.10 } /* client successfully created */
|
209 david.dillard 1.4
210 free(url);
211 return TRUE;
|
212 kumpf 1.10 } /*static BOOL _lookup_attrs()*/
|
213 david.dillard 1.4
|
214 kumpf 1.10 Array<CIMServerDescription> CIMServerDiscoveryRep::lookup(
215 const Array<Attribute>& criteria,
216 const SLPClientOptions* options)
|
217 tony 1.1 {
|
218 kumpf 1.10 struct slp_client *client = NULL;
219 lslpMsg responses, *srvReplyEntry;
220
221 const char *scopes; // = strdup("DEFAULT");
222 const char *spi; // = strdup("DSA");
223 char *iface; // = NULL;
224 char *addr; // = NULL;
225 const char *type; // = strdup("service:wbem");
226 const char *predicate; // = NULL;
227 int16 port; // = 427;
228 BOOL dir_agent; // = FALSE;
|
229 venkat.puvvada 1.12 int converge = 0; // Converge cycles.
|
230 kumpf 1.10
231 if ((SLPClientOptions*)NULL == options)
232 {
233 addr = NULL;
234 iface = NULL;
235 port = 427;
236 scopes = "DEFAULT";
237 spi="DSA";
238 type = "service:wbem";
239 predicate = NULL;
240 dir_agent = FALSE;
241 }
242 else
|
243 tony 1.1 {
|
244 kumpf 1.10 scopes = (char*)options->scopes;
245 spi = (char*)options->spi;
246 iface = options->local_interface;
247 addr = options->target_address;
248 type = options->service_type;
249 predicate = options->predicate;
250 port = options->target_port;
251 dir_agent = options->use_directory_agent==true?1:0;
252 options->print();
253 }
254 Array<CIMServerDescription> connections;
255
256 if (NULL != (client = create_slp_client(
257 addr, // target_addr
258 iface, // local_interface
259 port, // target_port
260 spi, // spi
261 scopes, // scopes
262 FALSE, // should_listen
|
263 venkat.puvvada 1.12 dir_agent,// use_das
264 0 // Service type , we are not SA.
|
265 kumpf 1.10 )))
266 {
|
267 venkat.puvvada 1.12 if (slp_is_loop_back_addr(addr))
|
268 tony 1.1 {
|
269 kumpf 1.10 client->local_srv_req(client, type, predicate, scopes);
|
270 tony 1.1 }
|
271 venkat.puvvada 1.12 else if (converge)
272 {
273 client->_convergence = converge ;
274 client->converge_srv_req(client, type, predicate, scopes);
275 }
|
276 kumpf 1.10 else
|
277 tony 1.1 {
|
278 venkat.puvvada 1.12 if (!addr)
|
279 kumpf 1.10 {
|
280 venkat.puvvada 1.12 client->converge_srv_req(client, type, predicate, scopes);
|
281 kumpf 1.10 }
282 else
283 {
|
284 venkat.puvvada 1.12 #ifdef PEGASUS_ENABLE_IPV6
285 SOCKADDR_IN6 ip6;
286 #endif
287 SOCKADDR_IN ip4;
288 void *target = 0;
289
290 if (slp_is_valid_ip4_addr(addr))
291 {
292 ip4.sin_port = htons(port);
293 ip4.sin_family = AF_INET;
294 ip4.sin_addr.s_addr = inet_addr(addr);
295 target = &ip4;
296 }
297 #ifdef PEGASUS_ENABLE_IPV6
298 else
299 {
300 memset(&ip6, 0, sizeof(ip6));
301 ip6.sin6_port = htons(port);
302 ip6.sin6_family = AF_INET6;
303 slp_pton(AF_INET6, addr, &ip6.sin6_addr);
304 target = &ip6;
305 venkat.puvvada 1.12 }
306 #endif
307 if(target)
308 {
309 client->unicast_srv_req(
310 client,
311 type,
312 predicate,
313 scopes,
314 (SOCKADDR*)target);
315 }
|
316 kumpf 1.10 }
|
317 tony 1.1 }
318
|
319 kumpf 1.10 responses.isHead = TRUE;
320 responses.next = responses.prev = &responses;
321
322 client->get_response(client, &responses);
323 while (!_LSLP_IS_EMPTY(&responses))
324 {
325 srvReplyEntry = responses.next;
|
326 dmitry.mikulin 1.13 if (srvReplyEntry != NULL)
|
327 tony 1.1 {
|
328 kumpf 1.10 lslpURL *url_list;
|
329 dmitry.mikulin 1.13 if (srvReplyEntry->type == srvRply)
|
330 tony 1.1 {
|
331 kumpf 1.10 if ((NULL != srvReplyEntry->msg.srvRply.urlList) &&
332 (!_LSLP_IS_EMPTY( srvReplyEntry->msg.srvRply.urlList)))
|
333 tony 1.1 {
|
334 kumpf 1.10 url_list = srvReplyEntry->msg.srvRply.urlList->next;
335 while (!_LSLP_IS_HEAD(url_list))
|
336 tony 1.1 {
|
337 kumpf 1.10 /* check for urls */
338 if (NULL != url_list->url)
|
339 tony 1.1 {
|
340 kumpf 1.10 CIMServerDescription connection(url_list->url);
|
341 tony 1.1
|
342 kumpf 1.10 Array<Attribute> attributes;
|
343 david.dillard 1.4
|
344 kumpf 1.10 /* check for attributes */
345 /* PegasusSLP reurns attributes with srvReply
346 * per RFC 3059. Other implementations do not.
347 */
348 if (NULL != url_list->attrs &&
349 !_LSLP_IS_HEAD(url_list->attrs->next))
|
350 tony 1.1 {
|
351 kumpf 1.10 lslpAtomList *attrs = url_list->attrs->next;
352 while (!_LSLP_IS_HEAD(attrs))
|
353 tony 1.1 {
|
354 kumpf 1.10 _extractAttributes(
355 String(attrs->str), attributes);
356 attrs = attrs->next;
|
357 tony 1.1 }
|
358 david.dillard 1.4 }/*if attrs*/
|
359 kumpf 1.10 /* add to connections array */
360 /* VRTS - interop. Add unconditionally.
361 * Not initialised in contsructor */
362 connection.setAttributes(attributes);
363 connections.append(connection);
|
364 david.dillard 1.4 }/*if url*/
|
365 kumpf 1.10 url_list = url_list->next;
|
366 david.dillard 1.4 }/*while we have urls*/
367 }/*if urlList*/
|
368 dmitry.mikulin 1.13 }/*if srvReplyEntry->type == srvRply*/
369 _LSLP_UNLINK(srvReplyEntry);
370 lslpDestroySLPMsg(srvReplyEntry, LSLP_DESTRUCTOR_DYNAMIC);
371 }/*if srvReplyEntry != NULL*/
|
372 david.dillard 1.4 }/*while*/
|
373 kumpf 1.10 destroy_slp_client(client);
|
374 david.dillard 1.4 }
|
375 tony 1.2
|
376 david.dillard 1.4 /* If no attributes were present, then the attributes array
|
377 kumpf 1.10 * has zero size. Rescan the connections and create a fresh slp_client to
|
378 david.dillard 1.4 * get the attributes, if none present
379 */
|
380 kumpf 1.10 if (0==connections.size())
381 {
382 return connections;
|
383 david.dillard 1.4 }
|
384 kumpf 1.10
|
385 dave.sudlik 1.11 for (Uint32 i=0; i < connections.size(); i++)
|
386 kumpf 1.10 {
|
387 david.dillard 1.4 Array<Attribute> attrs = connections[i].getAttributes();
|
388 kumpf 1.10 if (0 == attrs.size())
389 {
390 String url = connections[i].getUrl();
391 if (TRUE == _lookup_attrs(url, attrs, options))
392 {
|
393 david.dillard 1.4 connections[i].setAttributes(attrs);
|
394 tony 1.1 }
395 }
396 }
397
|
398 kumpf 1.10 return connections;
|
399 tony 1.1 }
400
401 PEGASUS_NAMESPACE_END
|