Initial import to Tizen
[profile/ivi/python-netifaces.git] / netifaces.c
1 #include <Python.h>
2
3 #ifndef WIN32
4
5 #  include <sys/types.h>
6 #  include <sys/socket.h>
7 #  include <net/if.h>
8 #  include <netdb.h>
9
10 #  if HAVE_SOCKET_IOCTLS
11 #    include <sys/ioctl.h>
12 #    include <netinet/in.h>
13 #    include <arpa/inet.h>
14 #if defined(__sun)
15 #include <unistd.h>
16 #include <stropts.h>
17 #include <sys/sockio.h>
18 #endif
19 #  endif /* HAVE_SOCKET_IOCTLS */
20
21 /* For logical interfaces support we convert all names to same name prefixed with l */
22 #if HAVE_SIOCGLIFNUM
23 #define CNAME(x) l##x
24 #else
25 #define CNAME(x) x
26 #endif
27
28 #if HAVE_NET_IF_DL_H
29 #  include <net/if_dl.h>
30 #endif
31
32 /* For the benefit of stupid platforms (Linux), include all the sockaddr
33    definitions we can lay our hands on. It can also be useful for the benefit
34    of another stupid platform (FreeBSD, see PR 152036). */
35 #include <netinet/in.h>
36 #  if HAVE_NETASH_ASH_H
37 #    include <netash/ash.h>
38 #  endif
39 #  if HAVE_NETATALK_AT_H
40 #    include <netatalk/at.h>
41 #  endif
42 #  if HAVE_NETAX25_AX25_H
43 #    include <netax25/ax25.h>
44 #  endif
45 #  if HAVE_NETECONET_EC_H
46 #    include <neteconet/ec.h>
47 #  endif
48 #  if HAVE_NETIPX_IPX_H
49 #    include <netipx/ipx.h>
50 #  endif
51 #  if HAVE_NETPACKET_PACKET_H
52 #    include <netpacket/packet.h>
53 #  endif
54 #  if HAVE_NETROSE_ROSE_H
55 #    include <netrose/rose.h>
56 #  endif
57 #  if HAVE_LINUX_IRDA_H
58 #    include <linux/irda.h>
59 #  endif
60 #  if HAVE_LINUX_ATM_H
61 #    include <linux/atm.h>
62 #  endif
63 #  if HAVE_LINUX_LLC_H
64 #    include <linux/llc.h>
65 #  endif
66 #  if HAVE_LINUX_TIPC_H
67 #    include <linux/tipc.h>
68 #  endif
69 #  if HAVE_LINUX_DN_H
70 #    include <linux/dn.h>
71 #  endif
72
73 /* Map address families to sizes of sockaddr structs */
74 static int af_to_len(int af) 
75 {
76   switch (af) {
77   case AF_INET: return sizeof (struct sockaddr_in);
78 #if defined(AF_INET6) && HAVE_SOCKADDR_IN6
79   case AF_INET6: return sizeof (struct sockaddr_in6);
80 #endif
81 #if defined(AF_AX25) && HAVE_SOCKADDR_AX25
82 #  if defined(AF_NETROM)
83   case AF_NETROM: /* I'm assuming this is carried over x25 */
84 #  endif
85   case AF_AX25: return sizeof (struct sockaddr_ax25);
86 #endif
87 #if defined(AF_IPX) && HAVE_SOCKADDR_IPX
88   case AF_IPX: return sizeof (struct sockaddr_ipx);
89 #endif
90 #if defined(AF_APPLETALK) && HAVE_SOCKADDR_AT
91   case AF_APPLETALK: return sizeof (struct sockaddr_at);
92 #endif
93 #if defined(AF_ATMPVC) && HAVE_SOCKADDR_ATMPVC
94   case AF_ATMPVC: return sizeof (struct sockaddr_atmpvc);
95 #endif
96 #if defined(AF_ATMSVC) && HAVE_SOCKADDR_ATMSVC
97   case AF_ATMSVC: return sizeof (struct sockaddr_atmsvc);
98 #endif
99 #if defined(AF_X25) && HAVE_SOCKADDR_X25
100   case AF_X25: return sizeof (struct sockaddr_x25);
101 #endif
102 #if defined(AF_ROSE) && HAVE_SOCKADDR_ROSE
103   case AF_ROSE: return sizeof (struct sockaddr_rose);
104 #endif
105 #if defined(AF_DECnet) && HAVE_SOCKADDR_DN
106   case AF_DECnet: return sizeof (struct sockaddr_dn);
107 #endif
108 #if defined(AF_PACKET) && HAVE_SOCKADDR_LL
109   case AF_PACKET: return sizeof (struct sockaddr_ll);
110 #endif
111 #if defined(AF_ASH) && HAVE_SOCKADDR_ASH
112   case AF_ASH: return sizeof (struct sockaddr_ash);
113 #endif
114 #if defined(AF_ECONET) && HAVE_SOCKADDR_EC
115   case AF_ECONET: return sizeof (struct sockaddr_ec);
116 #endif
117 #if defined(AF_IRDA) && HAVE_SOCKADDR_IRDA
118   case AF_IRDA: return sizeof (struct sockaddr_irda);
119 #endif
120   }
121   return sizeof (struct sockaddr);
122 }
123
124 #if !HAVE_SOCKADDR_SA_LEN
125 #define SA_LEN(sa)      af_to_len(sa->sa_family)
126 #if HAVE_SIOCGLIFNUM
127 #define SS_LEN(sa)      af_to_len(sa->ss_family)
128 #else
129 #define SS_LEN(sa)      SA_LEN(sa)
130 #endif
131 #else
132 #define SA_LEN(sa)      sa->sa_len
133 #endif /* !HAVE_SOCKADDR_SA_LEN */
134
135 #  if HAVE_GETIFADDRS
136 #    include <ifaddrs.h>
137 #  endif /* HAVE_GETIFADDRS */
138
139 #  if !HAVE_GETIFADDRS && (!HAVE_SOCKET_IOCTLS || !HAVE_SIOCGIFCONF)
140 /* If the platform doesn't define, what we need, barf.  If you're seeing this,
141    it means you need to write suitable code to retrieve interface information
142    on your system. */
143 #    error You need to add code for your platform.
144 #  endif
145
146 #else /* defined(WIN32) */
147
148 #  include <winsock2.h>
149 #  include <iphlpapi.h>
150
151 #endif /* defined(WIN32) */
152
153 #ifndef TRUE
154 #define TRUE 1
155 #endif
156
157 #ifndef FALSE
158 #define FALSE 0
159 #endif
160
161 /* On systems without AF_LINK (Windows, for instance), define it anyway, but
162    give it a crazy value.  On Linux, which has AF_PACKET but not AF_LINK,
163    define AF_LINK as the latter instead. */
164 #ifndef AF_LINK
165 #  ifdef AF_PACKET
166 #    define AF_LINK  AF_PACKET
167 #  else
168 #    define AF_LINK  -1000
169 #  endif
170 #  define HAVE_AF_LINK 0
171 #else
172 #  define HAVE_AF_LINK 1
173 #endif
174
175 #if !defined(WIN32)
176 #if  !HAVE_GETNAMEINFO
177 #undef getnameinfo
178 #undef NI_NUMERICHOST
179
180 #define getnameinfo our_getnameinfo
181 #define NI_NUMERICHOST 1
182
183 /* A very simple getnameinfo() for platforms without */
184 static int
185 getnameinfo (const struct sockaddr *addr, int addr_len,
186              char *buffer, int buflen,
187              char *buf2, int buf2len,
188              int flags)
189 {
190   switch (addr->sa_family) {
191   case AF_INET:
192     {
193       const struct sockaddr_in *sin = (struct sockaddr_in *)addr;
194       const unsigned char *bytes = (unsigned char *)&sin->sin_addr.s_addr;
195       char tmpbuf[20];
196
197       sprintf (tmpbuf, "%d.%d.%d.%d",
198                bytes[0], bytes[1], bytes[2], bytes[3]);
199
200       strncpy (buffer, tmpbuf, buflen);
201     }
202     break;
203 #ifdef AF_INET6
204   case AF_INET6:
205     {
206       const struct sockaddr_in6 *sin = (const struct sockaddr_in6 *)addr;
207       const unsigned char *bytes = sin->sin6_addr.s6_addr;
208       int n;
209       char tmpbuf[80], *ptr = tmpbuf;
210       int done_double_colon = FALSE;
211       int colon_mode = FALSE;
212
213       for (n = 0; n < 8; ++n) {
214         unsigned char b1 = bytes[2 * n];
215         unsigned char b2 = bytes[2 * n + 1];
216
217         if (b1) {
218           if (colon_mode) {
219             colon_mode = FALSE;
220             *ptr++ = ':';
221           }
222           sprintf (ptr, "%x%02x", b1, b2);
223           ptr += strlen (ptr);
224           *ptr++ = ':';
225         } else if (b2) {
226           if (colon_mode) {
227             colon_mode = FALSE;
228             *ptr++ = ':';
229           }
230           sprintf (ptr, "%x", b2);
231           ptr += strlen (ptr);
232           *ptr++ = ':';
233         } else {
234           if (!colon_mode) {
235             if (done_double_colon) {
236               *ptr++ = '0';
237               *ptr++ = ':';
238             } else {
239               if (n == 0)
240                 *ptr++ = ':';
241               colon_mode = TRUE;
242               done_double_colon = TRUE;
243             }
244           }
245         }
246       }
247       if (colon_mode) {
248         colon_mode = FALSE;
249         *ptr++ = ':';
250         *ptr++ = '\0';
251       } else {
252         *--ptr = '\0';
253       }
254
255       strncpy (buffer, tmpbuf, buflen);
256     }
257     break;
258 #endif /* AF_INET6 */
259   default:
260     return -1;
261   }
262
263   return 0;
264 }
265 #endif
266
267 static int
268 string_from_sockaddr (struct sockaddr *addr,
269                       char *buffer,
270                       int buflen)
271 {
272   struct sockaddr* bigaddr = 0;
273   int failure;
274   struct sockaddr* gniaddr;
275   socklen_t gnilen;
276
277   if (!addr || addr->sa_family == AF_UNSPEC)
278     return -1;
279
280   if (SA_LEN(addr) < af_to_len(addr->sa_family)) {
281     /* Someteims ifa_netmask can be truncated. So let's detruncate it.  FreeBSD
282      * PR: kern/152036: getifaddrs(3) returns truncated sockaddrs for netmasks
283      * -- http://www.freebsd.org/cgi/query-pr.cgi?pr=152036 */
284     gnilen = af_to_len(addr->sa_family);
285     bigaddr = calloc(1, gnilen);
286     if (!bigaddr)
287       return -1;
288     memcpy(bigaddr, addr, SA_LEN(addr));
289 #if HAVE_SOCKADDR_SA_LEN
290     bigaddr->sa_len = gnilen;
291 #endif
292     gniaddr = bigaddr;
293   } else {
294     gnilen = SA_LEN(addr);
295     gniaddr = addr;
296   }
297
298   failure = getnameinfo (gniaddr, gnilen,
299                    buffer, buflen,
300                    NULL, 0,
301                    NI_NUMERICHOST);
302
303   if (bigaddr) {
304     free(bigaddr);
305     bigaddr = 0;
306   }
307
308   if (failure) {
309     int n, len;
310     char *ptr;
311     const char *data;
312       
313     len = SA_LEN(addr);
314
315 #if HAVE_AF_LINK
316     /* BSD-like systems have AF_LINK */
317     if (addr->sa_family == AF_LINK) {
318       struct sockaddr_dl *dladdr = (struct sockaddr_dl *)addr;
319       len = dladdr->sdl_alen;
320       data = LLADDR(dladdr);
321     } else {
322 #endif
323 #if defined(AF_PACKET)
324       /* Linux has AF_PACKET instead */
325       if (addr->sa_family == AF_PACKET) {
326         struct sockaddr_ll *lladdr = (struct sockaddr_ll *)addr;
327         len = lladdr->sll_halen;
328         data = (const char *)lladdr->sll_addr;
329       } else {
330 #endif
331         /* We don't know anything about this sockaddr, so just display
332            the entire data area in binary. */
333         len -= (sizeof (struct sockaddr) - sizeof (addr->sa_data));
334         data = addr->sa_data;
335 #if defined(AF_PACKET)
336       }
337 #endif
338 #if HAVE_AF_LINK
339     }
340 #endif
341
342     if (buflen < 3 * len)
343       return -1;
344
345     ptr = buffer;
346     buffer[0] = '\0';
347
348     for (n = 0; n < len; ++n) {
349       sprintf (ptr, "%02x:", data[n] & 0xff);
350       ptr += 3;
351     }
352     *--ptr = '\0';
353   }
354
355   return 0;
356 }
357 #endif /* !defined(WIN32) */
358
359 static int
360 add_to_family (PyObject *result, int family, PyObject *dict)
361 {
362   PyObject *py_family = PyInt_FromLong (family);
363   PyObject *list = PyDict_GetItem (result, py_family);
364
365   if (!py_family) {
366     Py_DECREF (dict);
367     Py_XDECREF (list);
368     return FALSE;
369   }
370
371   if (!list) {
372     list = PyList_New (1);
373     if (!list) {
374       Py_DECREF (dict);
375       Py_DECREF (py_family);
376       return FALSE;
377     }
378
379     PyList_SET_ITEM (list, 0, dict);
380     PyDict_SetItem (result, py_family, list);
381     Py_DECREF (list);
382   } else {
383     PyList_Append (list, dict);
384     Py_DECREF (dict);
385   }
386
387   return TRUE;
388 }
389
390 static PyObject *
391 ifaddrs (PyObject *self, PyObject *args)
392 {
393   const char *ifname;
394   PyObject *result;
395   int found = FALSE;
396 #if defined(WIN32)
397   PIP_ADAPTER_INFO pAdapterInfo = NULL;
398   PIP_ADAPTER_INFO pInfo = NULL;
399   ULONG ulBufferLength = 0;
400   DWORD dwRet;
401   PIP_ADDR_STRING str;
402 #endif
403
404   if (!PyArg_ParseTuple (args, "s", &ifname))
405     return NULL;
406
407   result = PyDict_New ();
408
409   if (!result)
410     return NULL;
411
412 #if defined(WIN32)
413   /* First, retrieve the adapter information.  We do this in a loop, in
414      case someone adds or removes adapters in the meantime. */
415   do {
416     dwRet = GetAdaptersInfo(pAdapterInfo, &ulBufferLength);
417
418     if (dwRet == ERROR_BUFFER_OVERFLOW) {
419       if (pAdapterInfo)
420         free (pAdapterInfo);
421       pAdapterInfo = (PIP_ADAPTER_INFO)malloc (ulBufferLength);
422
423       if (!pAdapterInfo) {
424         Py_DECREF (result);
425         PyErr_SetString (PyExc_MemoryError, "Not enough memory");
426         return NULL;
427       }
428     }
429   } while (dwRet == ERROR_BUFFER_OVERFLOW);
430
431   /* If we failed, then fail in Python too */
432   if (dwRet != ERROR_SUCCESS && dwRet != ERROR_NO_DATA) {
433     Py_DECREF (result);
434     if (pAdapterInfo)
435       free (pAdapterInfo);
436
437     PyErr_SetString (PyExc_OSError,
438                      "Unable to obtain adapter information.");
439     return NULL;
440   }
441
442   for (pInfo = pAdapterInfo; pInfo; pInfo = pInfo->Next) {
443     char buffer[256];
444
445     if (strcmp (pInfo->AdapterName, ifname) != 0)
446       continue;
447
448     found = TRUE;
449
450     /* Do the physical address */
451     if (256 >= 3 * pInfo->AddressLength) {
452       PyObject *hwaddr, *dict;
453       char *ptr = buffer;
454       unsigned n;
455       
456       *ptr = '\0';
457       for (n = 0; n < pInfo->AddressLength; ++n) {
458         sprintf (ptr, "%02x:", pInfo->Address[n] & 0xff);
459         ptr += 3;
460       }
461       *--ptr = '\0';
462
463       hwaddr = PyString_FromString (buffer);
464       dict = PyDict_New ();
465
466       if (!dict) {
467         Py_XDECREF (hwaddr);
468         Py_DECREF (result);
469         free (pAdapterInfo);
470         return NULL;
471       }
472
473       PyDict_SetItemString (dict, "addr", hwaddr);
474       Py_DECREF (hwaddr);
475
476       if (!add_to_family (result, AF_LINK, dict)) {
477         Py_DECREF (result);
478         free (pAdapterInfo);
479         return NULL;
480       }
481     }
482
483     for (str = &pInfo->IpAddressList; str; str = str->Next) {
484       PyObject *addr = PyString_FromString (str->IpAddress.String);
485       PyObject *mask = PyString_FromString (str->IpMask.String);
486       PyObject *bcast = NULL;
487       PyObject *dict;
488
489       /* If this isn't the loopback interface, work out the broadcast
490          address, for better compatibility with other platforms. */
491       if (pInfo->Type != MIB_IF_TYPE_LOOPBACK) {
492         unsigned long inaddr = inet_addr (str->IpAddress.String);
493         unsigned long inmask = inet_addr (str->IpMask.String);
494         struct in_addr in;
495         char *brstr;
496
497         in.S_un.S_addr = (inaddr | ~inmask) & 0xfffffffful;
498
499         brstr = inet_ntoa (in);
500
501         if (brstr)
502           bcast = PyString_FromString (brstr);
503       }
504
505       dict = PyDict_New ();
506
507       if (!dict) {
508         Py_XDECREF (addr);
509         Py_XDECREF (mask);
510         Py_XDECREF (bcast);
511         Py_DECREF (result);
512         free (pAdapterInfo);
513         return NULL;
514       }
515
516       if (addr)
517         PyDict_SetItemString (dict, "addr", addr);
518       if (mask)
519         PyDict_SetItemString (dict, "netmask", mask);
520       if (bcast)
521         PyDict_SetItemString (dict, "broadcast", bcast);
522
523       Py_XDECREF (addr);
524       Py_XDECREF (mask);
525       Py_XDECREF (bcast);
526
527       if (!add_to_family (result, AF_INET, dict)) {
528         Py_DECREF (result);
529         free (pAdapterInfo);
530         return NULL;
531       }
532     }
533   }
534
535   free (pAdapterInfo);
536 #elif HAVE_GETIFADDRS
537   struct ifaddrs *addrs = NULL;
538   struct ifaddrs *addr = NULL;
539
540   if (getifaddrs (&addrs) < 0) {
541     Py_DECREF (result);
542     PyErr_SetFromErrno (PyExc_OSError);
543     return NULL;
544   }
545
546   for (addr = addrs; addr; addr = addr->ifa_next) {
547     char buffer[256];
548     PyObject *pyaddr = NULL, *netmask = NULL, *braddr = NULL;
549
550     if (strcmp (addr->ifa_name, ifname) != 0)
551       continue;
552  
553     /* Sometimes there are records without addresses (e.g. in the case of a
554        dial-up connection via ppp, which on Linux can have a link address
555        record with no actual address).  We skip these as they aren't useful.
556        Thanks to Christian Kauhaus for reporting this issue. */
557     if (!addr->ifa_addr)
558       continue;  
559
560     found = TRUE;
561
562     if (string_from_sockaddr (addr->ifa_addr, buffer, sizeof (buffer)) == 0)
563       pyaddr = PyString_FromString (buffer);
564
565     if (string_from_sockaddr (addr->ifa_netmask, buffer, sizeof (buffer)) == 0)
566       netmask = PyString_FromString (buffer);
567
568     if (string_from_sockaddr (addr->ifa_broadaddr, buffer, sizeof (buffer)) == 0)
569       braddr = PyString_FromString (buffer);
570
571     PyObject *dict = PyDict_New();
572
573     if (!dict) {
574       Py_XDECREF (pyaddr);
575       Py_XDECREF (netmask);
576       Py_XDECREF (braddr);
577       Py_DECREF (result);
578       freeifaddrs (addrs);
579       return NULL;
580     }
581
582     if (pyaddr)
583       PyDict_SetItemString (dict, "addr", pyaddr);
584     if (netmask)
585       PyDict_SetItemString (dict, "netmask", netmask);
586
587     if (braddr) {
588       if (addr->ifa_flags & (IFF_POINTOPOINT | IFF_LOOPBACK))
589         PyDict_SetItemString (dict, "peer", braddr);
590       else
591         PyDict_SetItemString (dict, "broadcast", braddr);
592     }
593
594     Py_XDECREF (pyaddr);
595     Py_XDECREF (netmask);
596     Py_XDECREF (braddr);
597
598     if (!add_to_family (result, addr->ifa_addr->sa_family, dict)) {
599       Py_DECREF (result);
600       freeifaddrs (addrs);
601       return NULL;
602     }
603   }
604
605   freeifaddrs (addrs);
606 #elif HAVE_SOCKET_IOCTLS
607   
608   int sock = socket(AF_INET, SOCK_DGRAM, 0);
609
610   if (sock < 0) {
611     Py_DECREF (result);
612     PyErr_SetFromErrno (PyExc_OSError);
613     return NULL;
614   }
615
616   struct CNAME(ifreq) ifr;
617   PyObject *addr = NULL, *netmask = NULL, *braddr = NULL, *dstaddr = NULL;
618   int is_p2p = FALSE;
619   char buffer[256];
620
621   strncpy (ifr.CNAME(ifr_name), ifname, IFNAMSIZ);
622
623 #if HAVE_SIOCGIFHWADDR
624   if (ioctl (sock, SIOCGIFHWADDR, &ifr) == 0) {
625     found = TRUE;
626
627     if (string_from_sockaddr (ifr->CNAME(ifr_addr), buffer, sizeof (buffer)) == 0) {
628       PyObject *hwaddr = PyString_FromString (buffer);
629       PyObject *dict = PyDict_New ();
630       PyObject *list = PyList_New (1);
631       PyObject *family = PyInt_FromLong (AF_LINK);
632
633       if (!hwaddr || !dict || !list || !family) {
634         Py_XDECREF (hwaddr);
635         Py_XDECREF (dict);
636         Py_XDECREF (list)
637         Py_XDECREF (family);
638         Py_XDECREF (result);
639         close (sock);
640         return NULL;
641       }
642
643       PyDict_SetItemString (dict, "addr", hwaddr);
644       Py_DECREF (hwaddr);
645
646       PyList_SET_ITEM (list, 0, dict);
647
648       PyDict_SetItem (result, family, list);
649       Py_DECREF (family);
650       Py_DECREF (list);
651     }
652   }
653 #endif
654
655 #if HAVE_SIOCGIFADDR
656 #if HAVE_SIOCGLIFNUM
657   if (ioctl (sock, SIOCGLIFADDR, &ifr) == 0) {
658 #else
659   if (ioctl (sock, SIOCGIFADDR, &ifr) == 0) {
660 #endif
661     found = TRUE;
662
663     if (string_from_sockaddr ((struct sockaddr *)&ifr.CNAME(ifr_addr), buffer, sizeof (buffer)) == 0)
664       addr = PyString_FromString (buffer);
665   }
666 #endif
667
668 #if HAVE_SIOCGIFNETMASK
669 #if HAVE_SIOCGLIFNUM
670   if (ioctl (sock, SIOCGLIFNETMASK, &ifr) == 0) {
671 #else
672   if (ioctl (sock, SIOCGIFNETMASK, &ifr) == 0) {
673 #endif
674     found = TRUE;
675
676     if (string_from_sockaddr ((struct sockaddr *)&ifr.CNAME(ifr_addr), buffer, sizeof (buffer)) == 0)
677       netmask = PyString_FromString (buffer);
678   }
679 #endif
680
681 #if HAVE_SIOCGIFFLAGS
682 #if HAVE_SIOCGLIFNUM
683   if (ioctl (sock, SIOCGLIFFLAGS, &ifr) == 0) {
684 #else
685   if (ioctl (sock, SIOCGIFFLAGS, &ifr) == 0) {
686 #endif
687     found = TRUE;
688
689     if (ifr.CNAME(ifr_flags) & IFF_POINTOPOINT)
690       is_p2p = TRUE;
691   }
692 #endif
693
694 #if HAVE_SIOCGIFBRDADDR
695 #if HAVE_SIOCGLIFNUM
696   if (!is_p2p && ioctl (sock, SIOCGLIFBRDADDR, &ifr) == 0) {
697 #else
698   if (!is_p2p && ioctl (sock, SIOCGIFBRDADDR, &ifr) == 0) {
699 #endif
700     found = TRUE;
701
702     if (string_from_sockaddr ((struct sockaddr *)&ifr.CNAME(ifr_addr), buffer, sizeof (buffer)) == 0)
703       braddr = PyString_FromString (buffer);
704   }
705 #endif
706
707 #if HAVE_SIOCGIFDSTADDR
708 #if HAVE_SIOCGLIFNUM
709   if (is_p2p && ioctl (sock, SIOCGLIFBRDADDR, &ifr) == 0) {
710 #else
711   if (is_p2p && ioctl (sock, SIOCGIFBRDADDR, &ifr) == 0) {
712 #endif
713     found = TRUE;
714
715     if (string_from_sockaddr ((struct sockaddr *)&ifr.CNAME(ifr_addr), buffer, sizeof (buffer)) == 0)
716       dstaddr = PyString_FromString (buffer);
717   }
718 #endif
719
720   PyObject *dict = PyDict_New();
721
722   if (!dict) {
723     Py_XDECREF (addr);
724     Py_XDECREF (netmask);
725     Py_XDECREF (braddr);
726     Py_XDECREF (dstaddr);
727     Py_DECREF (result);
728     close (sock);
729     return NULL;
730   }
731
732   if (addr)
733     PyDict_SetItemString (dict, "addr", addr);
734   if (netmask)
735     PyDict_SetItemString (dict, "netmask", netmask);
736   if (braddr)
737     PyDict_SetItemString (dict, "broadcast", braddr);
738   if (dstaddr)
739     PyDict_SetItemString (dict, "peer", dstaddr);
740
741   Py_XDECREF (addr);
742   Py_XDECREF (netmask);
743   Py_XDECREF (braddr);
744   Py_XDECREF (dstaddr);
745
746   if (!PyDict_Size (dict))
747     Py_DECREF (dict);
748   else {
749     PyObject *list = PyList_New(1);
750   
751     if (!list) {
752       Py_DECREF (dict);
753       Py_DECREF (result);
754       close (sock);
755       return NULL;
756     }
757
758     PyList_SET_ITEM (list, 0, dict);
759
760     PyObject *family = PyInt_FromLong (AF_INET);
761     if (!family) {
762       Py_DECREF (result);
763       Py_DECREF (list);
764       close (sock);
765       return NULL;
766     }
767
768     PyDict_SetItem (result, family, list);
769     Py_DECREF (family);
770     Py_DECREF (list);
771   }
772
773   close (sock);
774
775 #endif /* HAVE_SOCKET_IOCTLS */
776
777   if (found)
778     return result;
779   else {
780     Py_DECREF (result);
781     PyErr_SetString (PyExc_ValueError, 
782                      "You must specify a valid interface name.");
783     return NULL;
784   }
785 }
786
787 static PyObject *
788 interfaces (PyObject *self)
789 {
790   PyObject *result;
791
792 #if defined(WIN32)
793   PIP_ADAPTER_INFO pAdapterInfo = NULL;
794   PIP_ADAPTER_INFO pInfo = NULL;
795   ULONG ulBufferLength = 0;
796   DWORD dwRet;
797
798   /* First, retrieve the adapter information */
799   do {
800     dwRet = GetAdaptersInfo(pAdapterInfo, &ulBufferLength);
801
802     if (dwRet == ERROR_BUFFER_OVERFLOW) {
803       if (pAdapterInfo)
804         free (pAdapterInfo);
805       pAdapterInfo = (PIP_ADAPTER_INFO)malloc (ulBufferLength);
806
807       if (!pAdapterInfo) {
808         PyErr_SetString (PyExc_MemoryError, "Not enough memory");
809         return NULL;
810       }
811     }
812   } while (dwRet == ERROR_BUFFER_OVERFLOW);
813
814   /* If we failed, then fail in Python too */
815   if (dwRet != ERROR_SUCCESS && dwRet != ERROR_NO_DATA) {
816     if (pAdapterInfo)
817       free (pAdapterInfo);
818
819     PyErr_SetString (PyExc_OSError,
820                      "Unable to obtain adapter information.");
821     return NULL;
822   }
823
824   result = PyList_New(0);
825
826   if (dwRet == ERROR_NO_DATA) {
827     free (pAdapterInfo);
828     return result;
829   }
830
831   for (pInfo = pAdapterInfo; pInfo; pInfo = pInfo->Next) {
832     PyObject *ifname = PyString_FromString (pInfo->AdapterName);
833
834     PyList_Append (result, ifname);
835     Py_DECREF (ifname);
836   }
837
838   free (pAdapterInfo);
839 #elif HAVE_GETIFADDRS
840   const char *prev_name = NULL;
841   struct ifaddrs *addrs = NULL;
842   struct ifaddrs *addr = NULL;
843
844   result = PyList_New (0);
845
846   if (getifaddrs (&addrs) < 0) {
847     Py_DECREF (result);
848     PyErr_SetFromErrno (PyExc_OSError);
849     return NULL;
850   }
851
852   for (addr = addrs; addr; addr = addr->ifa_next) {
853     if (!prev_name || strncmp (addr->ifa_name, prev_name, IFNAMSIZ) != 0) {
854       PyObject *ifname = PyString_FromString (addr->ifa_name);
855     
856       if (!PySequence_Contains (result, ifname))
857         PyList_Append (result, ifname);
858       Py_DECREF (ifname);
859       prev_name = addr->ifa_name;
860     }
861   }
862
863   freeifaddrs (addrs);
864 #elif HAVE_SIOCGIFCONF
865   const char *prev_name = NULL;
866   int fd = socket (AF_INET, SOCK_DGRAM, 0);
867   struct CNAME(ifconf) ifc;
868   int len = -1, n;
869
870   if (fd < 0) {
871     PyErr_SetFromErrno (PyExc_OSError);
872     return NULL;
873   }
874
875   // Try to find out how much space we need
876 #if HAVE_SIOCGSIZIFCONF
877   if (ioctl (fd, SIOCGSIZIFCONF, &len) < 0)
878     len = -1;
879 #elif HAVE_SIOCGLIFNUM
880   { struct lifnum lifn;
881     lifn.lifn_family = AF_UNSPEC;
882     lifn.lifn_flags = LIFC_NOXMIT | LIFC_TEMPORARY | LIFC_ALLZONES;
883     ifc.lifc_family = AF_UNSPEC;
884     ifc.lifc_flags = LIFC_NOXMIT | LIFC_TEMPORARY | LIFC_ALLZONES;
885     if (ioctl (fd, SIOCGLIFNUM, (char *)&lifn) < 0)
886       len = -1;
887     else
888       len = lifn.lifn_count;
889   }
890 #endif
891
892   // As a last resort, guess
893   if (len < 0)
894     len = 64;
895
896   ifc.CNAME(ifc_len) = len * sizeof (struct CNAME(ifreq));
897   ifc.CNAME(ifc_buf) = malloc (ifc.CNAME(ifc_len));
898
899   if (!ifc.CNAME(ifc_buf)) {
900     PyErr_SetString (PyExc_MemoryError, "Not enough memory");
901     close (fd);
902     return NULL;
903   }
904
905 #if HAVE_SIOCGLIFNUM
906   if (ioctl (fd, SIOCGLIFCONF, &ifc) < 0) {
907 #else
908   if (ioctl (fd, SIOCGIFCONF, &ifc) < 0) {
909 #endif
910     free (ifc.CNAME(ifc_req));
911     PyErr_SetFromErrno (PyExc_OSError);
912     close (fd);
913     return NULL;
914   }
915
916   result = PyList_New (0);
917   struct CNAME(ifreq) *pfreq = ifc.CNAME(ifc_req);
918   for (n = 0; n < ifc.CNAME(ifc_len)/sizeof(struct CNAME(ifreq));
919       n++,pfreq++) {
920     if (!prev_name || strncmp (prev_name, pfreq->CNAME(ifr_name), IFNAMSIZ) != 0) {
921       PyObject *name = PyString_FromString (pfreq->CNAME(ifr_name));
922
923       if (!PySequence_Contains (result, name))
924         PyList_Append (result, name);
925       Py_XDECREF (name);
926
927       prev_name = pfreq->CNAME(ifr_name);
928     }
929   }
930
931   free (ifc.CNAME(ifc_buf));
932   close (fd);
933 #endif /* HAVE_SIOCGIFCONF */
934
935   return result;
936 }
937
938 static PyMethodDef methods[] = {
939   { "ifaddresses", (PyCFunction)ifaddrs, METH_VARARGS,
940     "Obtain information about the specified network interface.\n"
941 "\n"
942 "Returns a dict whose keys are equal to the address family constants,\n"
943 "e.g. netifaces.AF_INET, and whose values are a list of addresses in\n"
944 "that family that are attached to the network interface." },
945   { "interfaces", (PyCFunction)interfaces, METH_NOARGS,
946     "Obtain a list of the interfaces available on this machine." },
947   { NULL, NULL, 0, NULL }
948 };
949
950 PyMODINIT_FUNC
951 initnetifaces (void)
952 {
953   PyObject *m;
954
955 #ifdef WIN32
956   WSADATA wsad;
957   int iResult;
958   
959   iResult = WSAStartup(MAKEWORD (2, 2), &wsad);
960 #endif
961
962   m = Py_InitModule ("netifaces", methods);
963
964   /* Address families (auto-detect using #ifdef) */
965   PyObject *address_family_dict = PyDict_New();
966 #ifdef AF_UNSPEC  
967   PyModule_AddIntConstant (m, "AF_UNSPEC", AF_UNSPEC);
968   PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_UNSPEC),
969           PyString_FromString("AF_UNSPEC"));
970 #endif
971 #ifdef AF_UNIX
972   PyModule_AddIntConstant (m, "AF_UNIX", AF_UNIX);
973   PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_UNIX),
974           PyString_FromString("AF_UNIX"));
975 #endif
976 #ifdef AF_FILE
977   PyModule_AddIntConstant (m, "AF_FILE", AF_FILE);
978   PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_FILE),
979           PyString_FromString("AF_FILE"));
980 #endif
981 #ifdef AF_INET
982   PyModule_AddIntConstant (m, "AF_INET", AF_INET);
983   PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_INET),
984           PyString_FromString("AF_INET"));
985 #endif
986 #ifdef AF_AX25
987   PyModule_AddIntConstant (m, "AF_AX25", AF_AX25);
988   PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_AX25),
989           PyString_FromString("AF_AX25"));
990 #endif
991 #ifdef AF_IMPLINK  
992   PyModule_AddIntConstant (m, "AF_IMPLINK", AF_IMPLINK);
993   PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_IMPLINK),
994           PyString_FromString("AF_IMPLINK"));
995 #endif
996 #ifdef AF_PUP  
997   PyModule_AddIntConstant (m, "AF_PUP", AF_PUP);
998   PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_PUP),
999           PyString_FromString("AF_PUP"));
1000 #endif
1001 #ifdef AF_CHAOS
1002   PyModule_AddIntConstant (m, "AF_CHAOS", AF_CHAOS);
1003   PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_CHAOS),
1004           PyString_FromString("AF_CHAOS"));
1005 #endif
1006 #ifdef AF_NS
1007   PyModule_AddIntConstant (m, "AF_NS", AF_NS);
1008   PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_NS),
1009           PyString_FromString("AF_NS"));
1010 #endif
1011 #ifdef AF_ISO
1012   PyModule_AddIntConstant (m, "AF_ISO", AF_ISO);
1013   PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_ISO),
1014           PyString_FromString("AF_ISO"));
1015 #endif
1016 #ifdef AF_ECMA
1017   PyModule_AddIntConstant (m, "AF_ECMA", AF_ECMA);
1018   PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_ECMA),
1019           PyString_FromString("AF_ECMA"));
1020 #endif
1021 #ifdef AF_DATAKIT
1022   PyModule_AddIntConstant (m, "AF_DATAKIT", AF_DATAKIT);
1023   PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_DATAKIT),
1024           PyString_FromString("AF_DATAKIT"));
1025 #endif
1026 #ifdef AF_CCITT
1027   PyModule_AddIntConstant (m, "AF_CCITT", AF_CCITT);
1028   PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_CCITT),
1029           PyString_FromString("AF_CCITT"));
1030 #endif
1031 #ifdef AF_SNA
1032   PyModule_AddIntConstant (m, "AF_SNA", AF_SNA);
1033   PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_SNA),
1034           PyString_FromString("AF_SNA"));
1035 #endif
1036 #ifdef AF_DECnet
1037   PyModule_AddIntConstant (m, "AF_DECnet", AF_DECnet);
1038   PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_DECnet),
1039           PyString_FromString("AF_DECnet"));
1040 #endif
1041 #ifdef AF_DLI
1042   PyModule_AddIntConstant (m, "AF_DLI", AF_DLI);
1043   PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_DLI),
1044           PyString_FromString("AF_DLI"));
1045 #endif
1046 #ifdef AF_LAT
1047   PyModule_AddIntConstant (m, "AF_LAT", AF_LAT);
1048   PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_LAT),
1049           PyString_FromString("AF_LAT"));
1050 #endif
1051 #ifdef AF_HYLINK
1052   PyModule_AddIntConstant (m, "AF_HYLINK", AF_HYLINK);
1053   PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_HYLINK),
1054           PyString_FromString("AF_HYLINK"));
1055 #endif
1056 #ifdef AF_APPLETALK
1057   PyModule_AddIntConstant (m, "AF_APPLETALK", AF_APPLETALK);
1058   PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_APPLETALK),
1059           PyString_FromString("AF_APPLETALK"));
1060 #endif
1061 #ifdef AF_ROUTE
1062   PyModule_AddIntConstant (m, "AF_ROUTE", AF_ROUTE);
1063   PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_ROUTE),
1064           PyString_FromString("AF_ROUTE"));
1065 #endif
1066 #ifdef AF_LINK
1067   PyModule_AddIntConstant (m, "AF_LINK", AF_LINK);
1068   PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_LINK),
1069           PyString_FromString("AF_LINK"));
1070 #endif
1071 #ifdef AF_PACKET
1072   PyModule_AddIntConstant (m, "AF_PACKET", AF_PACKET);
1073   PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_PACKET),
1074           PyString_FromString("AF_PACKET"));
1075 #endif
1076 #ifdef AF_COIP
1077   PyModule_AddIntConstant (m, "AF_COIP", AF_COIP);
1078   PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_COIP),
1079           PyString_FromString("AF_COIP"));
1080 #endif
1081 #ifdef AF_CNT
1082   PyModule_AddIntConstant (m, "AF_CNT", AF_CNT);
1083   PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_CNT),
1084           PyString_FromString("AF_CNT"));
1085 #endif
1086 #ifdef AF_IPX
1087   PyModule_AddIntConstant (m, "AF_IPX", AF_IPX);
1088   PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_IPX),
1089           PyString_FromString("AF_IPX"));
1090 #endif
1091 #ifdef AF_SIP
1092   PyModule_AddIntConstant (m, "AF_SIP", AF_SIP);
1093   PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_SIP),
1094           PyString_FromString("AF_SIP"));
1095 #endif
1096 #ifdef AF_NDRV
1097   PyModule_AddIntConstant (m, "AF_NDRV", AF_NDRV);
1098   PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_NDRV),
1099           PyString_FromString("AF_NDRV"));
1100 #endif
1101 #ifdef AF_ISDN
1102   PyModule_AddIntConstant (m, "AF_ISDN", AF_ISDN);
1103   PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_ISDN),
1104           PyString_FromString("AF_ISDN"));
1105 #endif
1106 #ifdef AF_INET6
1107   PyModule_AddIntConstant (m, "AF_INET6", AF_INET6);
1108   PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_INET6),
1109           PyString_FromString("AF_INET6"));
1110 #endif
1111 #ifdef AF_NATM
1112   PyModule_AddIntConstant (m, "AF_NATM", AF_NATM);
1113   PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_NATM),
1114           PyString_FromString("AF_NATM"));
1115 #endif
1116 #ifdef AF_SYSTEM
1117   PyModule_AddIntConstant (m, "AF_SYSTEM", AF_SYSTEM);
1118   PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_SYSTEM),
1119           PyString_FromString("AF_SYSTEM"));
1120 #endif
1121 #ifdef AF_NETBIOS
1122   PyModule_AddIntConstant (m, "AF_NETBIOS", AF_NETBIOS);
1123   PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_NETBIOS),
1124           PyString_FromString("AF_NETBIOS"));
1125 #endif
1126 #ifdef AF_NETBEUI
1127   PyModule_AddIntConstant (m, "AF_NETBEUI", AF_NETBEUI);
1128   PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_NETBEUI),
1129           PyString_FromString("AF_NETBEUI"));
1130 #endif
1131 #ifdef AF_PPP
1132   PyModule_AddIntConstant (m, "AF_PPP", AF_PPP);
1133   PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_PPP),
1134           PyString_FromString("AF_PPP"));
1135 #endif
1136 #ifdef AF_ATM
1137   PyModule_AddIntConstant (m, "AF_ATM", AF_ATM);
1138   PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_ATM),
1139           PyString_FromString("AF_ATM"));
1140 #endif
1141 #ifdef AF_ATMPVC
1142   PyModule_AddIntConstant (m, "AF_ATMPVC", AF_ATMPVC);
1143   PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_ATMPVC),
1144           PyString_FromString("AF_ATMPVC"));
1145 #endif
1146 #ifdef AF_ATMSVC
1147   PyModule_AddIntConstant (m, "AF_ATMSVC", AF_ATMSVC);
1148   PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_ATMSVC),
1149           PyString_FromString("AF_ATMSVC"));
1150 #endif
1151 #ifdef AF_NETGRAPH
1152   PyModule_AddIntConstant (m, "AF_NETGRAPH", AF_NETGRAPH);
1153   PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_NETGRAPH),
1154           PyString_FromString("AF_NETGRAPH"));
1155 #endif
1156 #ifdef AF_VOICEVIEW
1157   PyModule_AddIntConstant (m, "AF_VOICEVIEW", AF_VOICEVIEW);
1158   PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_VOICEVIEW),
1159           PyString_FromString("AF_VOICEVIEW"));
1160 #endif
1161 #ifdef AF_FIREFOX
1162   PyModule_AddIntConstant (m, "AF_FIREFOX", AF_FIREFOX);
1163   PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_FIREFOX),
1164           PyString_FromString("AF_FIREFOX"));
1165 #endif
1166 #ifdef AF_UNKNOWN1
1167   PyModule_AddIntConstant (m, "AF_UNKNOWN1", AF_UNKNOWN1);
1168   PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_UNKNOWN1),
1169           PyString_FromString("AF_UNKNOWN1"));
1170 #endif
1171 #ifdef AF_BAN
1172   PyModule_AddIntConstant (m, "AF_BAN", AF_BAN);
1173   PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_BAN),
1174           PyString_FromString("AF_BAN"));
1175 #endif
1176 #ifdef AF_CLUSTER
1177   PyModule_AddIntConstant (m, "AF_CLUSTER", AF_CLUSTER);
1178   PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_CLUSTER),
1179           PyString_FromString("AF_CLUSTER"));
1180 #endif
1181 #ifdef AF_12844
1182   PyModule_AddIntConstant (m, "AF_12844", AF_12844);
1183   PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_12844),
1184           PyString_FromString("AF_12844"));
1185 #endif
1186 #ifdef AF_IRDA
1187   PyModule_AddIntConstant (m, "AF_IRDA", AF_IRDA);
1188   PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_IRDA),
1189           PyString_FromString("AF_IRDA"));
1190 #endif
1191 #ifdef AF_NETDES
1192   PyModule_AddIntConstant (m, "AF_NETDES", AF_NETDES);
1193   PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_NETDES),
1194           PyString_FromString("AF_NETDES"));
1195 #endif
1196 #ifdef AF_NETROM
1197   PyModule_AddIntConstant (m, "AF_NETROM", AF_NETROM);
1198   PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_NETROM),
1199           PyString_FromString("AF_NETROM"));
1200 #endif
1201 #ifdef AF_BRIDGE
1202   PyModule_AddIntConstant (m, "AF_BRIDGE", AF_BRIDGE);
1203   PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_BRIDGE),
1204           PyString_FromString("AF_BRIDGE"));
1205 #endif
1206 #ifdef AF_X25
1207   PyModule_AddIntConstant (m, "AF_X25", AF_X25);
1208   PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_X25),
1209           PyString_FromString("AF_X25"));
1210 #endif
1211 #ifdef AF_ROSE
1212   PyModule_AddIntConstant (m, "AF_ROSE", AF_ROSE);
1213   PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_ROSE),
1214           PyString_FromString("AF_ROSE"));
1215 #endif
1216 #ifdef AF_SECURITY
1217   PyModule_AddIntConstant (m, "AF_SECURITY", AF_SECURITY);
1218   PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_SECURITY),
1219           PyString_FromString("AF_SECURITY"));
1220 #endif
1221 #ifdef AF_KEY
1222   PyModule_AddIntConstant (m, "AF_KEY", AF_KEY);
1223   PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_KEY),
1224           PyString_FromString("AF_KEY"));
1225 #endif
1226 #ifdef AF_NETLINK
1227   PyModule_AddIntConstant (m, "AF_NETLINK", AF_NETLINK);
1228   PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_NETLINK),
1229           PyString_FromString("AF_NETLINK"));
1230 #endif
1231 #ifdef AF_ASH
1232   PyModule_AddIntConstant (m, "AF_ASH", AF_ASH);
1233   PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_ASH),
1234           PyString_FromString("AF_ASH"));
1235 #endif
1236 #ifdef AF_ECONET
1237   PyModule_AddIntConstant (m, "AF_ECONET", AF_ECONET);
1238   PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_ECONET),
1239           PyString_FromString("AF_ECONET"));
1240 #endif
1241 #ifdef AF_SNA
1242   PyModule_AddIntConstant (m, "AF_SNA", AF_SNA);
1243   PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_SNA),
1244           PyString_FromString("AF_SNA"));
1245 #endif
1246 #ifdef AF_PPPOX
1247   PyModule_AddIntConstant (m, "AF_PPPOX", AF_PPPOX);
1248   PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_PPPOX),
1249           PyString_FromString("AF_PPPOX"));
1250 #endif
1251 #ifdef AF_WANPIPE
1252   PyModule_AddIntConstant (m, "AF_WANPIPE", AF_WANPIPE);
1253   PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_WANPIPE),
1254           PyString_FromString("AF_WANPIPE"));
1255 #endif
1256 #ifdef AF_BLUETOOTH
1257   PyModule_AddIntConstant (m, "AF_BLUETOOTH", AF_BLUETOOTH);
1258   PyDict_SetItem(address_family_dict, PyInt_FromLong(AF_BLUETOOTH),
1259           PyString_FromString("AF_BLUETOOTH"));
1260 #endif
1261   PyModule_AddObject(m, "address_families", address_family_dict);
1262 }