~ps10gel/ubuntu/xenial/trafficserver/6.2.0

« back to all changes in this revision

Viewing changes to proxy/mgmt2/utils/MgmtUtils.cc

  • Committer: Bazaar Package Importer
  • Author(s): Arno Toell
  • Date: 2011-01-13 11:49:18 UTC
  • Revision ID: james.westby@ubuntu.com-20110113114918-vu422h8dknrgkj15
Tags: upstream-2.1.5-unstable
ImportĀ upstreamĀ versionĀ 2.1.5-unstable

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/** @file
 
2
 
 
3
  A brief file description
 
4
 
 
5
  @section license License
 
6
 
 
7
  Licensed to the Apache Software Foundation (ASF) under one
 
8
  or more contributor license agreements.  See the NOTICE file
 
9
  distributed with this work for additional information
 
10
  regarding copyright ownership.  The ASF licenses this file
 
11
  to you under the Apache License, Version 2.0 (the
 
12
  "License"); you may not use this file except in compliance
 
13
  with the License.  You may obtain a copy of the License at
 
14
 
 
15
      http://www.apache.org/licenses/LICENSE-2.0
 
16
 
 
17
  Unless required by applicable law or agreed to in writing, software
 
18
  distributed under the License is distributed on an "AS IS" BASIS,
 
19
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
20
  See the License for the specific language governing permissions and
 
21
  limitations under the License.
 
22
 */
 
23
 
 
24
/**************************************
 
25
 *
 
26
 * MgmtUtils.h
 
27
 *   Some utility and support functions for the management module.
 
28
 *
 
29
 *
 
30
 */
 
31
 
 
32
#include "ink_unused.h"      /* MAGIC_EDITING_TAG */
 
33
 
 
34
#include "libts.h"
 
35
#include "MgmtUtils.h"
 
36
#include "Diags.h"
 
37
 
 
38
#ifdef LOCAL_MANAGER
 
39
#include "mgmt2/Main.h"
 
40
#else
 
41
#include "mgmt2/../Main.h"
 
42
#endif
 
43
 
 
44
extern int diags_init;
 
45
 
 
46
#if defined (_WIN32)
 
47
#define syslog(_X, _Y, _Z)
 
48
#endif
 
49
static int use_syslog = 0;
 
50
 
 
51
/* mgmt_use_syslog()
 
52
 *
 
53
 *    Called to indicate that the syslog should be used and
 
54
 *       the log has been opened
 
55
 */
 
56
void
 
57
mgmt_use_syslog()
 
58
{
 
59
  use_syslog = 1;
 
60
}
 
61
 
 
62
/*
 
63
 * mgmt_readline(...)
 
64
 *   Simple, inefficient, read line function. Takes a socket to read
 
65
 * from, a char * to write into, and a max len to read. The newline
 
66
 * is stripped.
 
67
 *
 
68
 * Returns:  num bytes read
 
69
 *           -1  error
 
70
 */
 
71
int
 
72
mgmt_readline(int soc, char *buf, int maxlen)
 
73
{
 
74
  int n, rc;
 
75
  char c;
 
76
 
 
77
  for (n = 1; n < maxlen; n++) {
 
78
 
 
79
    if ((rc = read_socket(soc, &c, 1)) == 1) {
 
80
 
 
81
      *buf++ = c;
 
82
      if (c == '\n') {
 
83
        --buf;
 
84
        *buf = '\0';
 
85
        if (*(buf - 1) == '\r') {
 
86
          --buf;
 
87
          *buf = '\0';
 
88
        }
 
89
        break;
 
90
      }
 
91
    } else if (rc == 0) {
 
92
 
 
93
      if (n == 1) {             /* EOF */
 
94
        return 0;
 
95
      } else {
 
96
        break;
 
97
      }
 
98
    } else {                    /* Error */
 
99
      return -1;
 
100
    }
 
101
  }
 
102
  return n;
 
103
}                               /* End mgmt_readline */
 
