File: getiface.c

package info (click to toggle)
netatalk 3.1.12~ds-3
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 14,756 kB
  • sloc: ansic: 104,976; sh: 8,247; xml: 7,394; perl: 1,936; makefile: 1,430; python: 1,342; yacc: 309; lex: 49
file content (148 lines) | stat: -rw-r--r-- 3,119 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
/* 
 * Copyright (c) 1990,1993 Regents of The University of Michigan.
 * Copyright (c) 1999-2000 Adrian Sun. 
 * All Rights Reserved. See COPYRIGHT.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#ifdef TRU64
#include <sys/mbuf.h>
#include <net/route.h>
#endif /* TRU64 */
#include <net/if.h>
#include <errno.h>

#ifdef __svr4__
#include <sys/sockio.h>
#endif

#include <atalk/util.h>

/* allocation size for interface list. */
#define IFACE_NUM 5

/* we leave all of the ioctl's to the application */
static int addname(char **list, int *i, const char *name) 

{
    /* if we've run out of room, allocate some more. just return
     * the present list if we can't. */
     
    if ((list[*i] = strdup(name)) == NULL)
      return -1;

    (*i)++;
    list[*i] = NULL; /* zero out the next entry */
    return 0;
}


static int getifaces(const int sockfd, char ***list)
{
#ifdef HAVE_IFNAMEINDEX
      struct if_nameindex *ifstart, *ifs;
      int i = 0;
	  char **new;
  
      ifs = ifstart = if_nameindex();

	  new = (char **) malloc((sizeof(ifs)/sizeof(struct if_nameindex) + 1) * sizeof(char *));
      while (ifs && ifs->if_name) {
	/* just bail if there's a problem */
	if (addname(new, &i, ifs->if_name) < 0)
	  break;
	ifs++;
      }

      if_freenameindex(ifstart);
	  *list = new;
      return i;

#else
    struct ifconf	ifc;
    struct ifreq	ifrs[ 64 ], *ifr, *nextifr;
    int			ifrsize, i = 0;
	char **new;

    if (!list)
      return 0;

    memset( &ifc, 0, sizeof( struct ifconf ));
    ifc.ifc_len = sizeof( ifrs );
    memset( ifrs, 0, sizeof( ifrs ));
    ifc.ifc_buf = (caddr_t)ifrs;
    if ( ioctl( sockfd, SIOCGIFCONF, &ifc ) < 0 ) {
	return 0;
    }

	new = (char **) malloc((ifc.ifc_len/sizeof(struct ifreq) + 1) * sizeof(char *));
    for ( ifr = ifc.ifc_req; ifc.ifc_len >= (int) sizeof( struct ifreq );
	    ifc.ifc_len -= ifrsize, ifr = nextifr ) {
#ifdef BSD4_4
 	ifrsize = sizeof(ifr->ifr_name) +
	  (ifr->ifr_addr.sa_len > sizeof(struct sockaddr)
	   ? ifr->ifr_addr.sa_len : sizeof(struct sockaddr));
#else /* !BSD4_4 */
	ifrsize = sizeof( struct ifreq );
#endif /* BSD4_4 */
	nextifr = (struct ifreq *)((caddr_t)ifr + ifrsize );

	/* just bail if there's a problem */
	if (addname(new, &i, ifr->ifr_name) < 0)
	  break;
    }
	*list = new;
    return i;
#endif
}


/*
 * Get interfaces from the kernel. we keep an extra null entry to signify
 * the end of the interface list. 
 */
char **getifacelist(void)
{
  char **list = NULL; /* FIXME */
  int  i, fd;

  if ((fd = socket(PF_INET, SOCK_STREAM, 0)) < 0)
    return NULL;

  if ((i = getifaces(fd, &list)) == 0) {
    free(list);
    close(fd);
    return NULL;
  }
  close(fd);

  return list;
}


/* go through and free the interface list */
void freeifacelist(char **ifacelist)
{
  char *value, **list = ifacelist;

  if (!ifacelist)
    return;

  while ((value = *list++)) {
    free(value);
  }

  free(ifacelist);
}