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 $
27 * @(#) $DragonFly: src/sys/netproto/atm/uni/uniarp.c,v 1.3 2003/08/07 21:17:35 dillon 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 "unisig_var.h"
43 #include "uniip_var.h"
48 struct uniarp *uniarp_arptab[UNIARP_HASHSIZ] = {NULL};
49 struct uniarp *uniarp_nomaptab = NULL;
50 struct uniarp *uniarp_pvctab = NULL;
51 struct atm_time uniarp_timer = {0, 0}; /* Aging timer */
52 struct uniarp_stat uniarp_stat = {0};
55 Atm_endpoint uniarp_endpt = {
73 struct sp_info uniarp_pool = {
74 "uni arp pool", /* si_name */
75 sizeof(struct uniarp), /* si_blksiz */
84 static void uniarp_server_mode __P((struct uniip *));
85 static void uniarp_client_mode __P((struct uniip *, Atm_addr *));
89 * Process module loading notification
91 * Called whenever the uni module is initializing.
97 * 0 initialization successful
98 * errno initialization failed - reason indicated
107 * Register our endpoint
109 err = atm_endpoint_register(&uniarp_endpt);
116 * Process module unloading notification
118 * Called whenever the uni module is about to be unloaded. All signalling
119 * instances will have been previously detached. All uniarp resources
135 * Make sure the arp table is empty
137 for (i = 0; i < UNIARP_HASHSIZ; i++) {
138 if (uniarp_arptab[i] != NULL)
139 panic("uniarp_stop: arp table not empty");
145 (void) atm_untimeout(&uniarp_timer);
148 * De-register ourselves
150 (void) atm_endpoint_deregister(&uniarp_endpt);
153 * Free our storage pools
155 atm_release_pool(&uniarp_pool);
160 * Process IP Network Interface Activation
162 * Called whenever an IP network interface becomes active.
167 * uip pointer to UNI IP interface
179 ATM_DEBUG1("uniarp_ipact: uip=%p\n", uip);
184 uip->uip_arpstate = UIAS_NOTCONF;
185 uip->uip_arpsvratm.address_format = T_ATM_ABSENT;
186 uip->uip_arpsvratm.address_length = 0;
187 uip->uip_arpsvrsub.address_format = T_ATM_ABSENT;
188 uip->uip_arpsvrsub.address_length = 0;
190 usp = (struct unisig *)uip->uip_ipnif->inf_nif->nif_pif->pif_siginst;
191 if (usp->us_addr.address_format != T_ATM_ABSENT)
192 uip->uip_flags |= UIF_IFADDR;
195 * Make sure aging timer is running
197 if ((uniarp_timer.ti_flag & TIF_QUEUED) == 0)
198 atm_timeout(&uniarp_timer, UNIARP_AGING, uniarp_aging);
205 * Process IP Network Interface Deactivation
207 * Called whenever an IP network interface becomes inactive. All VCCs
208 * for this interface should already have been closed.
213 * uip pointer to UNI IP interface
223 struct uniarp *uap, *unext;
226 ATM_DEBUG1("uniarp_ipdact: uip=%p\n", uip);
229 * Delete all interface entries
231 for (i = 0; i < UNIARP_HASHSIZ; i++) {
232 for (uap = uniarp_arptab[i]; uap; uap = unext) {
233 unext = uap->ua_next;
235 if (uap->ua_intf != uip)
239 * All VCCs should (better) be gone by now
242 panic("uniarp_ipdact: entry not empty");
245 * Clean up any loose ends
250 * Delete entry from arp table and free entry
253 atm_free((caddr_t)uap);
258 * Clean up 'nomap' table
260 for (uap = uniarp_nomaptab; uap; uap = unext) {
261 unext = uap->ua_next;
263 if (uap->ua_intf != uip)
267 * All VCCs should (better) be gone by now
270 panic("uniarp_ipdact: entry not empty");
273 * Clean up any loose ends
278 * Delete entry from 'no map' table and free entry
280 UNLINK(uap, struct uniarp, uniarp_nomaptab, ua_next);
281 atm_free((caddr_t)uap);
285 * Also clean up pvc table
287 for (uap = uniarp_pvctab; uap; uap = unext) {
288 unext = uap->ua_next;
290 if (uap->ua_intf != uip)
294 * All PVCs should (better) be gone by now
296 panic("uniarp_ipdact: pvc table not empty");
300 * Cancel arp interface timer
302 UNIIP_ARP_CANCEL(uip);
305 * Stop aging timer if this is the last active interface
307 if (uniip_head == uip && uip->uip_next == NULL)
308 (void) atm_untimeout(&uniarp_timer);
313 * Process Interface ATM Address Change
315 * This function is called whenever the ATM address for a physical
316 * interface is set/changed.
321 * sip pointer to interface's UNI signalling instance
334 ATM_DEBUG1("uniarp_ifaddr: sip=%p\n", sip);
337 * We've got to handle this for every network interface
339 for (nip = sip->si_pif->pif_nif; nip; nip = nip->nif_pnext) {
342 * Find our control blocks
344 for (uip = uniip_head; uip; uip = uip->uip_next) {
345 if (uip->uip_ipnif->inf_nif == nip)
352 * We don't support changing prefix (yet)
354 if (uip->uip_flags & UIF_IFADDR) {
355 log(LOG_ERR, "uniarp_ifaddr: change not supported\n");
360 * Note that address has been set and figure out what
363 uip->uip_flags |= UIF_IFADDR;
365 if (uip->uip_arpstate == UIAS_CLIENT_PADDR) {
367 * This is what we're waiting for
369 uniarp_client_mode(uip, NULL);
370 } else if (uip->uip_arpstate == UIAS_SERVER_ACTIVE) {
372 * Set new local arpserver atm address
374 ATM_ADDR_SEL_COPY(&sip->si_addr, nip->nif_sel,
375 &uip->uip_arpsvratm);
384 * Set ATMARP Server Mode
386 * This function is called to configure the local node to become the
387 * ATMARP server for the specified LIS.
392 * uip pointer to UNI IP interface
399 uniarp_server_mode(uip)
405 struct ipvcc *ivp, *inext;
406 struct uniarp *uap, *unext;
409 ATM_DEBUG1("uniarp_server_mode: uip=%p\n", uip);
412 * Handle client/server mode changes first
414 switch (uip->uip_arpstate) {
417 case UIAS_SERVER_ACTIVE:
418 case UIAS_CLIENT_PADDR:
424 case UIAS_CLIENT_POPEN:
426 * We're becoming the server, so kill the pending connection
428 UNIIP_ARP_CANCEL(uip);
429 if ((ivp = uip->uip_arpsvrvcc) != NULL) {
430 ivp->iv_flags &= ~IVF_NOIDLE;
431 uip->uip_arpsvrvcc = NULL;
432 (*ivp->iv_ipnif->inf_arpnotify)(ivp, MAP_FAILED);
436 case UIAS_CLIENT_REGISTER:
437 case UIAS_CLIENT_ACTIVE:
439 * We're becoming the server, but leave existing VCC as a
442 UNIIP_ARP_CANCEL(uip);
443 ivp = uip->uip_arpsvrvcc;
444 ivp->iv_flags &= ~IVF_NOIDLE;
445 uip->uip_arpsvrvcc = NULL;
450 * Revalidate status for all arp entries on this interface
452 for (i = 0; i < UNIARP_HASHSIZ; i++) {
453 for (uap = uniarp_arptab[i]; uap; uap = unext) {
454 unext = uap->ua_next;
456 if (uap->ua_intf != uip)
459 if (uap->ua_origin >= UAO_PERM)
462 if (uap->ua_origin >= UAO_SCSP) {
463 if (uniarp_validate_ip(uip, &uap->ua_dstip,
464 uap->ua_origin) == 0)
468 if (uap->ua_ivp == NULL) {
471 atm_free((caddr_t)uap);
475 if (uap->ua_flags & UAF_VALID) {
476 uap->ua_flags |= UAF_LOCKED;
477 for (ivp = uap->ua_ivp; ivp; ivp = inext) {
478 inext = ivp->iv_arpnext;
479 (*ivp->iv_ipnif->inf_arpnotify)
482 uap->ua_flags &= ~(UAF_LOCKED | UAF_VALID);
490 * OK, now let's make ourselves the server
492 inp = uip->uip_ipnif;
494 sgp = nip->nif_pif->pif_siginst;
495 ATM_ADDR_SEL_COPY(&sgp->si_addr, nip->nif_sel, &uip->uip_arpsvratm);
496 uip->uip_arpsvrip = IA_SIN(inp->inf_addr)->sin_addr;
497 uip->uip_arpstate = UIAS_SERVER_ACTIVE;
503 * Set ATMARP Client Mode
505 * This function is called to configure the local node to be an ATMARP
506 * client on the specified LIS using the specified ATMARP server.
511 * uip pointer to UNI IP interface
512 * aap pointer to the ATMARP server's ATM address
519 uniarp_client_mode(uip, aap)
523 struct ip_nif *inp = uip->uip_ipnif;
524 struct uniarp *uap, *unext;
525 struct ipvcc *ivp, *inext;
528 ATM_DEBUG2("uniarp_client_mode: uip=%p, atm=(%s,-)\n",
529 uip, aap ? unisig_addr_print(aap): "-");
532 * Handle client/server mode changes first
534 switch (uip->uip_arpstate) {
537 case UIAS_CLIENT_PADDR:
543 case UIAS_CLIENT_POPEN:
545 * If this is this a timeout retry, just go do it
551 * If this isn't really a different arpserver, we're done
553 if (ATM_ADDR_EQUAL(aap, &uip->uip_arpsvratm))
557 * We're changing servers, so kill the pending connection
559 UNIIP_ARP_CANCEL(uip);
560 if ((ivp = uip->uip_arpsvrvcc) != NULL) {
561 ivp->iv_flags &= ~IVF_NOIDLE;
562 uip->uip_arpsvrvcc = NULL;
563 (*ivp->iv_ipnif->inf_arpnotify)(ivp, MAP_FAILED);
567 case UIAS_CLIENT_REGISTER:
568 case UIAS_CLIENT_ACTIVE:
570 * If this isn't really a different arpserver, we're done
572 if (ATM_ADDR_EQUAL(aap, &uip->uip_arpsvratm))
576 * We're changing servers, but leave existing VCC as a
579 UNIIP_ARP_CANCEL(uip);
580 ivp = uip->uip_arpsvrvcc;
581 ivp->iv_flags &= ~IVF_NOIDLE;
582 uip->uip_arpsvrvcc = NULL;
585 case UIAS_SERVER_ACTIVE:
587 * We're changing from server mode, so...
589 * Reset valid/authoritative status for all arp entries
592 for (i = 0; i < UNIARP_HASHSIZ; i++) {
593 for (uap = uniarp_arptab[i]; uap; uap = unext) {
594 unext = uap->ua_next;
596 if (uap->ua_intf != uip)
599 if (uap->ua_origin >= UAO_PERM)
602 if (uap->ua_ivp == NULL) {
605 atm_free((caddr_t)uap);
609 if (uap->ua_flags & UAF_VALID) {
610 uap->ua_flags |= UAF_LOCKED;
611 for (ivp = uap->ua_ivp; ivp;
613 inext = ivp->iv_arpnext;
614 (*ivp->iv_ipnif->inf_arpnotify)
618 ~(UAF_LOCKED | UAF_VALID);
624 uip->uip_arpsvratm.address_format = T_ATM_ABSENT;
625 uip->uip_arpsvratm.address_length = 0;
626 uip->uip_arpsvrsub.address_format = T_ATM_ABSENT;
627 uip->uip_arpsvrsub.address_length = 0;
628 uip->uip_arpsvrip.s_addr = 0;
633 * Save the arp server address, if supplied now
636 ATM_ADDR_COPY(aap, &uip->uip_arpsvratm);
639 * If the interface's ATM address isn't set yet, then we
640 * can't do much until it is
642 if ((uip->uip_flags & UIF_IFADDR) == 0) {
643 uip->uip_arpstate = UIAS_CLIENT_PADDR;
648 * Just to keep things simple, if we already have (or are trying to
649 * setup) any SVCs to our new server, kill the connections so we can
650 * open a "fresh" SVC for the arpserver connection.
652 for (i = 0; i < UNIARP_HASHSIZ; i++) {
653 for (uap = uniarp_arptab[i]; uap; uap = unext) {
654 unext = uap->ua_next;
656 if (ATM_ADDR_EQUAL(&uip->uip_arpsvratm,
658 ATM_ADDR_EQUAL(&uip->uip_arpsvrsub,
659 &uap->ua_dstatmsub)) {
660 uap->ua_flags &= ~UAF_VALID;
661 for (ivp = uap->ua_ivp; ivp; ivp = inext) {
662 inext = ivp->iv_arpnext;
663 (*inp->inf_arpnotify)(ivp, MAP_FAILED);
668 for (uap = uniarp_nomaptab; uap; uap = unext) {
669 unext = uap->ua_next;
671 if (ATM_ADDR_EQUAL(&uip->uip_arpsvratm, &uap->ua_dstatm) &&
672 ATM_ADDR_EQUAL(&uip->uip_arpsvrsub, &uap->ua_dstatmsub)) {
673 uap->ua_flags &= ~UAF_VALID;
674 for (ivp = uap->ua_ivp; ivp; ivp = inext) {
675 inext = ivp->iv_arpnext;
676 (*inp->inf_arpnotify)(ivp, MAP_FAILED);
682 * Now, get an arp entry for the server connection
684 uip->uip_arpstate = UIAS_CLIENT_POPEN;
685 uap = (struct uniarp *)atm_allocate(&uniarp_pool);
687 UNIIP_ARP_TIMER(uip, 1 * ATM_HZ);
692 * Next, initiate an SVC to the server
694 if ((*inp->inf_createsvc)(&inp->inf_nif->nif_if, AF_ATM,
695 (caddr_t)&uip->uip_arpsvratm, &ivp)) {
696 atm_free((caddr_t)uap);
697 UNIIP_ARP_TIMER(uip, 1 * ATM_HZ);
702 * Finally, get everything set up and wait for the SVC
703 * connection to complete
705 uip->uip_arpsvrvcc = ivp;
706 ivp->iv_flags |= IVF_NOIDLE;
708 ATM_ADDR_COPY(&uip->uip_arpsvratm, &uap->ua_dstatm);
709 ATM_ADDR_COPY(&uip->uip_arpsvrsub, &uap->ua_dstatmsub);
712 LINK2TAIL(ivp, struct ipvcc, uap->ua_ivp, iv_arpnext);
713 ivp->iv_arpent = (struct arpmap *)uap;
715 LINK2TAIL(uap, struct uniarp, uniarp_nomaptab, ua_next);
722 * Process a UNI ARP interface timeout
724 * Called when a previously scheduled uniip arp interface timer expires.
725 * Processing will be based on the current uniip arp state.
730 * tip pointer to uniip arp timer control block
737 uniarp_iftimeout(tip)
738 struct atm_time *tip;
745 * Back-off to uniip control block
747 uip = (struct uniip *)
748 ((caddr_t)tip - (int)(&((struct uniip *)0)->uip_arptime));
750 ATM_DEBUG2("uniarp_iftimeout: uip=%p, state=%d\n", uip,
754 * Process timeout based on protocol state
756 switch (uip->uip_arpstate) {
758 case UIAS_CLIENT_POPEN:
760 * Retry opening arp server connection
762 uniarp_client_mode(uip, NULL);
765 case UIAS_CLIENT_REGISTER:
767 * Resend registration request
769 inp = uip->uip_ipnif;
770 (void) uniarp_arp_req(uip, &(IA_SIN(inp->inf_addr)->sin_addr));
775 UNIIP_ARP_TIMER(uip, 2 * ATM_HZ);
779 case UIAS_CLIENT_ACTIVE:
781 * Refresh our registration
783 inp = uip->uip_ipnif;
784 (void) uniarp_arp_req(uip, &(IA_SIN(inp->inf_addr)->sin_addr));
789 UNIIP_ARP_TIMER(uip, UNIARP_REGIS_RETRY);
794 log(LOG_ERR, "uniarp_iftimeout: invalid state %d\n",
801 * UNI ARP IOCTL support
803 * Function will be called at splnet.
806 * code PF_ATM sub-operation code
807 * data pointer to code specific parameter data area
808 * arg1 pointer to code specific argument
812 * errno error processing request - reason indicated
816 uniarp_ioctl(code, data, arg1)
821 struct atmaddreq *aap;
822 struct atmdelreq *adp;
823 struct atmsetreq *asp;
824 struct atminfreq *aip;
825 struct air_arp_rsp aar;
826 struct air_asrv_rsp asr;
829 struct ipvcc *ivp, *inext;
836 int err = 0, i, buf_len;
843 * Add a permanent ARP mapping
845 aap = (struct atmaddreq *)data;
846 uip = (struct uniip *)arg1;
847 if (aap->aar_arp_addr.address_format != T_ATM_ENDSYS_ADDR) {
851 atmsub.address_format = T_ATM_ABSENT;
852 atmsub.address_length = 0;
853 ip = SATOSIN(&aap->aar_arp_dst)->sin_addr;
856 * Validate IP address
858 if (uniarp_validate_ip(uip, &ip, aap->aar_arp_origin) != 0) {
864 * Add an entry to the cache
866 err = uniarp_cache_svc(uip, &ip, &aap->aar_arp_addr,
867 &atmsub, aap->aar_arp_origin);
872 * Delete an ARP mapping
874 adp = (struct atmdelreq *)data;
875 uip = (struct uniip *)arg1;
876 ip = SATOSIN(&adp->adr_arp_dst)->sin_addr;
879 * Now find the entry to be deleted
881 UNIARP_LOOKUP(ip.s_addr, uap);
888 * Notify all VCCs using this entry that they must finish
891 uap->ua_flags |= UAF_LOCKED;
892 for (ivp = uap->ua_ivp; ivp; ivp = inext) {
893 inext = ivp->iv_arpnext;
894 (*ivp->iv_ipnif->inf_arpnotify)(ivp, MAP_FAILED);
898 * Now free up the entry
902 atm_free((caddr_t)uap);
907 * Set interface ARP server address
909 asp = (struct atmsetreq *)data;
910 for (uip = uniip_head; uip; uip = uip->uip_next) {
911 if (uip->uip_ipnif->inf_nif == (struct atm_nif *)arg1)
920 * Check for our own address
922 usp = (struct unisig *)
923 uip->uip_ipnif->inf_nif->nif_pif->pif_siginst;
924 if (ATM_ADDR_EQUAL(&asp->asr_arp_addr, &usp->us_addr)) {
925 asp->asr_arp_addr.address_format = T_ATM_ABSENT;
929 * If we're going into server mode, make sure we can get
930 * the memory for the prefix list before continuing
932 if (asp->asr_arp_addr.address_format == T_ATM_ABSENT) {
933 i = asp->asr_arp_plen / sizeof(struct uniarp_prf);
938 buf_len = i * sizeof(struct uniarp_prf);
939 buf_addr = KM_ALLOC(buf_len, M_DEVBUF, M_NOWAIT);
940 if (buf_addr == NULL) {
944 err = copyin(asp->asr_arp_pbuf, buf_addr, buf_len);
946 KM_FREE(buf_addr, buf_len, M_DEVBUF);
950 /* Silence the compiler */
956 * Free any existing prefix address list
958 if (uip->uip_prefix != NULL) {
959 KM_FREE(uip->uip_prefix,
960 uip->uip_nprefix * sizeof(struct uniarp_prf),
962 uip->uip_prefix = NULL;
963 uip->uip_nprefix = 0;
966 if (asp->asr_arp_addr.address_format == T_ATM_ABSENT) {
968 * Set ATMARP server mode
970 uip->uip_prefix = (struct uniarp_prf *)buf_addr;
971 uip->uip_nprefix = i;
972 uniarp_server_mode(uip);
975 * Set ATMARP client mode
977 uniarp_client_mode(uip, &asp->asr_arp_addr);
982 * Get ARP table information
984 aip = (struct atminfreq *)data;
986 if (aip->air_arp_addr.sa_family != AF_INET)
988 dst = SATOSIN(&aip->air_arp_addr)->sin_addr.s_addr;
990 buf_addr = aip->air_buf_addr;
991 buf_len = aip->air_buf_len;
993 pip = ((struct siginst *)arg1)->si_pif;
996 * Run through entire arp table
998 for (i = 0; i < UNIARP_HASHSIZ; i++) {
999 for (uap = uniarp_arptab[i]; uap; uap = uap->ua_next) {
1001 * We only want valid entries learned
1002 * from the supplied interface.
1004 nip = uap->ua_intf->uip_ipnif->inf_nif;
1005 if (nip->nif_pif != pip)
1007 if ((dst != INADDR_ANY) &&
1008 (dst != uap->ua_dstip.s_addr))
1012 * Make sure there's room in the user's buffer
1014 if (buf_len < sizeof(aar)) {
1020 * Fill in info to be returned
1022 SATOSIN(&aar.aap_arp_addr)->sin_family =
1024 SATOSIN(&aar.aap_arp_addr)->sin_addr.s_addr =
1025 uap->ua_dstip.s_addr;
1026 (void) snprintf(aar.aap_intf,
1027 sizeof(aar.aap_intf), "%s%d",
1028 nip->nif_if.if_name,
1029 nip->nif_if.if_unit);
1030 aar.aap_flags = uap->ua_flags;
1031 aar.aap_origin = uap->ua_origin;
1032 if (uap->ua_flags & UAF_VALID)
1033 aar.aap_age = uap->ua_aging +
1034 uap->ua_retry * UNIARP_RETRY_AGE;
1037 ATM_ADDR_COPY(&uap->ua_dstatm, &aar.aap_addr);
1038 ATM_ADDR_COPY(&uap->ua_dstatmsub,
1042 * Copy the response into the user's buffer
1044 if ((err = copyout((caddr_t)&aar, buf_addr,
1047 buf_addr += sizeof(aar);
1048 buf_len -= sizeof(aar);
1055 * Now go through the 'nomap' table
1057 if (err || (dst != INADDR_ANY))
1059 for (uap = uniarp_nomaptab; uap; uap = uap->ua_next) {
1061 * We only want valid entries learned
1062 * from the supplied interface.
1064 nip = uap->ua_intf->uip_ipnif->inf_nif;
1065 if (nip->nif_pif != pip)
1069 * Make sure there's room in the user's buffer
1071 if (buf_len < sizeof(aar)) {
1077 * Fill in info to be returned
1079 SATOSIN(&aar.aap_arp_addr)->sin_family = AF_INET;
1080 SATOSIN(&aar.aap_arp_addr)->sin_addr.s_addr = 0;
1081 (void) snprintf(aar.aap_intf,
1082 sizeof(aar.aap_intf), "%s%d",
1083 nip->nif_if.if_name, nip->nif_if.if_unit);
1085 aar.aap_origin = uap->ua_origin;
1087 ATM_ADDR_COPY(&uap->ua_dstatm, &aar.aap_addr);
1088 ATM_ADDR_COPY(&uap->ua_dstatmsub,
1092 * Copy the response into the user's buffer
1094 if ((err = copyout((caddr_t)&aar, buf_addr,
1097 buf_addr += sizeof(aar);
1098 buf_len -= sizeof(aar);
1103 * Update the buffer pointer and length
1105 aip->air_buf_addr = buf_addr;
1106 aip->air_buf_len = buf_len;
1109 * If the user wants the refresh status reset and no
1110 * errors have been encountered, then do the reset
1112 if ((err == 0) && (aip->air_arp_flags & ARP_RESET_REF)) {
1113 for (i = 0; i < UNIARP_HASHSIZ; i++) {
1114 for (uap = uniarp_arptab[i]; uap;
1115 uap = uap->ua_next) {
1117 * We only want valid entries learned
1118 * from the supplied interface.
1120 nip = uap->ua_intf->uip_ipnif->inf_nif;
1121 if (nip->nif_pif != pip)
1123 if ((dst != INADDR_ANY) &&
1124 (dst != uap->ua_dstip.s_addr))
1128 * Reset refresh flag
1130 uap->ua_flags &= ~UAF_REFRESH;
1138 * Get ARP server information
1140 aip = (struct atminfreq *)data;
1141 nip = (struct atm_nif *)arg1;
1143 buf_addr = aip->air_buf_addr;
1144 buf_len = aip->air_buf_len;
1146 for (uip = uniip_head; uip; uip = uip->uip_next) {
1148 if (uip->uip_ipnif->inf_nif != nip)
1152 * Make sure there's room in the user's buffer
1154 if (buf_len < sizeof(asr)) {
1160 * Fill in info to be returned
1162 (void) snprintf(asr.asp_intf,
1163 sizeof(asr.asp_intf), "%s%d",
1164 nip->nif_if.if_name, nip->nif_if.if_unit);
1165 asr.asp_state = uip->uip_arpstate;
1166 if (uip->uip_arpstate == UIAS_SERVER_ACTIVE) {
1167 asr.asp_addr.address_format = T_ATM_ABSENT;
1168 asr.asp_addr.address_length = 0;
1170 ATM_ADDR_COPY(&uip->uip_arpsvratm,
1173 asr.asp_subaddr.address_format = T_ATM_ABSENT;
1174 asr.asp_subaddr.address_length = 0;
1175 asr.asp_nprefix = uip->uip_nprefix;
1178 * Copy the response into the user's buffer
1180 if ((err = copyout((caddr_t)&asr, buf_addr, sizeof(asr))) != 0)
1182 buf_addr += sizeof(asr);
1183 buf_len -= sizeof(asr);
1186 * Copy the prefix list into the user's buffer
1188 if (uip->uip_nprefix) {
1189 i = uip->uip_nprefix
1190 * sizeof(struct uniarp_prf);
1195 if ((err = copyout(uip->uip_prefix, buf_addr, i)) != 0)
1203 * Update the buffer pointer and length
1205 aip->air_buf_addr = buf_addr;
1206 aip->air_buf_len = buf_len;
1218 * Get Connection's Application/Owner Name
1221 * tok uniarp connection token (pointer to ipvcc)
1224 * addr pointer to string containing our name