104
 
 
105
 
 
106
/*
 
107
 * mgmt_writeline(...)
 
108
 *   Simple, inefficient, write line function. Takes a soc to write to,
 
109
 * a char * containing the data, and the number of bytes to write.
 
110
 * It sends nbytes + 1 bytes worth of data, the + 1 being the newline
 
111
 * character.
 
112
 *
 
113
 * Returns:    num bytes not written
 
114
 *             -1  error
 
115
 */
 
116
int
 
117
mgmt_writeline(int soc, const char *data, int nbytes)
 
118
{
 
119
  int nleft, nwritten, n;
 
120
  const char *tmp = data;
 
121
 
 
122
  nleft = nbytes;
 
123
  while (nleft > 0) {
 
124
    nwritten = write_socket(soc, tmp, nleft);
 
125
    if (nwritten <= 0) {        /* Error or nothing written */
 
126
      return nwritten;
 
127
    }
 
128
    nleft -= nwritten;
 
129
    tmp += nwritten;
 
130
  }
 
131
 
 
132
  if ((n = write_socket(soc, "\n", 1)) <= 0) {      /* Terminating newline */
 
133
    if (n < 0) {
 
134
      return n;
 
135
    } else {
 
136
      return (nbytes - nleft);
 
137
    }
 
138
  }
 
139
 
 
140
  return (nleft);               /* Paranoia */
 
141
}                               /* End mgmt_writeline */
 
142
 
 
143
#if !defined(_WIN32)
 
144
 
 
145
/*
 
146
 * mgmt_read_pipe()
 
147
 * - Reads from a pipe
 
148
 *
 
149
 * Returns: bytes read
 
150
 *          0 on EOF
 
151
 *          -errno on error
 
152
 */
 
153
 
 
154
int
 
155
mgmt_read_pipe(int fd, char *buf, int bytes_to_read)
 
156
{
 
157
  int err = 0;
 
158
  char *p = buf;
 
159
  int bytes_read = 0;
 
160
  while (bytes_to_read > 0) {
 
161
    err = read_socket(fd, p, bytes_to_read);
 
162
    if (err == 0) {
 
163
      return err;
 
164
    } else if (err < 0) {
 
165
      switch (errno) {
 
166
      case EINTR:
 
167
      case EAGAIN:
 
168
#if defined(hpux)
 
169
      case EWOULDBLOCK:
 
170
#endif
 
171
        mgmt_sleep_msec(1);
 
172
        continue;
 
173
      default:
 
174
        return -errno;
 
175
      }
 
176
    }
 
177
    bytes_to_read -= err;
 
178
    bytes_read += err;
 
179
    p += err;
 
180
  }
 
181
  /*
 
182
     Ldone:
 
183
   */
 
184
  return bytes_read;
 
185
}
 
186
 
 
187
/*
 
188
 * mgmt_write_pipe()
 
189
 * - Writes to a pipe
 
190
 *
 
191
 * Returns: bytes written
 
192
 *          0 on EOF
 
193
 *          -errno on error
 
194
 */
 
195
 
 
196
int
 
197
mgmt_write_pipe(int fd, char *buf, int bytes_to_write)
 
198
{
 
199
  int err = 0;
 
200
  char *p = buf;
 
201
  int bytes_written = 0;
 
202
  while (bytes_to_write > 0) {
 
203
    err = write_socket(fd, p, bytes_to_write);
 
204
    if (err == 0) {
 
205
      return err;
 
206
    } else if (err < 0) {
 
207
      switch (errno) {
 
208
      case EINTR:
 
209
      case EAGAIN:
 
210
#if defined(hpux)
 
211
      case EWOULDBLOCK:
 
212
#endif
 
213
        mgmt_sleep_msec(1);
 
214
        continue;
 
215
      default:
 
216
        return -errno;
 
217
      }
 
218
    }
 
219
    bytes_to_write -= err;
 
220
    bytes_written += err;
 
221
    p += err;
 
222
  }
 
223
  /*
 
224
     Ldone:
 
225
   */
 
226
  return bytes_written;
 
227
}
 
228
 
 
229
#else
 
