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.8 2006/01/14 13:36:39 swildner Exp $
31 * ATM Forum UNI Support
32 * ---------------------
34 * UNI ATMARP support (RFC1577)
38 #include <netproto/atm/kern_include.h>
40 #include <netproto/atm/ipatm/ipatm_var.h>
41 #include <netproto/atm/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 (struct uniip *);
85 static void uniarp_client_mode (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 atm_untimeout(&uniarp_timer);
148 * De-register ourselves
150 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
174 uniarp_ipact(struct uniip *uip)
178 ATM_DEBUG1("uniarp_ipact: uip=%p\n", uip);
183 uip->uip_arpstate = UIAS_NOTCONF;
184 uip->uip_arpsvratm.address_format = T_ATM_ABSENT;
185 uip->uip_arpsvratm.address_length = 0;
186 uip->uip_arpsvrsub.address_format = T_ATM_ABSENT;
187 uip->uip_arpsvrsub.address_length = 0;
189 usp = (struct unisig *)uip->uip_ipnif->inf_nif->nif_pif->pif_siginst;
190 if (usp->us_addr.address_format != T_ATM_ABSENT)
191 uip->uip_flags |= UIF_IFADDR;
194 * Make sure aging timer is running
196 if ((uniarp_timer.ti_flag & TIF_QUEUED) == 0)
197 atm_timeout(&uniarp_timer, UNIARP_AGING, uniarp_aging);
204 * Process IP Network Interface Deactivation
206 * Called whenever an IP network interface becomes inactive. All VCCs
207 * for this interface should already have been closed.
212 * uip pointer to UNI IP interface
219 uniarp_ipdact(struct uniip *uip)
221 struct uniarp *uap, *unext;
224 ATM_DEBUG1("uniarp_ipdact: uip=%p\n", uip);
227 * Delete all interface entries
229 for (i = 0; i < UNIARP_HASHSIZ; i++) {
230 for (uap = uniarp_arptab[i]; uap; uap = unext) {
231 unext = uap->ua_next;
233 if (uap->ua_intf != uip)
237 * All VCCs should (better) be gone by now
240 panic("uniarp_ipdact: entry not empty");
243 * Clean up any loose ends
248 * Delete entry from arp table and free entry
251 atm_free((caddr_t)uap);
256 * Clean up 'nomap' table
258 for (uap = uniarp_nomaptab; uap; uap = unext) {
259 unext = uap->ua_next;
261 if (uap->ua_intf != uip)
265 * All VCCs should (better) be gone by now
268 panic("uniarp_ipdact: entry not empty");
271 * Clean up any loose ends
276 * Delete entry from 'no map' table and free entry
278 UNLINK(uap, struct uniarp, uniarp_nomaptab, ua_next);
279 atm_free((caddr_t)uap);
283 * Also clean up pvc table
285 for (uap = uniarp_pvctab; uap; uap = unext) {
286 unext = uap->ua_next;
288 if (uap->ua_intf != uip)
292 * All PVCs should (better) be gone by now
294 panic("uniarp_ipdact: pvc table not empty");
298 * Cancel arp interface timer
300 UNIIP_ARP_CANCEL(uip);
303 * Stop aging timer if this is the last active interface
305 if (uniip_head == uip && uip->uip_next == NULL)
306 atm_untimeout(&uniarp_timer);
311 * Process Interface ATM Address Change
313 * This function is called whenever the ATM address for a physical
314 * interface is set/changed.
319 * sip pointer to interface's UNI signalling instance
326 uniarp_ifaddr(struct siginst *sip)
331 ATM_DEBUG1("uniarp_ifaddr: sip=%p\n", sip);
334 * We've got to handle this for every network interface
336 for (nip = sip->si_pif->pif_nif; nip; nip = nip->nif_pnext) {
339 * Find our control blocks
341 for (uip = uniip_head; uip; uip = uip->uip_next) {
342 if (uip->uip_ipnif->inf_nif == nip)
349 * We don't support changing prefix (yet)
351 if (uip->uip_flags & UIF_IFADDR) {
352 log(LOG_ERR, "uniarp_ifaddr: change not supported\n");
357 * Note that address has been set and figure out what
360 uip->uip_flags |= UIF_IFADDR;
362 if (uip->uip_arpstate == UIAS_CLIENT_PADDR) {
364 * This is what we're waiting for
366 uniarp_client_mode(uip, NULL);
367 } else if (uip->uip_arpstate == UIAS_SERVER_ACTIVE) {
369 * Set new local arpserver atm address
371 ATM_ADDR_SEL_COPY(&sip->si_addr, nip->nif_sel,
372 &uip->uip_arpsvratm);
381 * Set ATMARP Server Mode
383 * This function is called to configure the local node to become the
384 * ATMARP server for the specified LIS.
389 * uip pointer to UNI IP interface
396 uniarp_server_mode(struct uniip *uip)
401 struct ipvcc *ivp, *inext;
402 struct uniarp *uap, *unext;
405 ATM_DEBUG1("uniarp_server_mode: uip=%p\n", uip);
408 * Handle client/server mode changes first
410 switch (uip->uip_arpstate) {
413 case UIAS_SERVER_ACTIVE:
414 case UIAS_CLIENT_PADDR:
420 case UIAS_CLIENT_POPEN:
422 * We're becoming the server, so kill the pending connection
424 UNIIP_ARP_CANCEL(uip);
425 if ((ivp = uip->uip_arpsvrvcc) != NULL) {
426 ivp->iv_flags &= ~IVF_NOIDLE;
427 uip->uip_arpsvrvcc = NULL;
428 (*ivp->iv_ipnif->inf_arpnotify)(ivp, MAP_FAILED);
432 case UIAS_CLIENT_REGISTER:
433 case UIAS_CLIENT_ACTIVE:
435 * We're becoming the server, but leave existing VCC as a
438 UNIIP_ARP_CANCEL(uip);
439 ivp = uip->uip_arpsvrvcc;
440 ivp->iv_flags &= ~IVF_NOIDLE;
441 uip->uip_arpsvrvcc = NULL;
446 * Revalidate status for all arp entries on this interface
448 for (i = 0; i < UNIARP_HASHSIZ; i++) {
449 for (uap = uniarp_arptab[i]; uap; uap = unext) {
450 unext = uap->ua_next;
452 if (uap->ua_intf != uip)
455 if (uap->ua_origin >= UAO_PERM)
458 if (uap->ua_origin >= UAO_SCSP) {
459 if (uniarp_validate_ip(uip, &uap->ua_dstip,
460 uap->ua_origin) == 0)
464 if (uap->ua_ivp == NULL) {
467 atm_free((caddr_t)uap);
471 if (uap->ua_flags & UAF_VALID) {
472 uap->ua_flags |= UAF_LOCKED;
473 for (ivp = uap->ua_ivp; ivp; ivp = inext) {
474 inext = ivp->iv_arpnext;
475 (*ivp->iv_ipnif->inf_arpnotify)
478 uap->ua_flags &= ~(UAF_LOCKED | UAF_VALID);
486 * OK, now let's make ourselves the server
488 inp = uip->uip_ipnif;
490 sgp = nip->nif_pif->pif_siginst;
491 ATM_ADDR_SEL_COPY(&sgp->si_addr, nip->nif_sel, &uip->uip_arpsvratm);
492 uip->uip_arpsvrip = IA_SIN(inp->inf_addr)->sin_addr;
493 uip->uip_arpstate = UIAS_SERVER_ACTIVE;
499 * Set ATMARP Client Mode
501 * This function is called to configure the local node to be an ATMARP
502 * client on the specified LIS using the specified ATMARP server.
507 * uip pointer to UNI IP interface
508 * aap pointer to the ATMARP server's ATM address
515 uniarp_client_mode(struct uniip *uip, Atm_addr *aap)
517 struct ip_nif *inp = uip->uip_ipnif;
518 struct uniarp *uap, *unext;
519 struct ipvcc *ivp, *inext;
522 ATM_DEBUG2("uniarp_client_mode: uip=%p, atm=(%s,-)\n",
523 uip, aap ? unisig_addr_print(aap): "-");
526 * Handle client/server mode changes first
528 switch (uip->uip_arpstate) {
531 case UIAS_CLIENT_PADDR:
537 case UIAS_CLIENT_POPEN:
539 * If this is this a timeout retry, just go do it
545 * If this isn't really a different arpserver, we're done
547 if (ATM_ADDR_EQUAL(aap, &uip->uip_arpsvratm))
551 * We're changing servers, so kill the pending connection
553 UNIIP_ARP_CANCEL(uip);
554 if ((ivp = uip->uip_arpsvrvcc) != NULL) {
555 ivp->iv_flags &= ~IVF_NOIDLE;
556 uip->uip_arpsvrvcc = NULL;
557 (*ivp->iv_ipnif->inf_arpnotify)(ivp, MAP_FAILED);
561 case UIAS_CLIENT_REGISTER:
562 case UIAS_CLIENT_ACTIVE:
564 * If this isn't really a different arpserver, we're done
566 if (ATM_ADDR_EQUAL(aap, &uip->uip_arpsvratm))
570 * We're changing servers, but leave existing VCC as a
573 UNIIP_ARP_CANCEL(uip);
574 ivp = uip->uip_arpsvrvcc;
575 ivp->iv_flags &= ~IVF_NOIDLE;
576 uip->uip_arpsvrvcc = NULL;
579 case UIAS_SERVER_ACTIVE:
581 * We're changing from server mode, so...
583 * Reset valid/authoritative status for all arp entries
586 for (i = 0; i < UNIARP_HASHSIZ; i++) {
587 for (uap = uniarp_arptab[i]; uap; uap = unext) {
588 unext = uap->ua_next;
590 if (uap->ua_intf != uip)
593 if (uap->ua_origin >= UAO_PERM)
596 if (uap->ua_ivp == NULL) {
599 atm_free((caddr_t)uap);
603 if (uap->ua_flags & UAF_VALID) {
604 uap->ua_flags |= UAF_LOCKED;
605 for (ivp = uap->ua_ivp; ivp;
607 inext = ivp->iv_arpnext;
608 (*ivp->iv_ipnif->inf_arpnotify)
612 ~(UAF_LOCKED | UAF_VALID);
618 uip->uip_arpsvratm.address_format = T_ATM_ABSENT;
619 uip->uip_arpsvratm.address_length = 0;
620 uip->uip_arpsvrsub.address_format = T_ATM_ABSENT;
621 uip->uip_arpsvrsub.address_length = 0;
622 uip->uip_arpsvrip.s_addr = 0;
627 * Save the arp server address, if supplied now
630 ATM_ADDR_COPY(aap, &uip->uip_arpsvratm);
633 * If the interface's ATM address isn't set yet, then we
634 * can't do much until it is
636 if ((uip->uip_flags & UIF_IFADDR) == 0) {
637 uip->uip_arpstate = UIAS_CLIENT_PADDR;
642 * Just to keep things simple, if we already have (or are trying to
643 * setup) any SVCs to our new server, kill the connections so we can
644 * open a "fresh" SVC for the arpserver connection.
646 for (i = 0; i < UNIARP_HASHSIZ; i++) {
647 for (uap = uniarp_arptab[i]; uap; uap = unext) {
648 unext = uap->ua_next;
650 if (ATM_ADDR_EQUAL(&uip->uip_arpsvratm,
652 ATM_ADDR_EQUAL(&uip->uip_arpsvrsub,
653 &uap->ua_dstatmsub)) {
654 uap->ua_flags &= ~UAF_VALID;
655 for (ivp = uap->ua_ivp; ivp; ivp = inext) {
656 inext = ivp->iv_arpnext;
657 (*inp->inf_arpnotify)(ivp, MAP_FAILED);
662 for (uap = uniarp_nomaptab; uap; uap = unext) {
663 unext = uap->ua_next;
665 if (ATM_ADDR_EQUAL(&uip->uip_arpsvratm, &uap->ua_dstatm) &&
666 ATM_ADDR_EQUAL(&uip->uip_arpsvrsub, &uap->ua_dstatmsub)) {
667 uap->ua_flags &= ~UAF_VALID;
668 for (ivp = uap->ua_ivp; ivp; ivp = inext) {
669 inext = ivp->iv_arpnext;
670 (*inp->inf_arpnotify)(ivp, MAP_FAILED);
676 * Now, get an arp entry for the server connection
678 uip->uip_arpstate = UIAS_CLIENT_POPEN;
679 uap = (struct uniarp *)atm_allocate(&uniarp_pool);
681 UNIIP_ARP_TIMER(uip, 1 * ATM_HZ);
686 * Next, initiate an SVC to the server
688 if ((*inp->inf_createsvc)(&inp->inf_nif->nif_if, AF_ATM,
689 (caddr_t)&uip->uip_arpsvratm, &ivp)) {
690 atm_free((caddr_t)uap);
691 UNIIP_ARP_TIMER(uip, 1 * ATM_HZ);
696 * Finally, get everything set up and wait for the SVC
697 * connection to complete
699 uip->uip_arpsvrvcc = ivp;
700 ivp->iv_flags |= IVF_NOIDLE;
702 ATM_ADDR_COPY(&uip->uip_arpsvratm, &uap->ua_dstatm);
703 ATM_ADDR_COPY(&uip->uip_arpsvrsub, &uap->ua_dstatmsub);
706 LINK2TAIL(ivp, struct ipvcc, uap->ua_ivp, iv_arpnext);
707 ivp->iv_arpent = (struct arpmap *)uap;
709 LINK2TAIL(uap, struct uniarp, uniarp_nomaptab, ua_next);
716 * Process a UNI ARP interface timeout
718 * Called when a previously scheduled uniip arp interface timer expires.
719 * Processing will be based on the current uniip arp state.
724 * tip pointer to uniip arp timer control block
731 uniarp_iftimeout(struct atm_time *tip)
738 * Back-off to uniip control block
740 uip = (struct uniip *)
741 ((caddr_t)tip - (int)(&((struct uniip *)0)->uip_arptime));
743 ATM_DEBUG2("uniarp_iftimeout: uip=%p, state=%d\n", uip,
747 * Process timeout based on protocol state
749 switch (uip->uip_arpstate) {
751 case UIAS_CLIENT_POPEN:
753 * Retry opening arp server connection
755 uniarp_client_mode(uip, NULL);
758 case UIAS_CLIENT_REGISTER:
760 * Resend registration request
762 inp = uip->uip_ipnif;
763 uniarp_arp_req(uip, &(IA_SIN(inp->inf_addr)->sin_addr));
768 UNIIP_ARP_TIMER(uip, 2 * ATM_HZ);
772 case UIAS_CLIENT_ACTIVE:
774 * Refresh our registration
776 inp = uip->uip_ipnif;
777 uniarp_arp_req(uip, &(IA_SIN(inp->inf_addr)->sin_addr));
782 UNIIP_ARP_TIMER(uip, UNIARP_REGIS_RETRY);
787 log(LOG_ERR, "uniarp_iftimeout: invalid state %d\n",
794 * UNI ARP IOCTL support
796 * Function will be called at splnet.
799 * code PF_ATM sub-operation code
800 * data pointer to code specific parameter data area
801 * arg1 pointer to code specific argument
805 * errno error processing request - reason indicated
809 uniarp_ioctl(int code, caddr_t data, caddr_t arg1)
811 struct atmaddreq *aap;
812 struct atmdelreq *adp;
813 struct atmsetreq *asp;
814 struct atminfreq *aip;
815 struct air_arp_rsp aar;
816 struct air_asrv_rsp asr;
819 struct ipvcc *ivp, *inext;
826 int err = 0, i, buf_len;
833 * Add a permanent ARP mapping
835 aap = (struct atmaddreq *)data;
836 uip = (struct uniip *)arg1;
837 if (aap->aar_arp_addr.address_format != T_ATM_ENDSYS_ADDR) {
841 atmsub.address_format = T_ATM_ABSENT;
842 atmsub.address_length = 0;
843 ip = SATOSIN(&aap->aar_arp_dst)->sin_addr;
846 * Validate IP address
848 if (uniarp_validate_ip(uip, &ip, aap->aar_arp_origin) != 0) {
854 * Add an entry to the cache
856 err = uniarp_cache_svc(uip, &ip, &aap->aar_arp_addr,
857 &atmsub, aap->aar_arp_origin);
862 * Delete an ARP mapping
864 adp = (struct atmdelreq *)data;
865 uip = (struct uniip *)arg1;
866 ip = SATOSIN(&adp->adr_arp_dst)->sin_addr;
869 * Now find the entry to be deleted
871 UNIARP_LOOKUP(ip.s_addr, uap);
878 * Notify all VCCs using this entry that they must finish
881 uap->ua_flags |= UAF_LOCKED;
882 for (ivp = uap->ua_ivp; ivp; ivp = inext) {
883 inext = ivp->iv_arpnext;
884 (*ivp->iv_ipnif->inf_arpnotify)(ivp, MAP_FAILED);
888 * Now free up the entry
892 atm_free((caddr_t)uap);
897 * Set interface ARP server address
899 asp = (struct atmsetreq *)data;
900 for (uip = uniip_head; uip; uip = uip->uip_next) {
901 if (uip->uip_ipnif->inf_nif == (struct atm_nif *)arg1)
910 * Check for our own address
912 usp = (struct unisig *)
913 uip->uip_ipnif->inf_nif->nif_pif->pif_siginst;
914 if (ATM_ADDR_EQUAL(&asp->asr_arp_addr, &usp->us_addr)) {
915 asp->asr_arp_addr.address_format = T_ATM_ABSENT;
919 * If we're going into server mode, make sure we can get
920 * the memory for the prefix list before continuing
922 if (asp->asr_arp_addr.address_format == T_ATM_ABSENT) {
923 i = asp->asr_arp_plen / sizeof(struct uniarp_prf);
928 buf_len = i * sizeof(struct uniarp_prf);
929 buf_addr = KM_ALLOC(buf_len, M_DEVBUF,
930 M_INTWAIT | M_NULLOK);
931 if (buf_addr == NULL) {
935 err = copyin(asp->asr_arp_pbuf, buf_addr, buf_len);
937 KM_FREE(buf_addr, buf_len, M_DEVBUF);
941 /* Silence the compiler */
947 * Free any existing prefix address list
949 if (uip->uip_prefix != NULL) {
950 KM_FREE(uip->uip_prefix,
951 uip->uip_nprefix * sizeof(struct uniarp_prf),
953 uip->uip_prefix = NULL;
954 uip->uip_nprefix = 0;
957 if (asp->asr_arp_addr.address_format == T_ATM_ABSENT) {
959 * Set ATMARP server mode
961 uip->uip_prefix = (struct uniarp_prf *)buf_addr;
962 uip->uip_nprefix = i;
963 uniarp_server_mode(uip);
966 * Set ATMARP client mode
968 uniarp_client_mode(uip, &asp->asr_arp_addr);
973 * Get ARP table information
975 aip = (struct atminfreq *)data;
977 if (aip->air_arp_addr.sa_family != AF_INET)
979 dst = SATOSIN(&aip->air_arp_addr)->sin_addr.s_addr;
981 buf_addr = aip->air_buf_addr;
982 buf_len = aip->air_buf_len;
984 pip = ((struct siginst *)arg1)->si_pif;
987 * Run through entire arp table
989 for (i = 0; i < UNIARP_HASHSIZ; i++) {
990 for (uap = uniarp_arptab[i]; uap; uap = uap->ua_next) {
992 * We only want valid entries learned
993 * from the supplied interface.
995 nip = uap->ua_intf->uip_ipnif->inf_nif;
996 if (nip->nif_pif != pip)
998 if ((dst != INADDR_ANY) &&
999 (dst != uap->ua_dstip.s_addr))
1003 * Make sure there's room in the user's buffer
1005 if (buf_len < sizeof(aar)) {
1011 * Fill in info to be returned
1013 SATOSIN(&aar.aap_arp_addr)->sin_family =
1015 SATOSIN(&aar.aap_arp_addr)->sin_addr.s_addr =
1016 uap->ua_dstip.s_addr;
1017 strlcpy(aar.aap_intf,
1018 nip->nif_if.if_xname,
1019 sizeof(aar.aap_intf));
1020 aar.aap_flags = uap->ua_flags;
1021 aar.aap_origin = uap->ua_origin;
1022 if (uap->ua_flags & UAF_VALID)
1023 aar.aap_age = uap->ua_aging +
1024 uap->ua_retry * UNIARP_RETRY_AGE;
1027 ATM_ADDR_COPY(&uap->ua_dstatm, &aar.aap_addr);
1028 ATM_ADDR_COPY(&uap->ua_dstatmsub,
1032 * Copy the response into the user's buffer
1034 if ((err = copyout((caddr_t)&aar, buf_addr,
1037 buf_addr += sizeof(aar);
1038 buf_len -= sizeof(aar);
1045 * Now go through the 'nomap' table
1047 if (err || (dst != INADDR_ANY))
1049 for (uap = uniarp_nomaptab; uap; uap = uap->ua_next) {
1051 * We only want valid entries learned
1052 * from the supplied interface.
1054 nip = uap->ua_intf->uip_ipnif->inf_nif;
1055 if (nip->nif_pif != pip)
1059 * Make sure there's room in the user's buffer
1061 if (buf_len < sizeof(aar)) {
1067 * Fill in info to be returned
1069 SATOSIN(&aar.aap_arp_addr)->sin_family = AF_INET;
1070 SATOSIN(&aar.aap_arp_addr)->sin_addr.s_addr = 0;
1071 strlcpy(aar.aap_intf,
1072 nip->nif_if.if_xname,
1073 sizeof(aar.aap_intf));
1075 aar.aap_origin = uap->ua_origin;
1077 ATM_ADDR_COPY(&uap->ua_dstatm, &aar.aap_addr);
1078 ATM_ADDR_COPY(&uap->ua_dstatmsub,
1082 * Copy the response into the user's buffer
1084 if ((err = copyout((caddr_t)&aar, buf_addr,
1087 buf_addr += sizeof(aar);
1088 buf_len -= sizeof(aar);
1093 * Update the buffer pointer and length
1095 aip->air_buf_addr = buf_addr;
1096 aip->air_buf_len = buf_len;
1099 * If the user wants the refresh status reset and no
1100 * errors have been encountered, then do the reset
1102 if ((err == 0) && (aip->air_arp_flags & ARP_RESET_REF)) {
1103 for (i = 0; i < UNIARP_HASHSIZ; i++) {
1104 for (uap = uniarp_arptab[i]; uap;
1105 uap = uap->ua_next) {
1107 * We only want valid entries learned
1108 * from the supplied interface.
1110 nip = uap->ua_intf->uip_ipnif->inf_nif;
1111 if (nip->nif_pif != pip)
1113 if ((dst != INADDR_ANY) &&
1114 (dst != uap->ua_dstip.s_addr))
1118 * Reset refresh flag
1120 uap->ua_flags &= ~UAF_REFRESH;
1128 * Get ARP server information
1130 aip = (struct atminfreq *)data;
1131 nip = (struct atm_nif *)arg1;
1133 buf_addr = aip->air_buf_addr;
1134 buf_len = aip->air_buf_len;
1136 for (uip = uniip_head; uip; uip = uip->uip_next) {
1138 if (uip->uip_ipnif->inf_nif != nip)
1142 * Make sure there's room in the user's buffer
1144 if (buf_len < sizeof(asr)) {
1150 * Fill in info to be returned
1152 strlcpy(asr.asp_intf,
1153 nip->nif_if.if_xname,
1154 sizeof(asr.asp_intf));
1155 asr.asp_state = uip->uip_arpstate;
1156 if (uip->uip_arpstate == UIAS_SERVER_ACTIVE) {
1157 asr.asp_addr.address_format = T_ATM_ABSENT;
1158 asr.asp_addr.address_length = 0;
1160 ATM_ADDR_COPY(&uip->uip_arpsvratm,
1163 asr.asp_subaddr.address_format = T_ATM_ABSENT;
1164 asr.asp_subaddr.address_length = 0;
1165 asr.asp_nprefix = uip->uip_nprefix;
1168 * Copy the response into the user's buffer
1170 if ((err = copyout((caddr_t)&asr, buf_addr, sizeof(asr))) != 0)
1172 buf_addr += sizeof(asr);
1173 buf_len -= sizeof(asr);
1176 * Copy the prefix list into the user's buffer
1178 if (uip->uip_nprefix) {
1179 i = uip->uip_nprefix
1180 * sizeof(struct uniarp_prf);
1185 if ((err = copyout(uip->uip_prefix, buf_addr, i)) != 0)
1193 * Update the buffer pointer and length
1195 aip->air_buf_addr = buf_addr;
1196 aip->air_buf_len = buf_len;
1208 * Get Connection's Application/Owner Name
1211 * tok uniarp connection token (pointer to ipvcc)
1214 * addr pointer to string containing our name
1218 uniarp_getname(void *tok)