src/windows/native/java/net/NetworkInterface.c

Print this page




  70 static EnumerateNetAddresses enumAddresses_fn;
  71 
  72 /* Windows 9x routines are external (not needed on 64-bit) */
  73 #ifndef _WIN64
  74 extern int enumInterfaces_win9x(JNIEnv *, netif **);
  75 extern int enumAddresses_win9x(JNIEnv *, netif *, netaddr **);
  76 extern int init_win9x(void);
  77 #endif
  78 
  79 
  80 /* Windows 95/98/ME running */
  81 static jboolean isW9x;
  82 
  83 /* Windows version supports */
  84 static jboolean os_supports_ipv6;
  85 
  86 /* various JNI ids */
  87 
  88 jclass ni_class;            /* NetworkInterface */
  89 
  90 jmethodID ni_ctor;          /* NetworkInterface() */
  91 
  92 jfieldID ni_indexID;        /* NetworkInterface.index */
  93 jfieldID ni_addrsID;        /* NetworkInterface.addrs */
  94 jfieldID ni_bindsID;        /* NetworkInterface.bindings */
  95 jfieldID ni_nameID;         /* NetworkInterface.name */
  96 jfieldID ni_displayNameID;  /* NetworkInterface.displayName */
  97 jfieldID ni_childsID;       /* NetworkInterface.childs */
  98 jclass ni_iacls;            /* InetAddress */
  99 jfieldID ni_iaAddr;         /* InetAddress.address */
 100 
 101 jclass ni_ia4cls;           /* Inet4Address */
 102 jmethodID ni_ia4Ctor;       /* Inet4Address() */
 103 
 104 jclass ni_ia6cls;           /* Inet6Address */
 105 jmethodID ni_ia6ctrID;      /* Inet6Address() */
 106 jfieldID ni_ia6ipaddressID;
 107 jfieldID ni_ia6ipaddressID;
 108 
 109 jclass ni_ibcls;            /* InterfaceAddress */
 110 jmethodID ni_ibctrID;       /* InterfaceAddress() */
 111 jfieldID ni_ibaddressID;        /* InterfaceAddress.address */
 112 jfieldID ni_ibbroadcastID;      /* InterfaceAddress.broadcast */
 113 jfieldID ni_ibmaskID;           /* InterfaceAddress.maskLength */
 114 
 115 /*
 116  * Support routines to free netif and netaddr lists
 117  */
 118 void free_netif(netif *netifP) {
 119     netif *curr = netifP;
 120     while (curr != NULL) {
 121         if (curr->name != NULL)
 122             free(curr->name);
 123         if (curr->displayName != NULL)
 124             free(curr->displayName);
 125         if (curr->addrs != NULL)
 126             free_netaddr (curr->addrs);
 127         netifP = netifP->next;
 128         free(curr);


 528         if (isW9x) {
 529             /* Use Windows 9x registry approach which requires initialization */
 530             enumInterfaces_fn = enumInterfaces_win9x;
 531             enumAddresses_fn = enumAddresses_win9x;
 532             init_win9x();
 533         } else
 534 #endif
 535         {
 536             JNU_ThrowByName(env, "java/lang/Error",
 537                 "Incompatible IP helper library (iphlpapi.dll)");
 538             return;
 539         }
 540     } else {
 541         enumInterfaces_fn = enumInterfaces_win;
 542         enumAddresses_fn = enumAddresses_win;
 543     }
 544 
 545     /*
 546      * Get the various JNI ids that we require
 547      */

 548     ni_class = (*env)->NewGlobalRef(env, cls);
 549     ni_nameID = (*env)->GetFieldID(env, ni_class, "name", "Ljava/lang/String;");
 550     ni_displayNameID = (*env)->GetFieldID(env, ni_class, "displayName", "Ljava/lang/String;");
 551     ni_indexID = (*env)->GetFieldID(env, ni_class, "index", "I");
 552     ni_addrsID = (*env)->GetFieldID(env, ni_class, "addrs", "[Ljava/net/InetAddress;");
 553     ni_bindsID = (*env)->GetFieldID(env, ni_class, "bindings", "[Ljava/net/InterfaceAddress;");
 554     ni_childsID = (*env)->GetFieldID(env, ni_class, "childs", "[Ljava/net/NetworkInterface;");
 555     ni_ctor = (*env)->GetMethodID(env, ni_class, "<init>", "()V");
 556 
 557     ni_iacls = (*env)->FindClass(env, "java/net/InetAddress");
 558     ni_iacls = (*env)->NewGlobalRef(env, ni_iacls);
 559     ni_iaAddr = (*env)->GetFieldID(env, ni_iacls, "address", "I");
 560 
 561     ni_ia4cls = (*env)->FindClass(env, "java/net/Inet4Address");
 562     ni_ia4cls = (*env)->NewGlobalRef(env, ni_ia4cls);
 563     ni_ia4Ctor = (*env)->GetMethodID(env, ni_ia4cls, "<init>", "()V");
 564 
 565     ni_ia6cls = (*env)->FindClass(env, "java/net/Inet6Address");
 566     ni_ia6cls = (*env)->NewGlobalRef(env, ni_ia6cls);
 567     ni_ia6ctrID = (*env)->GetMethodID(env, ni_ia6cls, "<init>", "()V");
 568     ni_ia6ipaddressID = (*env)->GetFieldID(env, ni_ia6cls, "ipaddress", "[B");
 569 
 570     ni_ibcls = (*env)->FindClass(env, "java/net/InterfaceAddress");
 571     ni_ibcls = (*env)->NewGlobalRef(env, ni_ibcls);
 572     ni_ibctrID = (*env)->GetMethodID(env, ni_ibcls, "<init>", "()V");
 573     ni_ibaddressID = (*env)->GetFieldID(env, ni_ibcls, "address", "Ljava/net/InetAddress;");
 574     ni_ibbroadcastID = (*env)->GetFieldID(env, ni_ibcls, "broadcast", "Ljava/net/Inet4Address;");
 575     ni_ibmaskID = (*env)->GetFieldID(env, ni_ibcls, "maskLength", "S");
 576 
 577 }
 578 
 579 /*
 580  * Create a NetworkInterface object, populate the name and index, and
 581  * populate the InetAddress array based on the IP addresses for this
 582  * interface.
 583  */
 584 jobject createNetworkInterface(JNIEnv *env, netif *ifs, int netaddrCount, netaddr *netaddrP)
 585 {
 586     jobject netifObj;
 587     jobject name, displayName;
 588     jobjectArray addrArr, bindsArr, childArr;
 589     netaddr *addrs;
 590     jint addr_index;
 591     jint bind_index;
 592 
 593     /*
 594      * Create a NetworkInterface object and populate it
 595      */
 596     netifObj = (*env)->NewObject(env, ni_class, ni_ctor);
 597     name = (*env)->NewStringUTF(env, ifs->name);
 598     if (ifs->dNameIsUnicode) {
 599         displayName = (*env)->NewString(env, (PWCHAR)ifs->displayName, wcslen ((PWCHAR)ifs->displayName));
 600     } else {
 601         displayName = (*env)->NewStringUTF(env, ifs->displayName);
 602     }
 603     if (netifObj == NULL || name == NULL || displayName == NULL) {
 604         return NULL;
 605     }
 606     (*env)->SetObjectField(env, netifObj, ni_nameID, name);
 607     (*env)->SetObjectField(env, netifObj, ni_displayNameID, displayName);
 608     (*env)->SetIntField(env, netifObj, ni_indexID, ifs->index);
 609 
 610     /*
 611      * Get the IP addresses for this interface if necessary
 612      * Note that 0 is a valid number of addresses.
 613      */
 614     if (netaddrCount < 0) {
 615         netaddrCount = (*enumAddresses_fn)(env, ifs, &netaddrP);
 616         if ((*env)->ExceptionOccurred(env)) {
 617             free_netaddr(netaddrP);
 618             return NULL;
 619         }
 620     }
 621     addrArr = (*env)->NewObjectArray(env, netaddrCount, ni_iacls, NULL);
 622     if (addrArr == NULL) {
 623         free_netaddr(netaddrP);
 624         return NULL;
 625     }
 626 
 627     bindsArr = (*env)->NewObjectArray(env, netaddrCount, ni_ibcls, NULL);
 628     if (bindsArr == NULL) {
 629       free_netaddr(netaddrP);
 630       return NULL;
 631     }
 632     addrs = netaddrP;
 633     addr_index = 0;
 634     bind_index = 0;
 635     while (addrs != NULL) {
 636         jobject iaObj, ia2Obj;
 637         jobject ibObj = NULL;
 638         if (addrs->addr.him.sa_family == AF_INET) {
 639             iaObj = (*env)->NewObject(env, ni_ia4cls, ni_ia4Ctor);
 640             if (iaObj == NULL) {
 641                 free_netaddr(netaddrP);
 642                 return NULL;
 643             }
 644             /* default ctor will set family to AF_INET */
 645 
 646             (*env)->SetIntField(env, iaObj, ni_iaAddr, ntohl(addrs->addr.him4.sin_addr.s_addr));
 647             if (addrs->mask != -1) {
 648               ibObj = (*env)->NewObject(env, ni_ibcls, ni_ibctrID);
 649               if (ibObj == NULL) {
 650                 free_netaddr(netaddrP);
 651                 return NULL;
 652               }
 653               (*env)->SetObjectField(env, ibObj, ni_ibaddressID, iaObj);
 654               ia2Obj = (*env)->NewObject(env, ni_ia4cls, ni_ia4Ctor);
 655               if (ia2Obj == NULL) {
 656                 free_netaddr(netaddrP);
 657                 return NULL;
 658               }
 659               (*env)->SetIntField(env, ia2Obj, ni_iaAddr,
 660                                   ntohl(addrs->brdcast.him4.sin_addr.s_addr));
 661               (*env)->SetObjectField(env, ibObj, ni_ibbroadcastID, ia2Obj);
 662               (*env)->SetShortField(env, ibObj, ni_ibmaskID, addrs->mask);
 663               (*env)->SetObjectArrayElement(env, bindsArr, bind_index++, ibObj);
 664             }
 665         } else /* AF_INET6 */ {
 666             int scope;
 667             iaObj = (*env)->NewObject(env, ni_ia6cls, ni_ia6ctrID);
 668             if (iaObj) {
 669                 jbyteArray ipaddress = (*env)->NewByteArray(env, 16);
 670                 if (ipaddress == NULL) {
 671                     return NULL;
 672                 }
 673                 (*env)->SetByteArrayRegion(env, ipaddress, 0, 16,
 674                     (jbyte *)&(addrs->addr.him6.sin6_addr.s6_addr));
 675                 scope = addrs->addr.him6.sin6_scope_id;
 676                 if (scope != 0) { /* zero is default value, no need to set */
 677                     (*env)->SetIntField(env, iaObj, ia6_scopeidID, scope);
 678                     (*env)->SetBooleanField(env, iaObj, ia6_scopeidsetID, JNI_TRUE);
 679                     (*env)->SetObjectField(env, iaObj, ia6_scopeifnameID, netifObj);
 680                 }
 681                 (*env)->SetObjectField(env, iaObj, ni_ia6ipaddressID, ipaddress);
 682                 ibObj = (*env)->NewObject(env, ni_ibcls, ni_ibctrID);
 683                 if (ibObj == NULL) {
 684                   free_netaddr(netaddrP);
 685                   return NULL;
 686                 }
 687                 (*env)->SetObjectField(env, ibObj, ni_ibaddressID, iaObj);
 688                 (*env)->SetShortField(env, ibObj, ni_ibmaskID, addrs->mask);
 689                 (*env)->SetObjectArrayElement(env, bindsArr, bind_index++, ibObj);
 690             }
 691         }
 692         (*env)->SetObjectArrayElement(env, addrArr, addr_index, iaObj);
 693         addrs = addrs->next;
 694         addr_index++;
 695     }
 696     (*env)->SetObjectField(env, netifObj, ni_addrsID, addrArr);
 697     (*env)->SetObjectField(env, netifObj, ni_bindsID, bindsArr);
 698 
 699     free_netaddr(netaddrP);
 700 
 701     /*


 792     /* if found create a NetworkInterface */
 793     if (curr != NULL) {
 794         netifObj = createNetworkInterface(env, curr, -1, NULL);
 795     }
 796 
 797     /* release the interface list */
 798     free_netif(ifList);
 799 
 800     return netifObj;
 801 }
 802 
 803 /*
 804  * Class:     java_net_NetworkInterface
 805  * Method:    getByInetAddress0
 806  * Signature: (Ljava/net/InetAddress;)Ljava/net/NetworkInterface;
 807  */
 808 JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByInetAddress0
 809     (JNIEnv *env, jclass cls, jobject iaObj)
 810 {
 811     netif *ifList, *curr;
 812     jint addr = (*env)->GetIntField(env, iaObj, ni_iaAddr);
 813     jobject netifObj = NULL;
 814 
 815     if (os_supports_ipv6 && ipv6_available()) {
 816         return Java_java_net_NetworkInterface_getByInetAddress0_XP (env, cls, iaObj);
 817     }
 818 
 819     /* get the list of interfaces */
 820     if ((*enumInterfaces_fn)(env, &ifList) < 0) {
 821         return NULL;
 822     }
 823 
 824     /*
 825      * Enumerate the addresses on each interface until we find a
 826      * matching address.
 827      */
 828     curr = ifList;
 829     while (curr != NULL) {
 830         int count;
 831         netaddr *addrList;
 832         netaddr *addrP;




  70 static EnumerateNetAddresses enumAddresses_fn;
  71 
  72 /* Windows 9x routines are external (not needed on 64-bit) */
  73 #ifndef _WIN64
  74 extern int enumInterfaces_win9x(JNIEnv *, netif **);
  75 extern int enumAddresses_win9x(JNIEnv *, netif *, netaddr **);
  76 extern int init_win9x(void);
  77 #endif
  78 
  79 
  80 /* Windows 95/98/ME running */
  81 static jboolean isW9x;
  82 
  83 /* Windows version supports */
  84 static jboolean os_supports_ipv6;
  85 
  86 /* various JNI ids */
  87 
  88 jclass ni_class;            /* NetworkInterface */
  89 
  90 jmethodID ni_ctrID;          /* NetworkInterface() */
  91 
  92 jfieldID ni_indexID;        /* NetworkInterface.index */
  93 jfieldID ni_addrsID;        /* NetworkInterface.addrs */
  94 jfieldID ni_bindsID;        /* NetworkInterface.bindings */
  95 jfieldID ni_nameID;         /* NetworkInterface.name */
  96 jfieldID ni_displayNameID;  /* NetworkInterface.displayName */
  97 jfieldID ni_childsID;       /* NetworkInterface.childs */


  98 








  99 jclass ni_ibcls;            /* InterfaceAddress */
 100 jmethodID ni_ibctrID;       /* InterfaceAddress() */
 101 jfieldID ni_ibaddressID;        /* InterfaceAddress.address */
 102 jfieldID ni_ibbroadcastID;      /* InterfaceAddress.broadcast */
 103 jfieldID ni_ibmaskID;           /* InterfaceAddress.maskLength */
 104 
 105 /*
 106  * Support routines to free netif and netaddr lists
 107  */
 108 void free_netif(netif *netifP) {
 109     netif *curr = netifP;
 110     while (curr != NULL) {
 111         if (curr->name != NULL)
 112             free(curr->name);
 113         if (curr->displayName != NULL)
 114             free(curr->displayName);
 115         if (curr->addrs != NULL)
 116             free_netaddr (curr->addrs);
 117         netifP = netifP->next;
 118         free(curr);


 518         if (isW9x) {
 519             /* Use Windows 9x registry approach which requires initialization */
 520             enumInterfaces_fn = enumInterfaces_win9x;
 521             enumAddresses_fn = enumAddresses_win9x;
 522             init_win9x();
 523         } else
 524 #endif
 525         {
 526             JNU_ThrowByName(env, "java/lang/Error",
 527                 "Incompatible IP helper library (iphlpapi.dll)");
 528             return;
 529         }
 530     } else {
 531         enumInterfaces_fn = enumInterfaces_win;
 532         enumAddresses_fn = enumAddresses_win;
 533     }
 534 
 535     /*
 536      * Get the various JNI ids that we require
 537      */
 538     if (ni_ibmaskID == NULL) {
 539         ni_class = (*env)->NewGlobalRef(env, cls);
 540         ni_nameID = (*env)->GetFieldID(env, ni_class, "name", "Ljava/lang/String;");
 541         ni_displayNameID = (*env)->GetFieldID(env, ni_class, "displayName", "Ljava/lang/String;");
 542         ni_indexID = (*env)->GetFieldID(env, ni_class, "index", "I");
 543         ni_addrsID = (*env)->GetFieldID(env, ni_class, "addrs", "[Ljava/net/InetAddress;");
 544         ni_bindsID = (*env)->GetFieldID(env, ni_class, "bindings", "[Ljava/net/InterfaceAddress;");
 545         ni_childsID = (*env)->GetFieldID(env, ni_class, "childs", "[Ljava/net/NetworkInterface;");
 546         ni_ctrID = (*env)->GetMethodID(env, ni_class, "<init>", "()V");
 547 
 548         init(env);


 549 









 550         ni_ibcls = (*env)->FindClass(env, "java/net/InterfaceAddress");
 551         ni_ibcls = (*env)->NewGlobalRef(env, ni_ibcls);
 552         ni_ibctrID = (*env)->GetMethodID(env, ni_ibcls, "<init>", "()V");
 553         ni_ibaddressID = (*env)->GetFieldID(env, ni_ibcls, "address", "Ljava/net/InetAddress;");
 554         ni_ibbroadcastID = (*env)->GetFieldID(env, ni_ibcls, "broadcast", "Ljava/net/Inet4Address;");
 555         ni_ibmaskID = (*env)->GetFieldID(env, ni_ibcls, "maskLength", "S");
 556     }
 557 }
 558 
 559 /*
 560  * Create a NetworkInterface object, populate the name and index, and
 561  * populate the InetAddress array based on the IP addresses for this
 562  * interface.
 563  */
 564 jobject createNetworkInterface(JNIEnv *env, netif *ifs, int netaddrCount, netaddr *netaddrP)
 565 {
 566     jobject netifObj;
 567     jobject name, displayName;
 568     jobjectArray addrArr, bindsArr, childArr;
 569     netaddr *addrs;
 570     jint addr_index;
 571     jint bind_index;
 572 
 573     /*
 574      * Create a NetworkInterface object and populate it
 575      */
 576     netifObj = (*env)->NewObject(env, ni_class, ni_ctrID);
 577     name = (*env)->NewStringUTF(env, ifs->name);
 578     if (ifs->dNameIsUnicode) {
 579         displayName = (*env)->NewString(env, (PWCHAR)ifs->displayName, wcslen ((PWCHAR)ifs->displayName));
 580     } else {
 581         displayName = (*env)->NewStringUTF(env, ifs->displayName);
 582     }
 583     if (netifObj == NULL || name == NULL || displayName == NULL) {
 584         return NULL;
 585     }
 586     (*env)->SetObjectField(env, netifObj, ni_nameID, name);
 587     (*env)->SetObjectField(env, netifObj, ni_displayNameID, displayName);
 588     (*env)->SetIntField(env, netifObj, ni_indexID, ifs->index);
 589 
 590     /*
 591      * Get the IP addresses for this interface if necessary
 592      * Note that 0 is a valid number of addresses.
 593      */
 594     if (netaddrCount < 0) {
 595         netaddrCount = (*enumAddresses_fn)(env, ifs, &netaddrP);
 596         if ((*env)->ExceptionOccurred(env)) {
 597             free_netaddr(netaddrP);
 598             return NULL;
 599         }
 600     }
 601     addrArr = (*env)->NewObjectArray(env, netaddrCount, ia_class, NULL);
 602     if (addrArr == NULL) {
 603         free_netaddr(netaddrP);
 604         return NULL;
 605     }
 606 
 607     bindsArr = (*env)->NewObjectArray(env, netaddrCount, ni_ibcls, NULL);
 608     if (bindsArr == NULL) {
 609       free_netaddr(netaddrP);
 610       return NULL;
 611     }
 612     addrs = netaddrP;
 613     addr_index = 0;
 614     bind_index = 0;
 615     while (addrs != NULL) {
 616         jobject iaObj, ia2Obj;
 617         jobject ibObj = NULL;
 618         if (addrs->addr.him.sa_family == AF_INET) {
 619             iaObj = (*env)->NewObject(env, ia4_class, ia4_ctrID);
 620             if (iaObj == NULL) {
 621                 free_netaddr(netaddrP);
 622                 return NULL;
 623             }
 624             /* default ctor will set family to AF_INET */
 625 
 626             (*env)->SetIntField(env, iaObj, ia_addressID, ntohl(addrs->addr.him4.sin_addr.s_addr));
 627             if (addrs->mask != -1) {
 628               ibObj = (*env)->NewObject(env, ni_ibcls, ni_ibctrID);
 629               if (ibObj == NULL) {
 630                 free_netaddr(netaddrP);
 631                 return NULL;
 632               }
 633               (*env)->SetObjectField(env, ibObj, ni_ibaddressID, iaObj);
 634               ia2Obj = (*env)->NewObject(env, ia4_class, ia4_ctrID);
 635               if (ia2Obj == NULL) {
 636                 free_netaddr(netaddrP);
 637                 return NULL;
 638               }
 639               (*env)->SetIntField(env, ia2Obj, ia_addressID,
 640                                   ntohl(addrs->brdcast.him4.sin_addr.s_addr));
 641               (*env)->SetObjectField(env, ibObj, ni_ibbroadcastID, ia2Obj);
 642               (*env)->SetShortField(env, ibObj, ni_ibmaskID, addrs->mask);
 643               (*env)->SetObjectArrayElement(env, bindsArr, bind_index++, ibObj);
 644             }
 645         } else /* AF_INET6 */ {
 646             int scope;
 647             iaObj = (*env)->NewObject(env, ia6_class, ia6_ctrID);
 648             if (iaObj) {
 649                 jbyteArray ipaddress = (*env)->NewByteArray(env, 16);
 650                 if (ipaddress == NULL) {
 651                     return NULL;
 652                 }
 653                 (*env)->SetByteArrayRegion(env, ipaddress, 0, 16,
 654                     (jbyte *)&(addrs->addr.him6.sin6_addr.s6_addr));
 655                 scope = addrs->addr.him6.sin6_scope_id;
 656                 if (scope != 0) { /* zero is default value, no need to set */
 657                     (*env)->SetIntField(env, iaObj, ia6_scopeidID, scope);
 658                     (*env)->SetBooleanField(env, iaObj, ia6_scopeidsetID, JNI_TRUE);
 659                     (*env)->SetObjectField(env, iaObj, ia6_scopeifnameID, netifObj);
 660                 }
 661                 (*env)->SetObjectField(env, iaObj, ia6_ipaddressID, ipaddress);
 662                 ibObj = (*env)->NewObject(env, ni_ibcls, ni_ibctrID);
 663                 if (ibObj == NULL) {
 664                   free_netaddr(netaddrP);
 665                   return NULL;
 666                 }
 667                 (*env)->SetObjectField(env, ibObj, ni_ibaddressID, iaObj);
 668                 (*env)->SetShortField(env, ibObj, ni_ibmaskID, addrs->mask);
 669                 (*env)->SetObjectArrayElement(env, bindsArr, bind_index++, ibObj);
 670             }
 671         }
 672         (*env)->SetObjectArrayElement(env, addrArr, addr_index, iaObj);
 673         addrs = addrs->next;
 674         addr_index++;
 675     }
 676     (*env)->SetObjectField(env, netifObj, ni_addrsID, addrArr);
 677     (*env)->SetObjectField(env, netifObj, ni_bindsID, bindsArr);
 678 
 679     free_netaddr(netaddrP);
 680 
 681     /*


 772     /* if found create a NetworkInterface */
 773     if (curr != NULL) {
 774         netifObj = createNetworkInterface(env, curr, -1, NULL);
 775     }
 776 
 777     /* release the interface list */
 778     free_netif(ifList);
 779 
 780     return netifObj;
 781 }
 782 
 783 /*
 784  * Class:     java_net_NetworkInterface
 785  * Method:    getByInetAddress0
 786  * Signature: (Ljava/net/InetAddress;)Ljava/net/NetworkInterface;
 787  */
 788 JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByInetAddress0
 789     (JNIEnv *env, jclass cls, jobject iaObj)
 790 {
 791     netif *ifList, *curr;
 792     jint addr = (*env)->GetIntField(env, iaObj, ia_addressID);
 793     jobject netifObj = NULL;
 794 
 795     if (os_supports_ipv6 && ipv6_available()) {
 796         return Java_java_net_NetworkInterface_getByInetAddress0_XP (env, cls, iaObj);
 797     }
 798 
 799     /* get the list of interfaces */
 800     if ((*enumInterfaces_fn)(env, &ifList) < 0) {
 801         return NULL;
 802     }
 803 
 804     /*
 805      * Enumerate the addresses on each interface until we find a
 806      * matching address.
 807      */
 808     curr = ifList;
 809     while (curr != NULL) {
 810         int count;
 811         netaddr *addrList;
 812         netaddr *addrP;