230
 
 
231
/*
 
232
 * mgmt_read_pipe()
 
233
 * - Reads from a message type named pipe.
 
234
 * - Blocking.
 
235
 *
 
236
 * Returns: num bytes read
 
237
 *          -1  error
 
238
 */
 
239
int
 
240
mgmt_read_pipe(HANDLE hpipe, char *buf, int maxlen)
 
241
{
 
242
  DWORD bytesRead = 0;
 
243
  OVERLAPPED ov;
 
244
 
 
245
  ov.Internal = ov.InternalHigh = ov.Offset = ov.OffsetHigh = 0;
 
246
  ov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
 
247
  if (ReadFile(hpipe, (LPVOID) buf, maxlen, NULL, &ov) == 0) {
 
248
    if (GetLastError() != ERROR_IO_PENDING) {
 
249
      CloseHandle(ov.hEvent);
 
250
      return -1;
 
251
    }
 
252
  }
 
253
  if (WaitForSingleObject(ov.hEvent, INFINITE) == WAIT_FAILED) {
 
254
    CloseHandle(ov.hEvent);
 
255
    return -1;
 
256
  }
 
257
  if (GetOverlappedResult(hpipe, &ov, &bytesRead, FALSE) == 0) {
 
258
    CloseHandle(ov.hEvent);
 
259
    return -1;
 
260
  }
 
261
 
 
262
  CloseHandle(ov.hEvent);
 
263
  buf[bytesRead] = 0;
 
264
  return bytesRead;
 
265
}
 
266
 
 
267
/*
 
268
 * mgmt_write_pipe()
 
269
 * - Writes to a message type named pipe.
 
270
 * - Blocking.
 
271
 *
 
272
 * Returns: num bytes not written
 
273
 *          -1  error
 
274
 */
 
275
int
 
276
mgmt_write_pipe(HANDLE hpipe, char *data, int nbytes)
 
277
{
 
278
  DWORD bytesWritten = 0;
 
279
  OVERLAPPED ov;
 
280
 
 
281
  ov.Internal = ov.InternalHigh = ov.Offset = ov.OffsetHigh = 0;
 
282
  ov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
 
283
  if (WriteFile(hpipe, (LPCVOID) data, nbytes, NULL, &ov) == 0) {
 
284
    if (GetLastError() != ERROR_IO_PENDING) {
 
285
      CloseHandle(ov.hEvent);
 
286
      return -1;
 
287
    }
 
288
  }
 
289
  if (WaitForSingleObject(ov.hEvent, INFINITE) == WAIT_FAILED) {
 
290
    CloseHandle(ov.hEvent);
 
291
    return -1;
 
292
  }
 
293
  if (GetOverlappedResult(hpipe, &ov, &bytesWritten, FALSE) == 0) {
 
294
    CloseHandle(ov.hEvent);
 
295
    return -1;
 
296
  }
 
297
 
 
298
  CloseHandle(ov.hEvent);
 
299
  return (nbytes - bytesWritten);
 
300
}
 
301
 
 
302
#endif // !_WIN32
 
303
 
 
304
void
 
305
mgmt_blockAllSigs()
 
306
{
 
307
#if !defined(linux) && !defined(_WIN32)
 
308
  // Start by blocking all signals
 
309
  sigset_t allSigs;             // Set of all signals
 
310
  sigfillset(&allSigs);
 
311
  if (ink_thread_sigsetmask(SIG_SETMASK, &allSigs, NULL) < 0) {
 
312
    perror("ink_thread_sigsetmask");
 
313
  }
 
314
#endif
 
315
}
 
316
 
 
317
/*
 
318
 * mgmt_log(...)
 
319
 *   Really just a print wrapper, function takes a string and outputs the
 
320
 * result to log. Written so that we could turn off all output or at least
 
321
 * better control it.
 
322
 */
 
323
void
 
324
mgmt_log(FILE * log, const char *message_format, ...)
 
