ipmi_intf.c (0e99dafa12494c00a7d9d2a4a61585c989ea0d68) ipmi_intf.c (eb54136775f63a6a159f3c55ee4772d7aa363cc4)
1/*
2 * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * Redistribution of source code must retain the above copyright

--- 182 unchanged lines hidden (view full) ---

191 }
192
193 return NULL;
194}
195
196void
197ipmi_intf_session_set_hostname(struct ipmi_intf * intf, char * hostname)
198{
1/*
2 * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * Redistribution of source code must retain the above copyright

--- 182 unchanged lines hidden (view full) ---

191 }
192
193 return NULL;
194}
195
196void
197ipmi_intf_session_set_hostname(struct ipmi_intf * intf, char * hostname)
198{
199 if (intf->session == NULL || hostname == NULL) {
199 if (intf->ssn_params.hostname != NULL) {
200 free(intf->ssn_params.hostname);
201 intf->ssn_params.hostname = NULL;
202 }
203 if (hostname == NULL) {
200 return;
201 }
204 return;
205 }
202 if (intf->session->hostname != NULL) {
203 free(intf->session->hostname);
204 intf->session->hostname = NULL;
205 }
206 intf->session->hostname = strdup(hostname);
206 intf->ssn_params.hostname = strdup(hostname);
207}
208
209void
210ipmi_intf_session_set_username(struct ipmi_intf * intf, char * username)
211{
207}
208
209void
210ipmi_intf_session_set_username(struct ipmi_intf * intf, char * username)
211{
212 if (intf->session == NULL)
213 return;
212 memset(intf->ssn_params.username, 0, 17);
214
213
215 memset(intf->session->username, 0, 17);
216
217 if (username == NULL)
218 return;
219
214 if (username == NULL)
215 return;
216
220 memcpy(intf->session->username, username, __min(strlen(username), 16));
217 memcpy(intf->ssn_params.username, username, __min(strlen(username), 16));
221}
222
223void
224ipmi_intf_session_set_password(struct ipmi_intf * intf, char * password)
225{
218}
219
220void
221ipmi_intf_session_set_password(struct ipmi_intf * intf, char * password)
222{
226 if (intf->session == NULL)
227 return;
223 memset(intf->ssn_params.authcode_set, 0, IPMI_AUTHCODE_BUFFER_SIZE);
228
224
229 memset(intf->session->authcode, 0, IPMI_AUTHCODE_BUFFER_SIZE);
230
231 if (password == NULL) {
225 if (password == NULL) {
232 intf->session->password = 0;
226 intf->ssn_params.password = 0;
233 return;
234 }
235
227 return;
228 }
229
236 intf->session->password = 1;
237 memcpy(intf->session->authcode, password,
230 intf->ssn_params.password = 1;
231 memcpy(intf->ssn_params.authcode_set, password,
238 __min(strlen(password), IPMI_AUTHCODE_BUFFER_SIZE));
239}
240
241void
242ipmi_intf_session_set_privlvl(struct ipmi_intf * intf, uint8_t level)
243{
232 __min(strlen(password), IPMI_AUTHCODE_BUFFER_SIZE));
233}
234
235void
236ipmi_intf_session_set_privlvl(struct ipmi_intf * intf, uint8_t level)
237{
244 if (intf->session == NULL)
245 return;
246
247 intf->session->privlvl = level;
238 intf->ssn_params.privlvl = level;
248}
249
250void
251ipmi_intf_session_set_lookupbit(struct ipmi_intf * intf, uint8_t lookupbit)
252{
239}
240
241void
242ipmi_intf_session_set_lookupbit(struct ipmi_intf * intf, uint8_t lookupbit)
243{
253 if (intf->session == NULL)
254 return;
255
256 intf->session->v2_data.lookupbit = lookupbit;
244 intf->ssn_params.lookupbit = lookupbit;
257}
258
259void
260ipmi_intf_session_set_cipher_suite_id(struct ipmi_intf * intf, uint8_t cipher_suite_id)
261{
245}
246
247void
248ipmi_intf_session_set_cipher_suite_id(struct ipmi_intf * intf, uint8_t cipher_suite_id)
249{
262 if (intf->session == NULL)
263 return;
264
265 intf->session->cipher_suite_id = cipher_suite_id;
250 intf->ssn_params.cipher_suite_id = cipher_suite_id;
266}
267
268void
269ipmi_intf_session_set_sol_escape_char(struct ipmi_intf * intf, char sol_escape_char)
270{
251}
252
253void
254ipmi_intf_session_set_sol_escape_char(struct ipmi_intf * intf, char sol_escape_char)
255{
271 if (intf->session == NULL)
272 return;
273
274 intf->session->sol_escape_char = sol_escape_char;
256 intf->ssn_params.sol_escape_char = sol_escape_char;
275}
276
277void
278ipmi_intf_session_set_kgkey(struct ipmi_intf * intf, char * kgkey)
279{
257}
258
259void
260ipmi_intf_session_set_kgkey(struct ipmi_intf * intf, char * kgkey)
261{
280 if (intf->session == NULL)
281 return;
262 memset(intf->ssn_params.kg, 0, IPMI_KG_BUFFER_SIZE);
282
263
283 memset(intf->session->v2_data.kg, 0, IPMI_KG_BUFFER_SIZE);
284
285 if (kgkey == NULL)
286 return;
287
264 if (kgkey == NULL)
265 return;
266
288 memcpy(intf->session->v2_data.kg, kgkey,
267 memcpy(intf->ssn_params.kg, kgkey,
289 __min(strlen(kgkey), IPMI_KG_BUFFER_SIZE));
290}
291
292void
293ipmi_intf_session_set_port(struct ipmi_intf * intf, int port)
294{
268 __min(strlen(kgkey), IPMI_KG_BUFFER_SIZE));
269}
270
271void
272ipmi_intf_session_set_port(struct ipmi_intf * intf, int port)
273{
295 if (intf->session == NULL)
296 return;
297
298 intf->session->port = port;
274 intf->ssn_params.port = port;
299}
300
301void
302ipmi_intf_session_set_authtype(struct ipmi_intf * intf, uint8_t authtype)
303{
275}
276
277void
278ipmi_intf_session_set_authtype(struct ipmi_intf * intf, uint8_t authtype)
279{
304 if (intf->session == NULL)
305 return;
306
307 /* clear password field if authtype NONE specified */
308 if (authtype == IPMI_SESSION_AUTHTYPE_NONE) {
280 /* clear password field if authtype NONE specified */
281 if (authtype == IPMI_SESSION_AUTHTYPE_NONE) {
309 memset(intf->session->authcode, 0, IPMI_AUTHCODE_BUFFER_SIZE);
310 intf->session->password = 0;
282 memset(intf->ssn_params.authcode_set, 0, IPMI_AUTHCODE_BUFFER_SIZE);
283 intf->ssn_params.password = 0;
311 }
312
284 }
285
313 intf->session->authtype_set = authtype;
286 intf->ssn_params.authtype_set = authtype;
314}
315
316void
317ipmi_intf_session_set_timeout(struct ipmi_intf * intf, uint32_t timeout)
318{
287}
288
289void
290ipmi_intf_session_set_timeout(struct ipmi_intf * intf, uint32_t timeout)
291{
319 if (intf->session == NULL)
320 return;
321
322 intf->session->timeout = timeout;
292 intf->ssn_params.timeout = timeout;
323}
324
325void
326ipmi_intf_session_set_retry(struct ipmi_intf * intf, int retry)
327{
293}
294
295void
296ipmi_intf_session_set_retry(struct ipmi_intf * intf, int retry)
297{
328 if (intf->session == NULL)
329 return;
330
331 intf->session->retry = retry;
298 intf->ssn_params.retry = retry;
332}
333
334void
335ipmi_intf_session_cleanup(struct ipmi_intf *intf)
336{
337 if (intf->session == NULL) {
338 return;
339 }
299}
300
301void
302ipmi_intf_session_cleanup(struct ipmi_intf *intf)
303{
304 if (intf->session == NULL) {
305 return;
306 }
340 if (intf->session->hostname != NULL) {
341 free(intf->session->hostname);
342 intf->session->hostname = NULL;
343 }
307
344 free(intf->session);
345 intf->session = NULL;
346}
347
348void
349ipmi_cleanup(struct ipmi_intf * intf)
350{
351 ipmi_sdr_list_empty(intf);
308 free(intf->session);
309 intf->session = NULL;
310}
311
312void
313ipmi_cleanup(struct ipmi_intf * intf)
314{
315 ipmi_sdr_list_empty(intf);
316 ipmi_intf_session_set_hostname(intf, NULL);
352}
353
354#if defined(IPMI_INTF_LAN) || defined (IPMI_INTF_LANPLUS)
355int
356ipmi_intf_socket_connect(struct ipmi_intf * intf)
357{
317}
318
319#if defined(IPMI_INTF_LAN) || defined (IPMI_INTF_LANPLUS)
320int
321ipmi_intf_socket_connect(struct ipmi_intf * intf)
322{
358 struct ipmi_session *session;
323 struct ipmi_session_params *params;
359
360 struct sockaddr_storage addr;
361 struct addrinfo hints;
362 struct addrinfo *rp0 = NULL, *rp;
363 char service[NI_MAXSERV];
364
324
325 struct sockaddr_storage addr;
326 struct addrinfo hints;
327 struct addrinfo *rp0 = NULL, *rp;
328 char service[NI_MAXSERV];
329
365 if (!intf || intf->session == NULL) {
330 if (!intf) {
366 return -1;
367 }
368
331 return -1;
332 }
333
369 session = intf->session;
334 params = &intf->ssn_params;
370
335
371 if (session->hostname == NULL || strlen((const char *)session->hostname) == 0) {
336 if (params->hostname == NULL || strlen((const char *)params->hostname) == 0) {
372 lprintf(LOG_ERR, "No hostname specified!");
373 return -1;
374 }
375
376 /* open port to BMC */
377 memset(&addr, 0, sizeof(addr));
378
337 lprintf(LOG_ERR, "No hostname specified!");
338 return -1;
339 }
340
341 /* open port to BMC */
342 memset(&addr, 0, sizeof(addr));
343
379 sprintf(service, "%d", session->port);
344 sprintf(service, "%d", params->port);
380 /* Obtain address(es) matching host/port */
381 memset(&hints, 0, sizeof(hints));
382 hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
383 hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */
384 hints.ai_flags = 0; /* use AI_NUMERICSERV for no name resolution */
385 hints.ai_protocol = IPPROTO_UDP; /* */
386
345 /* Obtain address(es) matching host/port */
346 memset(&hints, 0, sizeof(hints));
347 hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
348 hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */
349 hints.ai_flags = 0; /* use AI_NUMERICSERV for no name resolution */
350 hints.ai_protocol = IPPROTO_UDP; /* */
351
387 if (getaddrinfo(session->hostname, service, &hints, &rp0) != 0) {
352 if (getaddrinfo(params->hostname, service, &hints, &rp0) != 0) {
388 lprintf(LOG_ERR, "Address lookup for %s failed",
353 lprintf(LOG_ERR, "Address lookup for %s failed",
389 session->hostname);
354 params->hostname);
390 return -1;
391 }
392
393 /* getaddrinfo() returns a list of address structures.
394 * Try each address until we successfully connect(2).
395 * If socket(2) (or connect(2)) fails, we (close the socket
355 return -1;
356 }
357
358 /* getaddrinfo() returns a list of address structures.
359 * Try each address until we successfully connect(2).
360 * If socket(2) (or connect(2)) fails, we (close the socket
396 * and) try the next address.
361 * and) try the next address.
397 */
398
362 */
363
399 session->ai_family = AF_UNSPEC;
400 for (rp = rp0; rp != NULL; rp = rp->ai_next) {
401 /* We are only interested in IPv4 and IPv6 */
402 if ((rp->ai_family != AF_INET6) && (rp->ai_family != AF_INET)) {
403 continue;
404 }
405
406 intf->fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
407 if (intf->fd == -1) {
408 continue;
409 }
410
411 if (rp->ai_family == AF_INET) {
412 if (connect(intf->fd, rp->ai_addr, rp->ai_addrlen) != -1) {
364 for (rp = rp0; rp != NULL; rp = rp->ai_next) {
365 /* We are only interested in IPv4 and IPv6 */
366 if ((rp->ai_family != AF_INET6) && (rp->ai_family != AF_INET)) {
367 continue;
368 }
369
370 intf->fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
371 if (intf->fd == -1) {
372 continue;
373 }
374
375 if (rp->ai_family == AF_INET) {
376 if (connect(intf->fd, rp->ai_addr, rp->ai_addrlen) != -1) {
413 memcpy(&session->addr, rp->ai_addr, rp->ai_addrlen);
414 session->addrlen = rp->ai_addrlen;
415 session->ai_family = rp->ai_family;
377 hints.ai_family = rp->ai_family;
416 break; /* Success */
417 }
418 } else if (rp->ai_family == AF_INET6) {
419 struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)rp->ai_addr;
420 char hbuf[NI_MAXHOST];
421 socklen_t len;
422
423 /* The scope was specified on the command line e.g. with -H FE80::219:99FF:FEA0:BD95%eth0 */
424 if (addr6->sin6_scope_id != 0) {
425 len = sizeof(struct sockaddr_in6);
426 if (getnameinfo((struct sockaddr *)addr6, len, hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) == 0) {
378 break; /* Success */
379 }
380 } else if (rp->ai_family == AF_INET6) {
381 struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)rp->ai_addr;
382 char hbuf[NI_MAXHOST];
383 socklen_t len;
384
385 /* The scope was specified on the command line e.g. with -H FE80::219:99FF:FEA0:BD95%eth0 */
386 if (addr6->sin6_scope_id != 0) {
387 len = sizeof(struct sockaddr_in6);
388 if (getnameinfo((struct sockaddr *)addr6, len, hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) == 0) {
427 lprintf(LOG_DEBUG, "Trying address: %s scope=%d",
428 hbuf,
389 lprintf(LOG_DEBUG, "Trying address: %s scope=%d",
390 hbuf,
429 addr6->sin6_scope_id);
430 }
431 if (connect(intf->fd, rp->ai_addr, rp->ai_addrlen) != -1) {
391 addr6->sin6_scope_id);
392 }
393 if (connect(intf->fd, rp->ai_addr, rp->ai_addrlen) != -1) {
432 memcpy(&session->addr, rp->ai_addr, rp->ai_addrlen);
433 session->addrlen = rp->ai_addrlen;
434 session->ai_family = rp->ai_family;
394 hints.ai_family = rp->ai_family;
435 break; /* Success */
436 }
437 } else {
438 /* No scope specified, try to get this from the list of interfaces */
439 struct ifaddrs *ifaddrs = NULL;
440 struct ifaddrs *ifa = NULL;
441
442 if (getifaddrs(&ifaddrs) < 0) {
443 lprintf(LOG_ERR, "Interface address lookup for %s failed",
395 break; /* Success */
396 }
397 } else {
398 /* No scope specified, try to get this from the list of interfaces */
399 struct ifaddrs *ifaddrs = NULL;
400 struct ifaddrs *ifa = NULL;
401
402 if (getifaddrs(&ifaddrs) < 0) {
403 lprintf(LOG_ERR, "Interface address lookup for %s failed",
444 session->hostname);
404 params->hostname);
445 break;
446 }
447
448 for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) {
449 if (ifa->ifa_addr == NULL) {
450 continue;
451 }
452

--- 4 unchanged lines hidden (view full) ---

457 if (IN6_IS_ADDR_MULTICAST(&tmp6->sin6_addr)) {
458 continue;
459 }
460 if (IN6_IS_ADDR_LOOPBACK(&tmp6->sin6_addr)) {
461 continue;
462 }
463 len = sizeof(struct sockaddr_in6);
464 if ( getnameinfo((struct sockaddr *)tmp6, len, hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) == 0) {
405 break;
406 }
407
408 for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) {
409 if (ifa->ifa_addr == NULL) {
410 continue;
411 }
412

--- 4 unchanged lines hidden (view full) ---

417 if (IN6_IS_ADDR_MULTICAST(&tmp6->sin6_addr)) {
418 continue;
419 }
420 if (IN6_IS_ADDR_LOOPBACK(&tmp6->sin6_addr)) {
421 continue;
422 }
423 len = sizeof(struct sockaddr_in6);
424 if ( getnameinfo((struct sockaddr *)tmp6, len, hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) == 0) {
465 lprintf(LOG_DEBUG, "Testing %s interface address: %s scope=%d",
466 ifa->ifa_name != NULL ? ifa->ifa_name : "???",
467 hbuf,
425 lprintf(LOG_DEBUG, "Testing %s interface address: %s scope=%d",
426 ifa->ifa_name != NULL ? ifa->ifa_name : "???",
427 hbuf,
468 tmp6->sin6_scope_id);
469 }
470
471 if (tmp6->sin6_scope_id != 0) {
472 addr6->sin6_scope_id = tmp6->sin6_scope_id;
473 } else {
428 tmp6->sin6_scope_id);
429 }
430
431 if (tmp6->sin6_scope_id != 0) {
432 addr6->sin6_scope_id = tmp6->sin6_scope_id;
433 } else {
474 /*
475 * No scope information in interface address information
434 /*
435 * No scope information in interface address information
476 * On some OS'es, getifaddrs() is returning out the 'kernel' representation
477 * of scoped addresses which stores the scope in the 3rd and 4th
478 * byte. See also this page:
479 * http://www.freebsd.org/doc/en/books/developers-handbook/ipv6.html
480 */
481 if (IN6_IS_ADDR_LINKLOCAL(&tmp6->sin6_addr)
482 && (tmp6->sin6_addr.s6_addr[1] != 0)) {
483 addr6->sin6_scope_id = ntohs(tmp6->sin6_addr.s6_addr[1]);
484 }
485 }
486
487 /* OK, now try to connect with the scope id from this interface address */
488 if (addr6->sin6_scope_id != 0) {
489 if (connect(intf->fd, rp->ai_addr, rp->ai_addrlen) != -1) {
436 * On some OS'es, getifaddrs() is returning out the 'kernel' representation
437 * of scoped addresses which stores the scope in the 3rd and 4th
438 * byte. See also this page:
439 * http://www.freebsd.org/doc/en/books/developers-handbook/ipv6.html
440 */
441 if (IN6_IS_ADDR_LINKLOCAL(&tmp6->sin6_addr)
442 && (tmp6->sin6_addr.s6_addr[1] != 0)) {
443 addr6->sin6_scope_id = ntohs(tmp6->sin6_addr.s6_addr[1]);
444 }
445 }
446
447 /* OK, now try to connect with the scope id from this interface address */
448 if (addr6->sin6_scope_id != 0) {
449 if (connect(intf->fd, rp->ai_addr, rp->ai_addrlen) != -1) {
490 memcpy(&session->addr, rp->ai_addr, rp->ai_addrlen);
491 session->addrlen = rp->ai_addrlen;
492 session->ai_family = rp->ai_family;
450 hints.ai_family = rp->ai_family;
493 lprintf(LOG_DEBUG, "Successful connected on %s interface with scope id %d", ifa->ifa_name, tmp6->sin6_scope_id);
494 break; /* Success */
495 }
451 lprintf(LOG_DEBUG, "Successful connected on %s interface with scope id %d", ifa->ifa_name, tmp6->sin6_scope_id);
452 break; /* Success */
453 }
496 }
454 }
497 }
498 }
499 freeifaddrs(ifaddrs);
500 }
501 }
455 }
456 }
457 freeifaddrs(ifaddrs);
458 }
459 }
502 if (session->ai_family != AF_UNSPEC) {
460 if (hints.ai_family != AF_UNSPEC) {
503 break;
504 }
505 close(intf->fd);
506 intf->fd = -1;
507 }
508
509 /* No longer needed */
510 freeaddrinfo(rp0);

--- 155 unchanged lines hidden ---
461 break;
462 }
463 close(intf->fd);
464 intf->fd = -1;
465 }
466
467 /* No longer needed */
468 freeaddrinfo(rp0);

--- 155 unchanged lines hidden ---