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