325
{
 
326
  va_list ap;
 
327
  char extended_format[4096], message[4096];
 
328
 
 
329
  va_start(ap, message_format);
 
330
 
 
331
#if defined(LOCAL_MANAGER) || defined(PROCESS_MANAGER)
 
332
  if (diags_init) {
 
333
    diags->print_va(NULL, DL_Note, "NOTE", NULL, message_format, ap);
 
334
  } else {
 
335
#endif
 
336
 
 
337
    if (use_syslog) {
 
338
      snprintf(extended_format, sizeof(extended_format), "log ==> %s", message_format);
 
339
      vsprintf(message, extended_format, ap);
 
340
      syslog(LOG_WARNING, "%s", message);
 
341
    } else {
 
342
      snprintf(extended_format, sizeof(extended_format), "[E. Mgmt] log ==> %s", message_format);
 
343
      vsprintf(message, extended_format, ap);
 
344
      ink_assert(fwrite(message, strlen(message), 1, log) == 1);
 
345
    }
 
346
#if defined(LOCAL_MANAGER) || defined(PROCESS_MANAGER)
 
347
  }
 
348
#endif
 
349
 
 
350
  va_end(ap);
 
351
  return;
 
352
}                               /* End mgmt_log */
 
353
 
 
354
void
 
355
mgmt_log(const char *message_format, ...)
 
356
{
 
357
  va_list ap;
 
358
  char extended_format[4096], message[4096];
 
359
 
 
360
  va_start(ap, message_format);
 
361
#if defined(LOCAL_MANAGER) || defined(PROCESS_MANAGER)
 
362
  if (diags_init) {
 
363
    diags->print_va(NULL, DL_Note, "NOTE", NULL, message_format, ap);
 
364
  } else {
 
365
#endif
 
366
 
 
367
    if (use_syslog) {
 
368
      snprintf(extended_format, sizeof(extended_format), "log ==> %s", message_format);
 
369
      vsprintf(message, extended_format, ap);
 
370
      syslog(LOG_WARNING, "%s", message);
 
371
    } else {
 
372
      snprintf(extended_format, sizeof(extended_format), "[E. Mgmt] log ==> %s", message_format);
 
373
      vsprintf(message, extended_format, ap);
 
374
      ink_assert(fwrite(message, strlen(message), 1, stderr) == 1);
 
375
    }
 
376
#if defined(LOCAL_MANAGER) || defined(PROCESS_MANAGER)
 
377
  }
 
378
#endif
 
379
 
 
380
  va_end(ap);
 
381
  return;
 
382
}                               /* End mgmt_log */
 
383
 
 
384
 
 
385
/*
 
386
 * mgmt_log(...)
 
387
 *   Same as above, but intended for errors.
 
388
 */
 
389
void
 
390
mgmt_elog(FILE * log, const char *message_format, ...)
 
391
{
 
392
  va_list ap;
 
393
  char extended_format[4096], message[4096];
 
394
 
 
395
  va_start(ap, message_format);
 
396
 
 
397
#if defined(LOCAL_MANAGER) || defined(PROCESS_MANAGER)
 
398
  if (diags_init) {
 
399
    int lerrno = errno;
 
400
    diags->print_va(NULL, DL_Error, "ERROR", NULL, message_format, ap);
 
401
    snprintf(message, sizeof(message), " (last system error %d: %s)\n", lerrno, strerror(lerrno));
 
402
    diags->print(NULL, DL_Error, "ERROR", NULL, message);
 
403
  } else {
 
404
#endif
 
405
    if (use_syslog) {
 
406
      snprintf(extended_format, sizeof(extended_format), "ERROR ==> %s", message_format);
 
407
      vsprintf(message, extended_format, ap);
 
408
#if !defined (_WIN32)
 
409
      syslog(LOG_ERR, "%s", message);
 
410
      syslog(LOG_ERR, " (last system error %d: %s)", errno, strerror(errno));
 
411
#endif
 
412
    } else {
 
413
      snprintf(extended_format, sizeof(extended_format), "[E. Mgmt] ERROR ==> %s", message_format);
 
414
      vsprintf(message, extended_format, ap);
 
415
      ink_assert(fwrite(message, strlen(message), 1, log) == 1);
 
416
      snprintf(message, sizeof(message), "(last system error %d: %s)", errno, strerror(errno));
 
417
      ink_assert(fwrite(message, strlen(message), 1, log) == 1);
 
418
    }
 
419
#if defined(LOCAL_MANAGER) || defined(PROCESS_MANAGER)
 
420
  }
 
421
#endif
 
422
  va_end(ap);
 
423
 
 
424
  return;
 
425
}                               /* End mgmt_elog */
 
