Revision b1a1faba sysdep/unix/krt-iface.c

View differences:

sysdep/unix/krt-iface.c
2 2
 *	BIRD -- Unix Interface Scanning and Syncing
3 3
 *
4 4
 *	(c) 1998--2000 Martin Mares <mj@ucw.cz>
5
 *      (c) 2004       Ondrej Filip <feela@network.cz>
5 6
 *
6 7
 *	Can be freely distributed and used under the terms of the GNU GPL.
7 8
 */
......
36 37
  unsigned fl;
37 38
  ip_addr netmask;
38 39
  int l, scope;
40
  sockaddr *sa;
39 41

  
40 42
  if_start_update();
41 43
  for (cnt /= sizeof(struct ifreq); cnt; cnt--, r++)
......
43 45
      int sec = 0;
44 46
      bzero(&i, sizeof(i));
45 47
      bzero(&a, sizeof(a));
46
      DBG("%s\n", r->ifr_name);
47 48
      if (colon = strchr(r->ifr_name, ':'))
48 49
	{
49 50
	  /* It's an alias -- let's interpret it as a secondary interface address */
......
51 52
	  *colon = 0;
52 53
	}
53 54
      strncpy(i.name, r->ifr_name, sizeof(i.name) - 1);
54
      get_sockaddr((struct sockaddr_in *) &r->ifr_addr, &a.ip, NULL);
55

  
56
      if(ioctl(if_scan_sock, SIOCGIFADDR,r)<0) continue;
57

  
58
      get_sockaddr((struct sockaddr_in *) &r->ifr_addr, &a.ip, NULL, 1);
55 59
      if (ipa_nonzero(a.ip))
56 60
	{
57 61
	  l = ipa_classify(a.ip);
......
83 87

  
84 88
      if (ioctl(if_scan_sock, SIOCGIFNETMASK, r) < 0)
85 89
	{ err = "SIOCGIFNETMASK"; goto faulty; }
86
      get_sockaddr((struct sockaddr_in *) &r->ifr_addr, &netmask, NULL);
90
      get_sockaddr((struct sockaddr_in *) &r->ifr_addr, &netmask, NULL, 0);
87 91
      l = ipa_mklen(netmask);
88 92
      if (l < 0 || l == 31)
89 93
	{
90
	  log(L_ERR "%s: Invalid netmask", i.name);
94
	  log(L_ERR "%s: Invalid netmask (%x)", i.name, netmask);
91 95
	  goto bad;
92 96
	}
93 97
      a.pxlen = l;
......
97 101
	  a.flags |= IA_UNNUMBERED;
98 102
	  if (ioctl(if_scan_sock, SIOCGIFDSTADDR, r) < 0)
99 103
	    { err = "SIOCGIFDSTADDR"; goto faulty; }
100
	  get_sockaddr((struct sockaddr_in *) &r->ifr_addr, &a.opposite, NULL);
104
	  get_sockaddr((struct sockaddr_in *) &r->ifr_addr, &a.opposite, NULL, 1);
101 105
	  a.prefix = a.opposite;
102 106
	  a.pxlen = BITS_PER_IP_ADDRESS;
103 107
	}
......
188 192

  
189 193
  for(;;)
190 194
    {
191
      if (last_ifbuf_size)
192
	{
193
	  struct ifreq *r = alloca(last_ifbuf_size);
194
	  ic.ifc_ifcu.ifcu_req = r;
195
	  ic.ifc_len = last_ifbuf_size;
196
	  res = ioctl(if_scan_sock, SIOCGIFCONF, &ic);
197
	  if (res < 0 && errno != EFAULT)
198
	    die("SIOCCGIFCONF: %m");
199
	  if (res >= 0 && ic.ifc_len < last_ifbuf_size)
200
	    {
201
	      scan_ifs(r, ic.ifc_len);
202
	      break;
203
	    }
204
	}
205
#if 0
206
      /*
207
       *  Linux 2.1 and higher supports this, but it's not needed since
208
       *  we prefer to use Netlink there anyway.
209
       */
210
      ic.ifc_req = NULL;
211
      ic.ifc_len = 999999999;
212
      if (ioctl(if_scan_sock, SIOCGIFCONF, &ic) < 0)
213
	die("SIOCIFCONF: %m");
214
      ic.ifc_len += sizeof(struct ifreq);
215
      if (last_ifbuf_size < ic.ifc_len)
216
	{
217
	  last_ifbuf_size = ic.ifc_len;
218
	  DBG("Increased ifconf buffer size to %d\n", last_ifbuf_size);
219
	}
220
#else
195
      ic.ifc_buf = alloca(last_ifbuf_size);
196
      ic.ifc_len = last_ifbuf_size;
197
      res = ioctl(if_scan_sock, SIOCGIFCONF, &ic);
198
      if (res < 0 && errno != EFAULT)
199
        die("SIOCCGIFCONF: %m");
200
      if (res >= 0 && ic.ifc_len <= last_ifbuf_size)
201
        break;
221 202
      last_ifbuf_size *= 2;
222 203
      DBG("Increased ifconf buffer size to %d\n", last_ifbuf_size);
223
#endif
224 204
    }
205
  scan_ifs(ic.ifc_req, ic.ifc_len);
225 206
}
226 207

  
227 208
void
......
247 228
  if (if_scan_sock < 0)
248 229
    die("Cannot create scanning socket: %m");
249 230
}
231

  

Also available in: Unified diff