3 * ===================================
4 * HARP | Host ATM Research Platform
5 * ===================================
8 * This Host ATM Research Platform ("HARP") file (the "Software") is
9 * made available by Network Computing Services, Inc. ("NetworkCS")
10 * "AS IS". NetworkCS does not provide maintenance, improvements or
11 * support of any kind.
13 * NETWORKCS MAKES NO WARRANTIES OR REPRESENTATIONS, EXPRESS OR IMPLIED,
14 * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
15 * AND FITNESS FOR A PARTICULAR PURPOSE, AS TO ANY ELEMENT OF THE
16 * SOFTWARE OR ANY SUPPORT PROVIDED IN CONNECTION WITH THIS SOFTWARE.
17 * In no event shall NetworkCS be responsible for any damages, including
18 * but not limited to consequential damages, arising from or relating to
19 * any use of the Software or related support.
21 * Copyright 1994-1998 Network Computing Services, Inc.
23 * Copies of this Software may be made, however, the above copyright
24 * notice must be reproduced on all copies.
26 * @(#) $FreeBSD: src/sys/netatm/uni/uniarp.c,v 1.8 2000/01/15 20:46:07 mks Exp $
31 * ATM Forum UNI Support
32 * ---------------------
34 * UNI ATMARP support (RFC1577)
38 #include <netatm/kern_include.h>
40 #include <netatm/ipatm/ipatm_var.h>
41 #include <netatm/ipatm/ipatm_serv.h>
42 #include <netatm/uni/unisig_var.h>
43 #include <netatm/uni/uniip_var.h>
46 __RCSID("@(#) $FreeBSD: src/sys/netatm/uni/uniarp.c,v 1.8 2000/01/15 20:46:07 mks Exp $");
53 struct uniarp *uniarp_arptab[UNIARP_HASHSIZ] = {NULL};
54 struct uniarp *uniarp_nomaptab = NULL;
55 struct uniarp *uniarp_pvctab = NULL;
56 struct atm_time uniarp_timer = {0, 0}; /* Aging timer */
57 struct uniarp_stat uniarp_stat = {0};
60 Atm_endpoint uniarp_endpt = {
78 struct sp_info uniarp_pool = {
79 "uni arp pool", /* si_name */
80 sizeof(struct uniarp), /* si_blksiz */
89 static void uniarp_server_mode __P((struct uniip *));
90 static void uniarp_client_mode __P((struct uniip *, Atm_addr *));
94 * Process module loading notification
96 * Called whenever the uni module is initializing.
102 * 0 initialization successful
103 * errno initialization failed - reason indicated
112 * Register our endpoint
114 err = atm_endpoint_register(&uniarp_endpt);
121 * Process module unloading notification
123 * Called whenever the uni module is about to be unloaded. All signalling
124 * instances will have been previously detached. All uniarp resources
140 * Make sure the arp table is empty
142 for (i = 0; i < UNIARP_HASHSIZ; i++) {
143 if (uniarp_arptab[i] != NULL)
144 panic("uniarp_stop: arp table not empty");
150 (void) atm_untimeout(&uniarp_timer);
153 * De-register ourselves
155 (void) atm_endpoint_deregister(&uniarp_endpt);
158 * Free our storage pools
160 atm_release_pool(&uniarp_pool);
165 * Process IP Network Interface Activation
167 * Called whenever an IP network interface becomes active.
172 * uip pointer to UNI IP interface
184 ATM_DEBUG1("uniarp_ipact: uip=%p\n", uip);
189 uip->uip_arpstate = UIAS_NOTCONF;
190 uip->uip_arpsvratm.address_format = T_ATM_ABSENT;
191 uip->uip_arpsvratm.address_length = 0;
192 uip->uip_arpsvrsub.address_format = T_ATM_ABSENT;
193 uip->uip_arpsvrsub.address_length = 0;
195 usp = (struct unisig *)uip->uip_ipnif->inf_nif->nif_pif->pif_siginst;
196 if (usp->us_addr.address_format != T_ATM_ABSENT)
197 uip->uip_flags |= UIF_IFADDR;
200 * Make sure aging timer is running
202 if ((uniarp_timer.ti_flag & TIF_QUEUED) == 0)
203 atm_timeout(&uniarp_timer, UNIARP_AGING, uniarp_aging);
210 * Process IP Network Interface Deactivation
212 * Called whenever an IP network interface becomes inactive. All VCCs
213 * for this interface should already have been closed.
218 * uip pointer to UNI IP interface
228 struct uniarp *uap, *unext;
231 ATM_DEBUG1("uniarp_ipdact: uip=%p\n", uip);
234 * Delete all interface entries
236 for (i = 0; i < UNIARP_HASHSIZ; i++) {
237 for (uap = uniarp_arptab[i]; uap; uap = unext) {
238 unext = uap->ua_next;
240 if (uap->ua_intf != uip)
244 * All VCCs should (better) be gone by now
247 panic("uniarp_ipdact: entry not empty");
250 * Clean up any loose ends
255 * Delete entry from arp table and free entry
258 atm_free((caddr_t)uap);
263 * Clean up 'nomap' table
265 for (uap = uniarp_nomaptab; uap; uap = unext) {
266 unext = uap->ua_next;
268 if (uap->ua_intf != uip)
272 * All VCCs should (better) be gone by now
275 panic("uniarp_ipdact: entry not empty");
278 * Clean up any loose ends
283 * Delete entry from 'no map' table and free entry
285 UNLINK(uap, struct uniarp, uniarp_nomaptab, ua_next);
286 atm_free((caddr_t)uap);
290 * Also clean up pvc table
292 for (uap = uniarp_pvctab; uap; uap = unext) {
293 unext = uap->ua_next;
295 if (uap->ua_intf != uip)
299 * All PVCs should (better) be gone by now
301 panic("uniarp_ipdact: pvc table not empty");
305 * Cancel arp interface timer
307 UNIIP_ARP_CANCEL(uip);
310 * Stop aging timer if this is the last active interface
312 if (uniip_head == uip && uip->uip_next == NULL)
313 (void) atm_untimeout(&uniarp_timer);
318 * Process Interface ATM Address Change
320 * This function is called whenever the ATM address for a physical
321 * interface is set/changed.
326 * sip pointer to interface's UNI signalling instance
339 ATM_DEBUG1("uniarp_ifaddr: sip=%p\n", sip);
342 * We've got to handle this for every network interface
344 for (nip = sip->si_pif->pif_nif; nip; nip = nip->nif_pnext) {
347 * Find our control blocks
349 for (uip = uniip_head; uip; uip = uip->uip_next) {
350 if (uip->uip_ipnif->inf_nif == nip)
357 * We don't support changing prefix (yet)
359 if (uip->uip_flags & UIF_IFADDR) {
360 log(LOG_ERR, "uniarp_ifaddr: change not supported\n");
365 * Note that address has been set and figure out what
368 uip->uip_flags |= UIF_IFADDR;
370 if (uip->uip_arpstate == UIAS_CLIENT_PADDR) {
372 * This is what we're waiting for
374 uniarp_client_mode(uip, NULL);
375 } else if (uip->uip_arpstate == UIAS_SERVER_ACTIVE) {
377 * Set new local arpserver atm address
379 ATM_ADDR_SEL_COPY(&sip->si_addr, nip->nif_sel,
380 &uip->uip_arpsvratm);
389 * Set ATMARP Server Mode
391 * This function is called to configure the local node to become the
392 * ATMARP server for the specified LIS.
397 * uip pointer to UNI IP interface
404 uniarp_server_mode(uip)
410 struct ipvcc *ivp, *inext;
411 struct uniarp *uap, *unext;
414 ATM_DEBUG1("uniarp_server_mode: uip=%p\n", uip);
417 * Handle client/server mode changes first
419 switch (uip->uip_arpstate) {
422 case UIAS_SERVER_ACTIVE:
423 case UIAS_CLIENT_PADDR:
429 case UIAS_CLIENT_POPEN:
431 * We're becoming the server, so kill the pending connection
433 UNIIP_ARP_CANCEL(uip);
434 if ((ivp = uip->uip_arpsvrvcc) != NULL) {
435 ivp->iv_flags &= ~IVF_NOIDLE;
436 uip->uip_arpsvrvcc = NULL;
437 (*ivp->iv_ipnif->inf_arpnotify)(ivp, MAP_FAILED);
441 case UIAS_CLIENT_REGISTER:
442 case UIAS_CLIENT_ACTIVE:
444 * We're becoming the server, but leave existing VCC as a
447 UNIIP_ARP_CANCEL(uip);
448 ivp = uip->uip_arpsvrvcc;
449 ivp->iv_flags &= ~IVF_NOIDLE;
450 uip->uip_arpsvrvcc = NULL;
455 * Revalidate status for all arp entries on this interface
457 for (i = 0; i < UNIARP_HASHSIZ; i++) {
458 for (uap = uniarp_arptab[i]; uap; uap = unext) {
459 unext = uap->ua_next;
461 if (uap->ua_intf != uip)
464 if (uap->ua_origin >= UAO_PERM)
467 if (uap->ua_origin >= UAO_SCSP) {
468 if (uniarp_validate_ip(uip, &uap->ua_dstip,
469 uap->ua_origin) == 0)
473 if (uap->ua_ivp == NULL) {
476 atm_free((caddr_t)uap);
480 if (uap->ua_flags & UAF_VALID) {
481 uap->ua_flags |= UAF_LOCKED;
482 for (ivp = uap->ua_ivp; ivp; ivp = inext) {
483 inext = ivp->iv_arpnext;
484 (*ivp->iv_ipnif->inf_arpnotify)
487 uap->ua_flags &= ~(UAF_LOCKED | UAF_VALID);
495 * OK, now let's make ourselves the server
497 inp = uip->uip_ipnif;
499 sgp = nip->nif_pif->pif_siginst;
500 ATM_ADDR_SEL_COPY(&sgp->si_addr, nip->nif_sel, &uip->uip_arpsvratm);
501 uip->uip_arpsvrip = IA_SIN(inp->inf_addr)->sin_addr;
502 uip->uip_arpstate = UIAS_SERVER_ACTIVE;
508 * Set ATMARP Client Mode
510 * This function is called to configure the local node to be an ATMARP
511 * client on the specified LIS using the specified ATMARP server.
516 * uip pointer to UNI IP interface
517 * aap pointer to the ATMARP server's ATM address
524 uniarp_client_mode(uip, aap)
528 struct ip_nif *inp = uip->uip_ipnif;
529 struct uniarp *uap, *unext;
530 struct ipvcc *ivp, *inext;
533 ATM_DEBUG2("uniarp_client_mode: uip=%p, atm=(%s,-)\n",
534 uip, aap ? unisig_addr_print(aap): "-");
537 * Handle client/server mode changes first
539 switch (uip->uip_arpstate) {
542 case UIAS_CLIENT_PADDR:
548 case UIAS_CLIENT_POPEN:
550 * If this is this a timeout retry, just go do it
556 * If this isn't really a different arpserver, we're done
558 if (ATM_ADDR_EQUAL(aap, &uip->uip_arpsvratm))
562 * We're changing servers, so kill the pending connection
564 UNIIP_ARP_CANCEL(uip);
565 if ((ivp = uip->uip_arpsvrvcc) != NULL) {
566 ivp->iv_flags &= ~IVF_NOIDLE;
567 uip->uip_arpsvrvcc = NULL;
568 (*ivp->iv_ipnif->inf_arpnotify)(ivp, MAP_FAILED);
572 case UIAS_CLIENT_REGISTER:
573 case UIAS_CLIENT_ACTIVE:
575 * If this isn't really a different arpserver, we're done
577 if (ATM_ADDR_EQUAL(aap, &uip->uip_arpsvratm))
581 * We're changing servers, but leave existing VCC as a
584 UNIIP_ARP_CANCEL(uip);
585 ivp = uip->uip_arpsvrvcc;
586 ivp->iv_flags &= ~IVF_NOIDLE;
587 uip->uip_arpsvrvcc = NULL;
590 case UIAS_SERVER_ACTIVE:
592 * We're changing from server mode, so...
594 * Reset valid/authoritative status for all arp entries
597 for (i = 0; i < UNIARP_HASHSIZ; i++) {
598 for (uap = uniarp_arptab[i]; uap; uap = unext) {
599 unext = uap->ua_next;
601 if (uap->ua_intf != uip)
604 if (uap->ua_origin >= UAO_PERM)
607 if (uap->ua_ivp == NULL) {
610 atm_free((caddr_t)uap);
614 if (uap->ua_flags & UAF_VALID) {
615 uap->ua_flags |= UAF_LOCKED;
616 for (ivp = uap->ua_ivp; ivp;
618 inext = ivp->iv_arpnext;
619 (*ivp->iv_ipnif->inf_arpnotify)
623 ~(UAF_LOCKED | UAF_VALID);
629 uip->uip_arpsvratm.address_format = T_ATM_ABSENT;
630 uip->uip_arpsvratm.address_length = 0;
631 uip->uip_arpsvrsub.address_format = T_ATM_ABSENT;
632 uip->uip_arpsvrsub.address_length = 0;
633 uip->uip_arpsvrip.s_addr = 0;
638 * Save the arp server address, if supplied now
641 ATM_ADDR_COPY(aap, &uip->uip_arpsvratm);
644 * If the interface's ATM address isn't set yet, then we
645 * can't do much until it is
647 if ((uip->uip_flags & UIF_IFADDR) == 0) {
648 uip->uip_arpstate = UIAS_CLIENT_PADDR;
653 * Just to keep things simple, if we already have (or are trying to
654 * setup) any SVCs to our new server, kill the connections so we can
655 * open a "fresh" SVC for the arpserver connection.
657 for (i = 0; i < UNIARP_HASHSIZ; i++) {
658 for (uap = uniarp_arptab[i]; uap; uap = unext) {
659 unext = uap->ua_next;
661 if (ATM_ADDR_EQUAL(&uip->uip_arpsvratm,
663 ATM_ADDR_EQUAL(&uip->uip_arpsvrsub,
664 &uap->ua_dstatmsub)) {
665 uap->ua_flags &= ~UAF_VALID;
666 for (ivp = uap->ua_ivp; ivp; ivp = inext) {
667 inext = ivp->iv_arpnext;
668 (*inp->inf_arpnotify)(ivp, MAP_FAILED);
673 for (uap = uniarp_nomaptab; uap; uap = unext) {
674 unext = uap->ua_next;
676 if (ATM_ADDR_EQUAL(&uip->uip_arpsvratm, &uap->ua_dstatm) &&
677 ATM_ADDR_EQUAL(&uip->uip_arpsvrsub, &uap->ua_dstatmsub)) {
678 uap->ua_flags &= ~UAF_VALID;
679 for (ivp = uap->ua_ivp; ivp; ivp = inext) {
680 inext = ivp->iv_arpnext;
681 (*inp->inf_arpnotify)(ivp, MAP_FAILED);
687 * Now, get an arp entry for the server connection
689 uip->uip_arpstate = UIAS_CLIENT_POPEN;
690 uap = (struct uniarp *)atm_allocate(&uniarp_pool);
692 UNIIP_ARP_TIMER(uip, 1 * ATM_HZ);
697 * Next, initiate an SVC to the server
699 if ((*inp->inf_createsvc)(&inp->inf_nif->nif_if, AF_ATM,
700 (caddr_t)&uip->uip_arpsvratm, &ivp)) {
701 atm_free((caddr_t)uap);
702 UNIIP_ARP_TIMER(uip, 1 * ATM_HZ);
707 * Finally, get everything set up and wait for the SVC
708 * connection to complete
710 uip->uip_arpsvrvcc = ivp;
711 ivp->iv_flags |= IVF_NOIDLE;
713 ATM_ADDR_COPY(&uip->uip_arpsvratm, &uap->ua_dstatm);
714 ATM_ADDR_COPY(&uip->uip_arpsvrsub, &uap->ua_dstatmsub);
717 LINK2TAIL(ivp, struct ipvcc, uap->ua_ivp, iv_arpnext);
718 ivp->iv_arpent = (struct arpmap *)uap;
720 LINK2TAIL(uap, struct uniarp, uniarp_nomaptab, ua_next);
727 * Process a UNI ARP interface timeout
729 * Called when a previously scheduled uniip arp interface timer expires.
730 * Processing will be based on the current uniip arp state.
735 * tip pointer to uniip arp timer control block
742 uniarp_iftimeout(tip)
743 struct atm_time *tip;
750 * Back-off to uniip control block
752 uip = (struct uniip *)
753 ((caddr_t)tip - (int)(&((struct uniip *)0)->uip_arptime));
755 ATM_DEBUG2("uniarp_iftimeout: uip=%p, state=%d\n", uip,
759 * Process timeout based on protocol state
761 switch (uip->uip_arpstate) {
763 case UIAS_CLIENT_POPEN:
765 * Retry opening arp server connection
767 uniarp_client_mode(uip, NULL);
770 case UIAS_CLIENT_REGISTER:
772 * Resend registration request
774 inp = uip->uip_ipnif;
775 (void) uniarp_arp_req(uip, &(IA_SIN(inp->inf_addr)->sin_addr));
780 UNIIP_ARP_TIMER(uip, 2 * ATM_HZ);
784 case UIAS_CLIENT_ACTIVE:
786 * Refresh our registration
788 inp = uip->uip_ipnif;
789 (void) uniarp_arp_req(uip, &(IA_SIN(inp->inf_addr)->sin_addr));
794 UNIIP_ARP_TIMER(uip, UNIARP_REGIS_RETRY);
799 log(LOG_ERR, "uniarp_iftimeout: invalid state %d\n",
806 * UNI ARP IOCTL support
808 * Function will be called at splnet.
811 * code PF_ATM sub-operation code
812 * data pointer to code specific parameter data area
813 * arg1 pointer to code specific argument
817 * errno error processing request - reason indicated
821 uniarp_ioctl(code, data, arg1)
826 struct atmaddreq *aap;
827 struct atmdelreq *adp;
828 struct atmsetreq *asp;
829 struct atminfreq *aip;
830 struct air_arp_rsp aar;
831 struct air_asrv_rsp asr;
834 struct ipvcc *ivp, *inext;
841 int err = 0, i, buf_len;
848 * Add a permanent ARP mapping
850 aap = (struct atmaddreq *)data;
851 uip = (struct uniip *)arg1;
852 if (aap->aar_arp_addr.address_format != T_ATM_ENDSYS_ADDR) {
856 atmsub.address_format = T_ATM_ABSENT;
857 atmsub.address_length = 0;
858 ip = SATOSIN(&aap->aar_arp_dst)->sin_addr;
861 * Validate IP address
863 if (uniarp_validate_ip(uip, &ip, aap->aar_arp_origin) != 0) {
869 * Add an entry to the cache
871 err = uniarp_cache_svc(uip, &ip, &aap->aar_arp_addr,
872 &atmsub, aap->aar_arp_origin);
877 * Delete an ARP mapping
879 adp = (struct atmdelreq *)data;
880 uip = (struct uniip *)arg1;
881 ip = SATOSIN(&adp->adr_arp_dst)->sin_addr;
884 * Now find the entry to be deleted
886 UNIARP_LOOKUP(ip.s_addr, uap);
893 * Notify all VCCs using this entry that they must finish
896 uap->ua_flags |= UAF_LOCKED;
897 for (ivp = uap->ua_ivp; ivp; ivp = inext) {
898 inext = ivp->iv_arpnext;
899 (*ivp->iv_ipnif->inf_arpnotify)(ivp, MAP_FAILED);
903 * Now free up the entry
907 atm_free((caddr_t)uap);
912 * Set interface ARP server address
914 asp = (struct atmsetreq *)data;
915 for (uip = uniip_head; uip; uip = uip->uip_next) {
916 if (uip->uip_ipnif->inf_nif == (struct atm_nif *)arg1)
925 * Check for our own address
927 usp = (struct unisig *)
928 uip->uip_ipnif->inf_nif->nif_pif->pif_siginst;
929 if (ATM_ADDR_EQUAL(&asp->asr_arp_addr, &usp->us_addr)) {
930 asp->asr_arp_addr.address_format = T_ATM_ABSENT;
934 * If we're going into server mode, make sure we can get
935 * the memory for the prefix list before continuing
937 if (asp->asr_arp_addr.address_format == T_ATM_ABSENT) {
938 i = asp->asr_arp_plen / sizeof(struct uniarp_prf);
943 buf_len = i * sizeof(struct uniarp_prf);
944 buf_addr = KM_ALLOC(buf_len, M_DEVBUF, M_NOWAIT);
945 if (buf_addr == NULL) {
949 err = copyin(asp->asr_arp_pbuf, buf_addr, buf_len);
951 KM_FREE(buf_addr, buf_len, M_DEVBUF);
955 /* Silence the compiler */
961 * Free any existing prefix address list
963 if (uip->uip_prefix != NULL) {
964 KM_FREE(uip->uip_prefix,
965 uip->uip_nprefix * sizeof(struct uniarp_prf),
967 uip->uip_prefix = NULL;
968 uip->uip_nprefix = 0;
971 if (asp->asr_arp_addr.address_format == T_ATM_ABSENT) {
973 * Set ATMARP server mode
975 uip->uip_prefix = (struct uniarp_prf *)buf_addr;
976 uip->uip_nprefix = i;
977 uniarp_server_mode(uip);
980 * Set ATMARP client mode
982 uniarp_client_mode(uip, &asp->asr_arp_addr);
987 * Get ARP table information
989 aip = (struct atminfreq *)data;
991 if (aip->air_arp_addr.sa_family != AF_INET)
993 dst = SATOSIN(&aip->air_arp_addr)->sin_addr.s_addr;
995 buf_addr = aip->air_buf_addr;
996 buf_len = aip->air_buf_len;
998 pip = ((struct siginst *)arg1)->si_pif;
1001 * Run through entire arp table
1003 for (i = 0; i < UNIARP_HASHSIZ; i++) {
1004 for (uap = uniarp_arptab[i]; uap; uap = uap->ua_next) {
1006 * We only want valid entries learned
1007 * from the supplied interface.
1009 nip = uap->ua_intf->uip_ipnif->inf_nif;
1010 if (nip->nif_pif != pip)
1012 if ((dst != INADDR_ANY) &&
1013 (dst != uap->ua_dstip.s_addr))
1017 * Make sure there's room in the user's buffer
1019 if (buf_len < sizeof(aar)) {
1025 * Fill in info to be returned
1027 SATOSIN(&aar.aap_arp_addr)->sin_family =
1029 SATOSIN(&aar.aap_arp_addr)->sin_addr.s_addr =
1030 uap->ua_dstip.s_addr;
1031 (void) snprintf(aar.aap_intf,
1032 sizeof(aar.aap_intf), "%s%d",
1033 nip->nif_if.if_name,
1034 nip->nif_if.if_unit);
1035 aar.aap_flags = uap->ua_flags;
1036 aar.aap_origin = uap->ua_origin;
1037 if (uap->ua_flags & UAF_VALID)
1038 aar.aap_age = uap->ua_aging +
1039 uap->ua_retry * UNIARP_RETRY_AGE;
1042 ATM_ADDR_COPY(&uap->ua_dstatm, &aar.aap_addr);
1043 ATM_ADDR_COPY(&uap->ua_dstatmsub,
1047 * Copy the response into the user's buffer
1049 if ((err = copyout((caddr_t)&aar, buf_addr,
1052 buf_addr += sizeof(aar);
1053 buf_len -= sizeof(aar);
1060 * Now go through the 'nomap' table
1062 if (err || (dst != INADDR_ANY))
1064 for (uap = uniarp_nomaptab; uap; uap = uap->ua_next) {
1066 * We only want valid entries learned
1067 * from the supplied interface.
1069 nip = uap->ua_intf->uip_ipnif->inf_nif;
1070 if (nip->nif_pif != pip)
1074 * Make sure there's room in the user's buffer
1076 if (buf_len < sizeof(aar)) {
1082 * Fill in info to be returned
1084 SATOSIN(&aar.aap_arp_addr)->sin_family = AF_INET;
1085 SATOSIN(&aar.aap_arp_addr)->sin_addr.s_addr = 0;
1086 (void) snprintf(aar.aap_intf,
1087 sizeof(aar.aap_intf), "%s%d",
1088 nip->nif_if.if_name, nip->nif_if.if_unit);
1090 aar.aap_origin = uap->ua_origin;
1092 ATM_ADDR_COPY(&uap->ua_dstatm, &aar.aap_addr);
1093 ATM_ADDR_COPY(&uap->ua_dstatmsub,
1097 * Copy the response into the user's buffer
1099 if ((err = copyout((caddr_t)&aar, buf_addr,
1102 buf_addr += sizeof(aar);
1103 buf_len -= sizeof(aar);
1108 * Update the buffer pointer and length
1110 aip->air_buf_addr = buf_addr;
1111 aip->air_buf_len = buf_len;
1114 * If the user wants the refresh status reset and no
1115 * errors have been encountered, then do the reset
1117 if ((err == 0) && (aip->air_arp_flags & ARP_RESET_REF)) {
1118 for (i = 0; i < UNIARP_HASHSIZ; i++) {
1119 for (uap = uniarp_arptab[i]; uap;
1120 uap = uap->ua_next) {
1122 * We only want valid entries learned
1123 * from the supplied interface.
1125 nip = uap->ua_intf->uip_ipnif->inf_nif;
1126 if (nip->nif_pif != pip)
1128 if ((dst != INADDR_ANY) &&
1129 (dst != uap->ua_dstip.s_addr))
1133 * Reset refresh flag
1135 uap->ua_flags &= ~UAF_REFRESH;
1143 * Get ARP server information
1145 aip = (struct atminfreq *)data;
1146 nip = (struct atm_nif *)arg1;
1148 buf_addr = aip->air_buf_addr;
1149 buf_len = aip->air_buf_len;
1151 for (uip = uniip_head; uip; uip = uip->uip_next) {
1153 if (uip->uip_ipnif->inf_nif != nip)
1157 * Make sure there's room in the user's buffer
1159 if (buf_len < sizeof(asr)) {
1165 * Fill in info to be returned
1167 (void) snprintf(asr.asp_intf,
1168 sizeof(asr.asp_intf), "%s%d",
1169 nip->nif_if.if_name, nip->nif_if.if_unit);
1170 asr.asp_state = uip->uip_arpstate;
1171 if (uip->uip_arpstate == UIAS_SERVER_ACTIVE) {
1172 asr.asp_addr.address_format = T_ATM_ABSENT;
1173 asr.asp_addr.address_length = 0;
1175 ATM_ADDR_COPY(&uip->uip_arpsvratm,
1178 asr.asp_subaddr.address_format = T_ATM_ABSENT;
1179 asr.asp_subaddr.address_length = 0;
1180 asr.asp_nprefix = uip->uip_nprefix;
1183 * Copy the response into the user's buffer
1185 if ((err = copyout((caddr_t)&asr, buf_addr, sizeof(asr))) != 0)
1187 buf_addr += sizeof(asr);
1188 buf_len -= sizeof(asr);
1191 * Copy the prefix list into the user's buffer
1193 if (uip->uip_nprefix) {
1194 i = uip->uip_nprefix
1195 * sizeof(struct uniarp_prf);
1200 if ((err = copyout(uip->uip_prefix, buf_addr, i)) != 0)
1208 * Update the buffer pointer and length
1210 aip->air_buf_addr = buf_addr;
1211 aip->air_buf_len = buf_len;
1223 * Get Connection's Application/Owner Name
1226 * tok uniarp connection token (pointer to ipvcc)
1229 * addr pointer to string containing our name