426
 
 
427
 
 
428
void
 
429
mgmt_elog(const char *message_format, ...)
 
430
{
 
431
  va_list ap;
 
432
  char extended_format[4096], message[4096];
 
433
 
 
434
  va_start(ap, message_format);
 
435
 
 
436
#if defined(LOCAL_MANAGER) || defined(PROCESS_MANAGER)
 
437
  if (diags_init) {
 
438
    int lerrno = errno;
 
439
    diags->print_va(NULL, DL_Error, "ERROR", NULL, message_format, ap);
 
440
    snprintf(message, sizeof(message), " (last system error %d: %s)\n", lerrno, strerror(lerrno));
 
441
    diags->print(NULL, DL_Error, "ERROR", NULL, message);
 
442
  } else {
 
443
#endif
 
444
 
 
445
    if (use_syslog) {
 
446
      snprintf(extended_format, sizeof(extended_format), "ERROR ==> %s", message_format);
 
447
      vsprintf(message, extended_format, ap);
 
448
      syslog(LOG_ERR, "%s", message);
 
449
#if !defined (_WIN32)
 
450
      syslog(LOG_ERR, " (last system error %d: %s)", errno, strerror(errno));
 
451
#endif
 
452
    } else {
 
453
      snprintf(extended_format, sizeof(extended_format), "Manager ERROR: %s", message_format);
 
454
      vsprintf(message, extended_format, ap);
 
455
      ink_assert(fwrite(message, strlen(message), 1, stderr) == 1);
 
456
      snprintf(message, sizeof(message), "(last system error %d: %s)", errno, strerror(errno));
 
457
      ink_assert(fwrite(message, strlen(message), 1, stderr) == 1);
 
458
    }
 
459
#if defined(LOCAL_MANAGER) || defined(PROCESS_MANAGER)
 
460
  }
 
461
#endif
 
462
  va_end(ap);
 
463
  return;
 
464
}                               /* End mgmt_elog */
 
465
 
 
466
 
 
467
/*
 
468
 * mgmt_fatal(...)
 
469
 *   Same as above, but for fatal errors. Logs error, calls perror, and
 
470
 * asserts false.
 
471
 */
 
472
void
 
473
mgmt_fatal(FILE * log, const char *message_format, ...)
 
474
{
 
475
  va_list ap;
 
476
  char extended_format[4096], message[4096];
 
477
 
 
478
  va_start(ap, message_format);
 
479
 
 
480
 
 
481
#if defined(LOCAL_MANAGER) || defined(PROCESS_MANAGER)
 
482
  if (diags_init) {
 
483
    int lerrno = errno;
 
484
    diags->print_va(NULL, DL_Fatal, "FATAL", NULL, message_format, ap);
 
485
    snprintf(message, sizeof(message), " (last system error %d: %s)\n", lerrno, strerror(lerrno));
 
486
    diags->print(NULL, DL_Fatal, "FATAL", NULL, message);
 
487
  } else {
 
488
#endif
 
489
 
 
490
    snprintf(extended_format, sizeof(extended_format), "FATAL ==> %s", message_format);
 
491
    vsprintf(message, extended_format, ap);
 
492
 
 
493
    ink_assert(fwrite(message, strlen(message), 1, log) == 1);
 
494
 
 
495
    if (use_syslog) {
 
496
      syslog(LOG_ERR, "%s", message);
 
497
    }
 
498
 
 
499
 
 
500
 
 
501
    perror("[E. Mgmt] ");
 
502
 
 
503
    if (use_syslog) {
 
504
#if !defined (_WIN32)
 
505
      syslog(LOG_ERR, " (last system error %d: %s)", errno, strerror(errno));
 
506
#endif
 
507
    }
 
508
#if defined(LOCAL_MANAGER) || defined(PROCESS_MANAGER)
 
509
  }
 
510
#endif
 
511
 
 
512
  va_end(ap);
 
513
 
 
514
  mgmt_cleanup();
 
515
  _exit(1);
 
516
}                               /* End mgmt_fatal */
 
