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
)