2 * ===================================
3 * HARP | Host ATM Research Platform
4 * ===================================
7 * This Host ATM Research Platform ("HARP") file (the "Software") is
8 * made available by Network Computing Services, Inc. ("NetworkCS")
9 * "AS IS". NetworkCS does not provide maintenance, improvements or
10 * support of any kind.
12 * NETWORKCS MAKES NO WARRANTIES OR REPRESENTATIONS, EXPRESS OR IMPLIED,
13 * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
14 * AND FITNESS FOR A PARTICULAR PURPOSE, AS TO ANY ELEMENT OF THE
15 * SOFTWARE OR ANY SUPPORT PROVIDED IN CONNECTION WITH THIS SOFTWARE.
16 * In no event shall NetworkCS be responsible for any damages, including
17 * but not limited to consequential damages, arising from or relating to
18 * any use of the Software or related support.
20 * Copyright 1994-1998 Network Computing Services, Inc.
22 * Copies of this Software may be made, however, the above copyright
23 * notice must be reproduced on all copies.
27 * ATM Forum UNI Support
28 * ---------------------
30 * UNI ATMARP support (RFC1577)
33 #include <sys/cdefs.h>
34 __FBSDID("$FreeBSD$");
36 #include <sys/param.h>
37 #include <sys/systm.h>
38 #include <sys/errno.h>
39 #include <sys/malloc.h>
41 #include <sys/socket.h>
42 #include <sys/socketvar.h>
43 #include <sys/syslog.h>
44 #include <sys/kernel.h>
45 #include <sys/sysctl.h>
47 #include <netinet/in.h>
48 #include <netinet/in_var.h>
49 #include <netatm/port.h>
50 #include <netatm/queue.h>
51 #include <netatm/atm.h>
52 #include <netatm/atm_sys.h>
53 #include <netatm/atm_sap.h>
54 #include <netatm/atm_cm.h>
55 #include <netatm/atm_if.h>
56 #include <netatm/atm_vc.h>
57 #include <netatm/atm_ioctl.h>
58 #include <netatm/atm_sigmgr.h>
59 #include <netatm/atm_stack.h>
60 #include <netatm/atm_pcb.h>
61 #include <netatm/atm_var.h>
63 #include <netatm/ipatm/ipatm_var.h>
64 #include <netatm/ipatm/ipatm_serv.h>
65 #include <netatm/uni/unisig_var.h>
66 #include <netatm/uni/uniip_var.h>
73 struct uniarp *uniarp_arptab[UNIARP_HASHSIZ] = {NULL};
74 struct uniarp *uniarp_nomaptab = NULL;
75 struct uniarp *uniarp_pvctab = NULL;
76 struct atm_time uniarp_timer = {0, 0}; /* Aging timer */
77 struct uniarp_stat uniarp_stat = {0};
80 * net.harp.uni.uniarp_print
83 SYSCTL_INT(_net_harp_uni, OID_AUTO, uniarp_print, CTLFLAG_RW,
84 &uniarp_print, 0, "dump UNI/ARP messages");
86 Atm_endpoint uniarp_endpt = {
104 uma_zone_t uniarp_zone;
110 static void uniarp_server_mode(struct uniip *);
111 static void uniarp_client_mode(struct uniip *, Atm_addr *);
115 * Process module loading notification
117 * Called whenever the uni module is initializing.
123 * 0 initialization successful
124 * errno initialization failed - reason indicated
132 uniarp_zone = uma_zcreate("uni arp", sizeof(struct uniarp), NULL, NULL,
133 NULL, NULL, UMA_ALIGN_PTR, 0);
134 if (uniarp_zone == NULL)
135 panic("uniarp_start: uma_zcreate");
138 * Register our endpoint
140 err = atm_endpoint_register(&uniarp_endpt);
146 * Process module unloading notification
148 * Called whenever the uni module is about to be unloaded. All signalling
149 * instances will have been previously detached. All uniarp resources
165 * Make sure the arp table is empty
167 for (i = 0; i < UNIARP_HASHSIZ; i++) {
168 if (uniarp_arptab[i] != NULL)
169 panic("uniarp_stop: arp table not empty");
175 (void) atm_untimeout(&uniarp_timer);
178 * De-register ourselves
180 (void) atm_endpoint_deregister(&uniarp_endpt);
183 * Free our storage pools
185 uma_zdestroy(uniarp_zone);
190 * Process IP Network Interface Activation
192 * Called whenever an IP network interface becomes active.
197 * uip pointer to UNI IP interface
209 ATM_DEBUG1("uniarp_ipact: uip=%p\n", uip);
214 uip->uip_arpstate = UIAS_NOTCONF;
215 uip->uip_arpsvratm.address_format = T_ATM_ABSENT;
216 uip->uip_arpsvratm.address_length = 0;
217 uip->uip_arpsvrsub.address_format = T_ATM_ABSENT;
218 uip->uip_arpsvrsub.address_length = 0;
220 usp = (struct unisig *)uip->uip_ipnif->inf_nif->nif_pif->pif_siginst;
221 if (usp->us_addr.address_format != T_ATM_ABSENT)
222 uip->uip_flags |= UIF_IFADDR;
225 * Make sure aging timer is running
227 if ((uniarp_timer.ti_flag & TIF_QUEUED) == 0)
228 atm_timeout(&uniarp_timer, UNIARP_AGING, uniarp_aging);
235 * Process IP Network Interface Deactivation
237 * Called whenever an IP network interface becomes inactive. All VCCs
238 * for this interface should already have been closed.
243 * uip pointer to UNI IP interface
253 struct uniarp *uap, *unext;
256 ATM_DEBUG1("uniarp_ipdact: uip=%p\n", uip);
259 * Delete all interface entries
261 for (i = 0; i < UNIARP_HASHSIZ; i++) {
262 for (uap = uniarp_arptab[i]; uap; uap = unext) {
263 unext = uap->ua_next;
265 if (uap->ua_intf != uip)
269 * All VCCs should (better) be gone by now
272 panic("uniarp_ipdact: entry not empty");
275 * Clean up any loose ends
280 * Delete entry from arp table and free entry
283 uma_zfree(uniarp_zone, uap);
288 * Clean up 'nomap' table
290 for (uap = uniarp_nomaptab; uap; uap = unext) {
291 unext = uap->ua_next;
293 if (uap->ua_intf != uip)
297 * All VCCs should (better) be gone by now
300 panic("uniarp_ipdact: entry not empty");
303 * Clean up any loose ends
308 * Delete entry from 'no map' table and free entry
310 UNLINK(uap, struct uniarp, uniarp_nomaptab, ua_next);
311 uma_zfree(uniarp_zone, uap);
315 * Also clean up pvc table
317 for (uap = uniarp_pvctab; uap; uap = unext) {
318 unext = uap->ua_next;
320 if (uap->ua_intf != uip)
324 * All PVCs should (better) be gone by now
326 panic("uniarp_ipdact: pvc table not empty");
330 * Cancel arp interface timer
332 UNIIP_ARP_CANCEL(uip);
335 * Stop aging timer if this is the last active interface
337 if (uniip_head == uip && uip->uip_next == NULL)
338 (void) atm_untimeout(&uniarp_timer);
343 * Process Interface ATM Address Change
345 * This function is called whenever the ATM address for a physical
346 * interface is set/changed.
351 * sip pointer to interface's UNI signalling instance
364 ATM_DEBUG1("uniarp_ifaddr: sip=%p\n", sip);
367 * We've got to handle this for every network interface
369 for (nip = sip->si_pif->pif_nif; nip; nip = nip->nif_pnext) {
372 * Find our control blocks
374 for (uip = uniip_head; uip; uip = uip->uip_next) {
375 if (uip->uip_ipnif->inf_nif == nip)
382 * We don't support changing prefix (yet)
384 if (uip->uip_flags & UIF_IFADDR) {
385 log(LOG_ERR, "uniarp_ifaddr: change not supported\n");
390 * Note that address has been set and figure out what
393 uip->uip_flags |= UIF_IFADDR;
395 if (uip->uip_arpstate == UIAS_CLIENT_PADDR) {
397 * This is what we're waiting for
399 uniarp_client_mode(uip, NULL);
400 } else if (uip->uip_arpstate == UIAS_SERVER_ACTIVE) {
402 * Set new local arpserver atm address
404 ATM_ADDR_SEL_COPY(&sip->si_addr, nip->nif_sel,
405 &uip->uip_arpsvratm);
414 * Set ATMARP Server Mode
416 * This function is called to configure the local node to become the
417 * ATMARP server for the specified LIS.
422 * uip pointer to UNI IP interface
429 uniarp_server_mode(uip)
435 struct ipvcc *ivp, *inext;
436 struct uniarp *uap, *unext;
439 ATM_DEBUG1("uniarp_server_mode: uip=%p\n", uip);
442 * Handle client/server mode changes first
444 switch (uip->uip_arpstate) {
447 case UIAS_SERVER_ACTIVE:
448 case UIAS_CLIENT_PADDR:
454 case UIAS_CLIENT_POPEN:
456 * We're becoming the server, so kill the pending connection
458 UNIIP_ARP_CANCEL(uip);
459 if ((ivp = uip->uip_arpsvrvcc) != NULL) {
460 ivp->iv_flags &= ~IVF_NOIDLE;
461 uip->uip_arpsvrvcc = NULL;
462 (*ivp->iv_ipnif->inf_arpnotify)(ivp, MAP_FAILED);
466 case UIAS_CLIENT_REGISTER:
467 case UIAS_CLIENT_ACTIVE:
469 * We're becoming the server, but leave existing VCC as a
472 UNIIP_ARP_CANCEL(uip);
473 ivp = uip->uip_arpsvrvcc;
474 ivp->iv_flags &= ~IVF_NOIDLE;
475 uip->uip_arpsvrvcc = NULL;
480 * Revalidate status for all arp entries on this interface
482 for (i = 0; i < UNIARP_HASHSIZ; i++) {
483 for (uap = uniarp_arptab[i]; uap; uap = unext) {
484 unext = uap->ua_next;
486 if (uap->ua_intf != uip)
489 if (uap->ua_origin >= UAO_PERM)
492 if (uap->ua_origin >= UAO_SCSP) {
493 if (uniarp_validate_ip(uip, &uap->ua_dstip,
494 uap->ua_origin) == 0)
498 if (uap->ua_ivp == NULL) {
501 uma_zfree(uniarp_zone, uap);
505 if (uap->ua_flags & UAF_VALID) {
506 uap->ua_flags |= UAF_LOCKED;
507 for (ivp = uap->ua_ivp; ivp; ivp = inext) {
508 inext = ivp->iv_arpnext;
509 (*ivp->iv_ipnif->inf_arpnotify)
512 uap->ua_flags &= ~(UAF_LOCKED | UAF_VALID);
520 * OK, now let's make ourselves the server
522 inp = uip->uip_ipnif;
524 sgp = nip->nif_pif->pif_siginst;
525 ATM_ADDR_SEL_COPY(&sgp->si_addr, nip->nif_sel, &uip->uip_arpsvratm);
526 uip->uip_arpsvrip = IA_SIN(inp->inf_addr)->sin_addr;
527 uip->uip_arpstate = UIAS_SERVER_ACTIVE;
533 * Set ATMARP Client Mode
535 * This function is called to configure the local node to be an ATMARP
536 * client on the specified LIS using the specified ATMARP server.
541 * uip pointer to UNI IP interface
542 * aap pointer to the ATMARP server's ATM address
549 uniarp_client_mode(uip, aap)
553 struct ip_nif *inp = uip->uip_ipnif;
554 struct uniarp *uap, *unext;
555 struct ipvcc *ivp, *inext;
558 ATM_DEBUG2("uniarp_client_mode: uip=%p, atm=(%s,-)\n",
559 uip, aap ? unisig_addr_print(aap): "-");
562 * Handle client/server mode changes first
564 switch (uip->uip_arpstate) {
567 case UIAS_CLIENT_PADDR:
573 case UIAS_CLIENT_POPEN:
575 * If this is this a timeout retry, just go do it
581 * If this isn't really a different arpserver, we're done
583 if (ATM_ADDR_EQUAL(aap, &uip->uip_arpsvratm))
587 * We're changing servers, so kill the pending connection
589 UNIIP_ARP_CANCEL(uip);
590 if ((ivp = uip->uip_arpsvrvcc) != NULL) {
591 ivp->iv_flags &= ~IVF_NOIDLE;
592 uip->uip_arpsvrvcc = NULL;
593 (*ivp->iv_ipnif->inf_arpnotify)(ivp, MAP_FAILED);
597 case UIAS_CLIENT_REGISTER:
598 case UIAS_CLIENT_ACTIVE:
600 * If this isn't really a different arpserver, we're done
602 if (ATM_ADDR_EQUAL(aap, &uip->uip_arpsvratm))
606 * We're changing servers, but leave existing VCC as a
609 UNIIP_ARP_CANCEL(uip);
610 ivp = uip->uip_arpsvrvcc;
611 ivp->iv_flags &= ~IVF_NOIDLE;
612 uip->uip_arpsvrvcc = NULL;
615 case UIAS_SERVER_ACTIVE:
617 * We're changing from server mode, so...
619 * Reset valid/authoritative status for all arp entries
622 for (i = 0; i < UNIARP_HASHSIZ; i++) {
623 for (uap = uniarp_arptab[i]; uap; uap = unext) {
624 unext = uap->ua_next;
626 if (uap->ua_intf != uip)
629 if (uap->ua_origin >= UAO_PERM)
632 if (uap->ua_ivp == NULL) {
635 uma_zfree(uniarp_zone, uap);
639 if (uap->ua_flags & UAF_VALID) {
640 uap->ua_flags |= UAF_LOCKED;
641 for (ivp = uap->ua_ivp; ivp;
643 inext = ivp->iv_arpnext;
644 (*ivp->iv_ipnif->inf_arpnotify)
648 ~(UAF_LOCKED | UAF_VALID);
654 uip->uip_arpsvratm.address_format = T_ATM_ABSENT;
655 uip->uip_arpsvratm.address_length = 0;
656 uip->uip_arpsvrsub.address_format = T_ATM_ABSENT;
657 uip->uip_arpsvrsub.address_length = 0;
658 uip->uip_arpsvrip.s_addr = 0;
663 * Save the arp server address, if supplied now
666 ATM_ADDR_COPY(aap, &uip->uip_arpsvratm);
669 * If the interface's ATM address isn't set yet, then we
670 * can't do much until it is
672 if ((uip->uip_flags & UIF_IFADDR) == 0) {
673 uip->uip_arpstate = UIAS_CLIENT_PADDR;
678 * Just to keep things simple, if we already have (or are trying to
679 * setup) any SVCs to our new server, kill the connections so we can
680 * open a "fresh" SVC for the arpserver connection.
682 for (i = 0; i < UNIARP_HASHSIZ; i++) {
683 for (uap = uniarp_arptab[i]; uap; uap = unext) {
684 unext = uap->ua_next;
686 if (ATM_ADDR_EQUAL(&uip->uip_arpsvratm,
688 ATM_ADDR_EQUAL(&uip->uip_arpsvrsub,
689 &uap->ua_dstatmsub)) {
690 uap->ua_flags &= ~UAF_VALID;
691 for (ivp = uap->ua_ivp; ivp; ivp = inext) {
692 inext = ivp->iv_arpnext;
693 (*inp->inf_arpnotify)(ivp, MAP_FAILED);
698 for (uap = uniarp_nomaptab; uap; uap = unext) {
699 unext = uap->ua_next;
701 if (ATM_ADDR_EQUAL(&uip->uip_arpsvratm, &uap->ua_dstatm) &&
702 ATM_ADDR_EQUAL(&uip->uip_arpsvrsub, &uap->ua_dstatmsub)) {
703 uap->ua_flags &= ~UAF_VALID;
704 for (ivp = uap->ua_ivp; ivp; ivp = inext) {
705 inext = ivp->iv_arpnext;
706 (*inp->inf_arpnotify)(ivp, MAP_FAILED);
712 * Now, get an arp entry for the server connection
713 * May be called from timeout - don't wait.
715 uip->uip_arpstate = UIAS_CLIENT_POPEN;
716 uap = uma_zalloc(uniarp_zone, M_NOWAIT | M_ZERO);
718 UNIIP_ARP_TIMER(uip, 1 * ATM_HZ);
723 * Next, initiate an SVC to the server
725 if ((*inp->inf_createsvc)(ANIF2IFP(inp->inf_nif), AF_ATM,
726 (caddr_t)&uip->uip_arpsvratm, &ivp)) {
727 uma_zfree(uniarp_zone, uap);
728 UNIIP_ARP_TIMER(uip, 1 * ATM_HZ);
733 * Finally, get everything set up and wait for the SVC
734 * connection to complete
736 uip->uip_arpsvrvcc = ivp;
737 ivp->iv_flags |= IVF_NOIDLE;
739 ATM_ADDR_COPY(&uip->uip_arpsvratm, &uap->ua_dstatm);
740 ATM_ADDR_COPY(&uip->uip_arpsvrsub, &uap->ua_dstatmsub);
743 LINK2TAIL(ivp, struct ipvcc, uap->ua_ivp, iv_arpnext);
744 ivp->iv_arpent = (struct arpmap *)uap;
746 LINK2TAIL(uap, struct uniarp, uniarp_nomaptab, ua_next);
753 * Process a UNI ARP interface timeout
755 * Called when a previously scheduled uniip arp interface timer expires.
756 * Processing will be based on the current uniip arp state.
761 * tip pointer to uniip arp timer control block
768 uniarp_iftimeout(tip)
769 struct atm_time *tip;
776 * Back-off to uniip control block
778 uip = (struct uniip *)
779 ((caddr_t)tip - (int)(&((struct uniip *)0)->uip_arptime));
781 ATM_DEBUG2("uniarp_iftimeout: uip=%p, state=%d\n", uip,
785 * Process timeout based on protocol state
787 switch (uip->uip_arpstate) {
789 case UIAS_CLIENT_POPEN:
791 * Retry opening arp server connection
793 uniarp_client_mode(uip, NULL);
796 case UIAS_CLIENT_REGISTER:
798 * Resend registration request
800 inp = uip->uip_ipnif;
801 (void) uniarp_arp_req(uip, &(IA_SIN(inp->inf_addr)->sin_addr));
806 UNIIP_ARP_TIMER(uip, 2 * ATM_HZ);
810 case UIAS_CLIENT_ACTIVE:
812 * Refresh our registration
814 inp = uip->uip_ipnif;
815 (void) uniarp_arp_req(uip, &(IA_SIN(inp->inf_addr)->sin_addr));
820 UNIIP_ARP_TIMER(uip, UNIARP_REGIS_RETRY);
825 log(LOG_ERR, "uniarp_iftimeout: invalid state %d\n",
832 * UNI ARP IOCTL support
834 * Function will be called at splnet.
837 * code PF_ATM sub-operation code
838 * data pointer to code specific parameter data area
839 * arg1 pointer to code specific argument
843 * errno error processing request - reason indicated
847 uniarp_ioctl(code, data, arg1)
852 struct atmaddreq *aap;
853 struct atmdelreq *adp;
854 struct atmsetreq *asp;
855 struct atminfreq *aip;
856 struct air_arp_rsp aar;
857 struct air_asrv_rsp asr;
860 struct ipvcc *ivp, *inext;
868 size_t buf_len, tlen;
876 * Add a permanent ARP mapping
878 aap = (struct atmaddreq *)data;
879 uip = (struct uniip *)arg1;
880 if (aap->aar_arp_addr.address_format != T_ATM_ENDSYS_ADDR) {
884 atmsub.address_format = T_ATM_ABSENT;
885 atmsub.address_length = 0;
886 ip = SATOSIN(&aap->aar_arp_dst)->sin_addr;
889 * Validate IP address
891 if (uniarp_validate_ip(uip, &ip, aap->aar_arp_origin) != 0) {
897 * Add an entry to the cache
899 err = uniarp_cache_svc(uip, &ip, &aap->aar_arp_addr,
900 &atmsub, aap->aar_arp_origin);
905 * Delete an ARP mapping
907 adp = (struct atmdelreq *)data;
908 uip = (struct uniip *)arg1;
909 ip = SATOSIN(&adp->adr_arp_dst)->sin_addr;
912 * Now find the entry to be deleted
914 UNIARP_LOOKUP(ip.s_addr, uap);
921 * Notify all VCCs using this entry that they must finish
924 uap->ua_flags |= UAF_LOCKED;
925 for (ivp = uap->ua_ivp; ivp; ivp = inext) {
926 inext = ivp->iv_arpnext;
927 (*ivp->iv_ipnif->inf_arpnotify)(ivp, MAP_FAILED);
931 * Now free up the entry
935 uma_zfree(uniarp_zone, uap);
940 * Set interface ARP server address
942 asp = (struct atmsetreq *)data;
943 for (uip = uniip_head; uip; uip = uip->uip_next) {
944 if (uip->uip_ipnif->inf_nif == (struct atm_nif *)arg1)
953 * Check for our own address
955 usp = (struct unisig *)
956 uip->uip_ipnif->inf_nif->nif_pif->pif_siginst;
957 if (ATM_ADDR_EQUAL(&asp->asr_arp_addr, &usp->us_addr)) {
958 asp->asr_arp_addr.address_format = T_ATM_ABSENT;
962 * If we're going into server mode, make sure we can get
963 * the memory for the prefix list before continuing
965 if (asp->asr_arp_addr.address_format == T_ATM_ABSENT) {
966 i = asp->asr_arp_plen / sizeof(struct uniarp_prf);
971 buf_len = i * sizeof(struct uniarp_prf);
972 buf_addr = malloc(buf_len, M_DEVBUF, M_NOWAIT);
973 if (buf_addr == NULL) {
977 err = copyin(asp->asr_arp_pbuf, buf_addr, buf_len);
979 free(buf_addr, M_DEVBUF);
983 /* Silence the compiler */
989 * Free any existing prefix address list
991 if (uip->uip_prefix != NULL) {
992 free(uip->uip_prefix, M_DEVBUF);
993 uip->uip_prefix = NULL;
994 uip->uip_nprefix = 0;
997 if (asp->asr_arp_addr.address_format == T_ATM_ABSENT) {
999 * Set ATMARP server mode
1001 uip->uip_prefix = (struct uniarp_prf *)buf_addr;
1002 uip->uip_nprefix = i;
1003 uniarp_server_mode(uip);
1006 * Set ATMARP client mode
1008 uniarp_client_mode(uip, &asp->asr_arp_addr);
1013 * Get ARP table information
1015 aip = (struct atminfreq *)data;
1017 if (aip->air_arp_addr.sa_family != AF_INET)
1019 dst = SATOSIN(&aip->air_arp_addr)->sin_addr.s_addr;
1021 buf_addr = aip->air_buf_addr;
1022 buf_len = aip->air_buf_len;
1024 pip = ((struct siginst *)arg1)->si_pif;
1027 * Run through entire arp table
1029 for (i = 0; i < UNIARP_HASHSIZ; i++) {
1030 for (uap = uniarp_arptab[i]; uap; uap = uap->ua_next) {
1032 * We only want valid entries learned
1033 * from the supplied interface.
1035 nip = uap->ua_intf->uip_ipnif->inf_nif;
1036 if (nip->nif_pif != pip)
1038 if ((dst != INADDR_ANY) &&
1039 (dst != uap->ua_dstip.s_addr))
1043 * Make sure there's room in the user's buffer
1045 if (buf_len < sizeof(aar)) {
1051 * Fill in info to be returned
1053 SATOSIN(&aar.aap_arp_addr)->sin_family =
1055 SATOSIN(&aar.aap_arp_addr)->sin_addr.s_addr =
1056 uap->ua_dstip.s_addr;
1057 strlcpy(aar.aap_intf, ANIF2IFP(nip)->if_xname,
1058 sizeof(aar.aap_intf));
1059 aar.aap_flags = uap->ua_flags;
1060 aar.aap_origin = uap->ua_origin;
1061 if (uap->ua_flags & UAF_VALID)
1062 aar.aap_age = uap->ua_aging +
1063 uap->ua_retry * UNIARP_RETRY_AGE;
1066 ATM_ADDR_COPY(&uap->ua_dstatm, &aar.aap_addr);
1067 ATM_ADDR_COPY(&uap->ua_dstatmsub,
1071 * Copy the response into the user's buffer
1073 if ((err = copyout((caddr_t)&aar, buf_addr,
1076 buf_addr += sizeof(aar);
1077 buf_len -= sizeof(aar);
1084 * Now go through the 'nomap' table
1086 if (err || (dst != INADDR_ANY))
1088 for (uap = uniarp_nomaptab; uap; uap = uap->ua_next) {
1090 * We only want valid entries learned
1091 * from the supplied interface.
1093 nip = uap->ua_intf->uip_ipnif->inf_nif;
1094 if (nip->nif_pif != pip)
1098 * Make sure there's room in the user's buffer
1100 if (buf_len < sizeof(aar)) {
1106 * Fill in info to be returned
1108 SATOSIN(&aar.aap_arp_addr)->sin_family = AF_INET;
1109 SATOSIN(&aar.aap_arp_addr)->sin_addr.s_addr = 0;
1110 strlcpy(aar.aap_intf, ANIF2IFP(nip)->if_xname,
1111 sizeof(aar.aap_intf));
1113 aar.aap_origin = uap->ua_origin;
1115 ATM_ADDR_COPY(&uap->ua_dstatm, &aar.aap_addr);
1116 ATM_ADDR_COPY(&uap->ua_dstatmsub,
1120 * Copy the response into the user's buffer
1122 if ((err = copyout((caddr_t)&aar, buf_addr,
1125 buf_addr += sizeof(aar);
1126 buf_len -= sizeof(aar);
1131 * Update the buffer pointer and length
1133 aip->air_buf_addr = buf_addr;
1134 aip->air_buf_len = buf_len;
1137 * If the user wants the refresh status reset and no
1138 * errors have been encountered, then do the reset
1140 if ((err == 0) && (aip->air_arp_flags & ARP_RESET_REF)) {
1141 for (i = 0; i < UNIARP_HASHSIZ; i++) {
1142 for (uap = uniarp_arptab[i]; uap;
1143 uap = uap->ua_next) {
1145 * We only want valid entries learned
1146 * from the supplied interface.
1148 nip = uap->ua_intf->uip_ipnif->inf_nif;
1149 if (nip->nif_pif != pip)
1151 if ((dst != INADDR_ANY) &&
1152 (dst != uap->ua_dstip.s_addr))
1156 * Reset refresh flag
1158 uap->ua_flags &= ~UAF_REFRESH;
1166 * Get ARP server information
1168 aip = (struct atminfreq *)data;
1169 nip = (struct atm_nif *)arg1;
1171 buf_addr = aip->air_buf_addr;
1172 buf_len = aip->air_buf_len;
1174 for (uip = uniip_head; uip; uip = uip->uip_next) {
1176 if (uip->uip_ipnif->inf_nif != nip)
1180 * Make sure there's room in the user's buffer
1182 if (buf_len < sizeof(asr)) {
1188 * Fill in info to be returned
1190 strlcpy(asr.asp_intf, ANIF2IFP(nip)->if_xname,
1191 sizeof(asr.asp_intf));
1192 asr.asp_state = uip->uip_arpstate;
1193 if (uip->uip_arpstate == UIAS_SERVER_ACTIVE) {
1194 asr.asp_addr.address_format = T_ATM_ABSENT;
1195 asr.asp_addr.address_length = 0;
1197 ATM_ADDR_COPY(&uip->uip_arpsvratm,
1200 asr.asp_subaddr.address_format = T_ATM_ABSENT;
1201 asr.asp_subaddr.address_length = 0;
1202 asr.asp_nprefix = uip->uip_nprefix;
1205 * Copy the response into the user's buffer
1207 if ((err = copyout((caddr_t)&asr, buf_addr, sizeof(asr))) != 0)
1209 buf_addr += sizeof(asr);
1210 buf_len -= sizeof(asr);
1213 * Copy the prefix list into the user's buffer
1215 if (uip->uip_nprefix) {
1216 tlen = uip->uip_nprefix *
1217 sizeof(struct uniarp_prf);
1218 if (buf_len < tlen) {
1222 err = copyout(uip->uip_prefix, buf_addr, tlen);
1231 * Update the buffer pointer and length
1233 aip->air_buf_addr = buf_addr;
1234 aip->air_buf_len = buf_len;
1246 * Get Connection's Application/Owner Name
1249 * tok uniarp connection token (pointer to ipvcc)
1252 * addr pointer to string containing our name