517
 
 
518
 
 
519
 
 
520
void
 
521
mgmt_fatal(const char *message_format, ...)
 
522
{
 
523
  va_list ap;
 
524
  char extended_format[4096], message[4096];
 
525
 
 
526
  va_start(ap, message_format);
 
527
 
 
528
#if defined(LOCAL_MANAGER) || defined(PROCESS_MANAGER)
 
529
  if (diags_init) {
 
530
    int lerrno = errno;
 
531
    diags->print_va(NULL, DL_Fatal, "FATAL", NULL, message_format, ap);
 
532
    snprintf(message, sizeof(message), " (last system error %d: %s)\n", lerrno, strerror(lerrno));
 
533
    diags->print(NULL, DL_Fatal, "FATAL", NULL, message);
 
534
  } else {
 
535
#endif
 
536
 
 
537
    snprintf(extended_format, sizeof(extended_format), "FATAL ==> %s", message_format);
 
538
    vsprintf(message, extended_format, ap);
 
539
 
 
540
    ink_assert(fwrite(message, strlen(message), 1, stderr) == 1);
 
541
 
 
542
    if (use_syslog) {
 
543
      syslog(LOG_ERR, "%s", message);
 
544
    }
 
545
 
 
546
 
 
547
 
 
548
    perror("[E. Mgmt] ");
 
549
 
 
550
    if (use_syslog) {
 
551
#if !defined (_WIN32)
 
552
      syslog(LOG_ERR, " (last system error %d: %s)", errno, strerror(errno));
 
553
#endif
 
554
    }
 
555
#if defined(LOCAL_MANAGER) || defined(PROCESS_MANAGER)
 
556
  }
 
557
#endif
 
558
 
 
559
  va_end(ap);
 
560
 
 
561
  mgmt_cleanup();
 
562
  _exit(1);
 
563
}                               /* End mgmt_fatal */
 
564
 
 
565
void
 
566
mgmt_cleanup()
 
567
{
 
568
#if defined(LOCAL_MANAGER)
 
569
  if (lmgmt != NULL) {
 
570
    lmgmt->mgmtShutdown(1, true);
 
571
  }
 
572
#endif
 
573
}
 
574
 
 
575
#if !defined(_WIN32)
 
576
static inline int
 
577
get_interface_mtu(int sock_fd, struct ifreq *ifr)
 
578
{
 
579
  if (ioctl(sock_fd, SIOCGIFMTU, ifr) < 0) {
 
580
    mgmt_log(stderr, "[getAddrForIntr] Unable to obtain MTU for " "interface '%s'", ifr->ifr_name);
 
581
    return 0;
 
582
  } else
 
583
#if defined(solaris) || defined(hpux)
 
584
    return ifr->ifr_metric;
 
585
#else
 
586
    return ifr->ifr_mtu;
 
587
#endif
 
588
}
 
589
#endif
 
590
 
 
591
bool
 
592
mgmt_getAddrForIntr(char *intrName, struct in_addr * addr, int *mtu)
 
593
{
 
594
  bool found = false;
 
595
 
 
596
  if (intrName == NULL) {
 
597
    return false;
 
598
  }
 
599
#if !defined(_WIN32)
 
600
 
 
601
  int fakeSocket;               // a temporary socket to pass to ioctl
 
602
  struct sockaddr_in *tmp;      // a tmp ptr for addresses
 
603
  struct ifconf ifc;            // ifconf information
 
604
  char *ifbuf;                  // ifconf buffer
 
605
  struct ifreq *ifr, *ifend;    // pointer to individual inferface info
 
606
  int lastlen;
 
607
  int len;
 
608
 
 
609
  // Prevent UMRs
 
610
  memset(addr, 0, sizeof(struct in_addr));
 
611
 
 
612
  if ((fakeSocket = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
 
613
    mgmt_fatal(stderr, "[getAddrForIntr] Unable to create socket\n");
 
614
  }
 
615
  // INKqa06739
 
616
  // Fetch the list of network interfaces
 
617
  // . from Stevens, Unix Network Prog., pg 434-435
 
618
  ifbuf = 0;
 
619
  lastlen = 0;
 
620
  len = 128 * sizeof(struct ifreq);     // initial buffer size guess
 
621
  for (;;) {
 
622
    ifbuf = (char *) xmalloc(len);
 
623
    memset(ifbuf, 0, len);      // prevent UMRs
 
624
    ifc.ifc_len = len;
 
625
    ifc.ifc_buf = ifbuf;
 
626
    if (ioctl(fakeSocket, SIOCGIFCONF, &ifc) < 0) {
 
627
      if (errno != EINVAL || lastlen != 0) {
 
628
        mgmt_fatal(stderr, "[getAddrForIntr] Unable to read network interface configuration\n");
 
629
      }
 
630
    } else {
 
631
      if (ifc.ifc_len == lastlen) {
 
632
        break;
 
633
      }
 
634
      lastlen = ifc.ifc_len;
 
635
    }
 
636
    len *= 2;
 
637
    xfree(ifbuf);
 
638
  }
 
639
 
 
640
  ifr = ifc.ifc_req;
 
641
  found = false;
 
642
  // Loop through the list of interfaces
 
643
  ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
 
644
  for (ifr = ifc.ifc_req; ifr < ifend;) {
 
645
    if (ifr->ifr_addr.sa_family == AF_INET && strcmp(ifr->ifr_name, intrName) == 0) {
 
646
      // Get the address of the interface
 
647
      if (ioctl(fakeSocket, SIOCGIFADDR, (char *) ifr) < 0) {
 
648
        mgmt_log(stderr, "[getAddrForIntr] Unable obtain address for network interface %s\n", intrName);
 
649
      } else {
 
650
        // Only look at the address if it an internet address
 
651
        if (ifr->ifr_ifru.ifru_addr.sa_family == AF_INET) {
 
652
          tmp = (struct sockaddr_in *) &ifr->ifr_ifru.ifru_addr;
 
653
          *addr = tmp->sin_addr;
 
654
          found = true;
 
655
 
 
656
          if (mtu)
 
657
            *mtu = get_interface_mtu(fakeSocket, ifr);
 
658
 
 
659
          break;
 
660
        } else {
 
661
          mgmt_log(stderr, "[getAddrForIntr] Interface %s is not configured for IP.\n", intrName);
 
662
        }
 
663
      }
 
664
    }
 
665
#if defined(freebsd) || defined(darwin)
 
666
    ifr = (struct ifreq *) ((char *) &ifr->ifr_addr + ifr->ifr_addr.sa_len);
 
667
#else
 
668
    ifr = (struct ifreq *) (((char *) ifr) + sizeof(*ifr));
 
669
#endif
 
670
  }
 
671
  xfree(ifbuf);
 
672
  close(fakeSocket);
 
673
 
 
674
#else /* _WIN32 */
 
675
 
 
676
  // There is no notion of network interface names on NT.
 
677
  // So we use a winnt_intr.config file to give each of
 
678
  // the interface a name.
 
679
 
 
680
  char intr_file[PATH_MAX + 1];
 
681
  FILE *fp = NULL;
 
682
 
 
683
#ifdef LOCAL_MANAGER
 
684
  snprintf(intr_file, sizeof(intr_file), "%s%sconfig%s%s", ts_base_dir, DIR_SEP, DIR_SEP, "winnt_intr.config");
 
685
#else
 
686
  snprintf(intr_file, sizeof(intr_file), "%s%sconfig%s%s", system_base_install, DIR_SEP, DIR_SEP, "winnt_intr.config");
 
687
#endif
 
688
 
 
689
  if ((fp = fopen(intr_file, "r")) == NULL) {
 
690
    mgmt_log(stderr, "[getAddrForIntr] Unable to open %s\n", intr_file);
 
691
  } else {
 
692
    char buffer[1024];
 
693
    char *p = NULL;
 
694
 
 
695
    while (!feof(fp)) {
 
696
 
 
697
      if (!fgets(buffer, 1024, fp)) {
 
698
        break;
 
699
      }
 
700
      // replace newline with null termination
 
701
      p = strchr(buffer, '\n');
 
702
      if (p) {
 
703
        *p = '\0';
 
704
      }
 
705
      // skip beginning line spaces
 
706
      p = buffer;
 
707
      while (*p != '\0' && isspace(*p)) {
 
708
        p++;
 
709
      }
 
710
 
 
711
      // skip blank or comment lines
 
712
      if (*p == '#' || *p == '\0') {
 
713
        continue;
 
714
      }
 
715
 
 
716
      if (p = strstr(p, intrName)) {
 
717
        p = p + strlen(intrName) + 1;
 
718
        in_addr_t cluster_ip = inet_addr(p);
 
719
 
 
720
        if (cluster_ip != INADDR_NONE) {
 
721
          addr->s_addr = cluster_ip;
 
722
          found = true;
 
723
          break;
 
724
        }
 
725
      }
 
726
 
 
727
    }
 
728
    fclose(fp);
 
729
  }
 
730
 
 
731
#endif // !_WIN32
 
732
 
 
733
  return found;
 
734
}                               /* End mgmt_getAddrForIntr */
 
735
 
 
736
/*
 
737
 * mgmt_sortipaddrs(...)
 
738
 *   Routine to sort and pick smallest ip addr.
 
739
 */
 
740
struct in_addr *
 
741
mgmt_sortipaddrs(int num, struct in_addr **list)
 
742
{
 
743
  int i = 0;
 
744
  unsigned long min;
 
745
  struct in_addr *entry, *tmp;
 
746
 
 
747
  min = (list[0])->s_addr;
 
748
  entry = list[0];
 
749
  while (i < num && (tmp = (struct in_addr *) list[i]) != NULL) {
 
750
    i++;
 
751
    if (min > tmp->s_addr) {
 
752
      min = tmp->s_addr;
 
753
      entry = tmp;
 
754
    }
 
755
  }
 
756
  return entry;
 
757
}                               /* End mgmt_sortipaddrs */
 
758
 
 
759
char *
 
760
mgmt_localhost_ip()
 
761
{
 
762
#if defined(LOCAL_MANAGER)
 
763
  bool found;
 
764
  char *hostname;
 
765
  unsigned int ip;
 
766
  int rec_err = RecGetRecordString_Xmalloc("proxy.node.hostname_FQ", &hostname);
 
767
  found = (rec_err == REC_ERR_OKAY);
 
768
  if (found && hostname) {
 
769
    ip = host_to_ip(hostname);
 
770
    if (ip != INADDR_ANY) {
 
771
      return inet_ntoa(*(struct in_addr *) &ip);
 
772
    }
 
773
  }
 
774
#endif
 
775
  return NULL;
 
776
}
 
777
 
 
778
#ifndef _WIN32
 
779
void
 
780
mgmt_sleep_sec(int seconds)
 
781
{
 
782
  sleep(seconds);
 
783
}
 
784
 
 
785
void
 
786
mgmt_sleep_msec(int msec)
 
787
{
 
788
  usleep(msec * 1000);
 
789
}
 
790
#else
 
791
void
 
792
mgmt_sleep_sec(int seconds)
 
793
{
 
794
  Sleep(1000 * seconds);
 
795
}
 
796
 
 
797
void
 
798
mgmt_sleep_msec(int msec)
 
799
{
 
800
  Sleep(msec);
 
801
}
 
802
#endif