Rename sprintf -> ksprintf
[dfdiff.git] / sys / netproto / atm / uni / unisig_if.c
blob900aac66ce6f387a2cb4a4a83c10451cf89ffc44
1 /*
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/unisig_if.c,v 1.8 2000/01/17 20:49:56 mks Exp $
27 * @(#) $DragonFly: src/sys/netproto/atm/uni/unisig_if.c,v 1.9 2006/12/20 18:14:43 dillon Exp $
31 * ATM Forum UNI 3.0/3.1 Signalling Manager
32 * ----------------------------------------
34 * System interface module
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 "uniip_var.h"
44 #include "unisig.h"
45 #include "unisig_var.h"
46 #include "unisig_msg.h"
49 * Global variables
51 struct sp_info unisig_vcpool = {
52 "unisig vcc pool", /* si_name */
53 sizeof(struct unisig_vccb), /* si_blksiz */
54 10, /* si_blkcnt */
55 50 /* si_maxallow */
58 struct sp_info unisig_msgpool = {
59 "unisig message pool", /* si_name */
60 sizeof(struct unisig_msg), /* si_blksiz */
61 10, /* si_blkcnt */
62 50 /* si_maxallow */
65 struct sp_info unisig_iepool = {
66 "unisig ie pool", /* si_name */
67 sizeof(struct ie_generic), /* si_blksiz */
68 10, /* si_blkcnt */
69 50 /* si_maxallow */
74 * Local functions
76 static int unisig_attach (struct sigmgr *, struct atm_pif *);
77 static int unisig_detach (struct atm_pif *);
78 static int unisig_setup (Atm_connvc *, int *);
79 static int unisig_release (struct vccb *, int *);
80 static int unisig_accept (struct vccb *, int *);
81 static int unisig_reject (struct vccb *, int *);
82 static int unisig_abort (struct vccb *);
83 static int unisig_ioctl (int, caddr_t, caddr_t);
87 * Local variables
89 static struct sigmgr unisig_mgr30 = {
90 NULL,
91 ATM_SIG_UNI30,
92 NULL,
93 unisig_attach,
94 unisig_detach,
95 unisig_setup,
96 unisig_accept,
97 unisig_reject,
98 unisig_release,
99 unisig_free,
100 unisig_ioctl
103 static struct sigmgr unisig_mgr31 = {
104 NULL,
105 ATM_SIG_UNI31,
106 NULL,
107 unisig_attach,
108 unisig_detach,
109 unisig_setup,
110 unisig_accept,
111 unisig_reject,
112 unisig_release,
113 unisig_free,
114 unisig_ioctl
119 * Initialize UNISIG processing
121 * This will be called during module loading. We'll just register
122 * the UNISIG protocol descriptor and wait for a UNISIG ATM interface
123 * to come online.
125 * Arguments:
126 * none
128 * Returns:
129 * 0 startup was successful
130 * errno startup failed - reason indicated
134 unisig_start(void)
136 int err = 0;
139 * Verify software version
141 if (atm_version != ATM_VERSION) {
142 log(LOG_ERR, "version mismatch: unisig=%d.%d kernel=%d.%d\n",
143 ATM_VERS_MAJ(ATM_VERSION),
144 ATM_VERS_MIN(ATM_VERSION),
145 ATM_VERS_MAJ(atm_version),
146 ATM_VERS_MIN(atm_version));
147 return (EINVAL);
151 * Register ourselves with system
153 err = atm_sigmgr_register(&unisig_mgr30);
154 if (err)
155 goto done;
157 err = atm_sigmgr_register(&unisig_mgr31);
159 done:
160 return (err);
165 * Halt UNISIG processing
167 * This should be called just prior to unloading the module from
168 * memory. All UNISIG interfaces must be deregistered before the
169 * protocol can be shutdown.
171 * Arguments:
172 * none
174 * Returns:
175 * 0 startup was successful
176 * errno startup failed - reason indicated
180 unisig_stop(void)
182 int err = 0;
184 crit_enter();
187 * Any protocol instances still registered?
189 if ((unisig_mgr30.sm_prinst != NULL) ||
190 (unisig_mgr31.sm_prinst != NULL)) {
192 /* Yes, can't stop now */
193 err = EBUSY;
194 goto done;
198 * De-register from system
200 atm_sigmgr_deregister(&unisig_mgr30);
201 atm_sigmgr_deregister(&unisig_mgr31);
204 * Free up our storage pools
206 atm_release_pool(&unisig_vcpool);
207 atm_release_pool(&unisig_msgpool);
208 atm_release_pool(&unisig_iepool);
210 done:
211 crit_exit();
212 return (err);
217 * Attach a UNISIG-controlled interface
219 * Each ATM physical interface must be attached with the signalling
220 * manager for the interface's signalling protocol (via the
221 * atm_sigmgr_attach function). This function will handle the
222 * attachment for UNISIG-controlled interfaces. A new UNISIG protocol
223 * instance will be created and then we'll just sit around waiting for
224 * status or connection requests.
226 * Function must be called from a critical section.
228 * Arguments:
229 * smp pointer to UNISIG signalling manager control block
230 * pip pointer to ATM physical interface control block
232 * Returns:
233 * 0 attach successful
234 * errno attach failed - reason indicated
237 static int
238 unisig_attach(struct sigmgr *smp, struct atm_pif *pip)
240 int err = 0;
241 struct unisig *usp = NULL;
243 ATM_DEBUG2("unisig_attach: smp=%p, pip=%p\n", smp, pip);
246 * Allocate UNISIG protocol instance control block
248 usp = KM_ALLOC(sizeof(struct unisig), M_DEVBUF, M_INTWAIT | M_NULLOK);
249 if (usp == NULL) {
250 err = ENOMEM;
251 goto done;
253 KM_ZERO(usp, sizeof(struct unisig));
256 * Set state in UNISIG protocol instance control block
258 usp->us_state = UNISIG_NULL;
259 usp->us_proto = smp->sm_proto;
262 * Set initial call reference allocation value
264 usp->us_cref = 1;
267 * Link instance into manager's chain
269 LINK2TAIL((struct siginst *)usp, struct siginst, smp->sm_prinst,
270 si_next);
273 * Link in interface
275 usp->us_pif = pip;
276 crit_enter();
277 pip->pif_sigmgr = smp;
278 pip->pif_siginst = (struct siginst *) usp;
279 crit_exit();
282 * Clear our ATM address. The address will be set by user
283 * command or by registration via ILMI.
285 usp->us_addr.address_format = T_ATM_ABSENT;
286 usp->us_addr.address_length = 0;
287 usp->us_subaddr.address_format = T_ATM_ABSENT;
288 usp->us_subaddr.address_length = 0;
291 * Set pointer to IP
293 usp->us_ipserv = &uniip_ipserv;
296 * Kick-start the UNISIG protocol
298 UNISIG_TIMER(usp, 0);
301 * Log the fact that we've attached
303 log(LOG_INFO, "unisig: attached to interface %s%d\n",
304 pip->pif_name, pip->pif_unit);
306 done:
308 * Reset our work if attach fails
310 if (err) {
311 if (usp) {
312 UNISIG_CANCEL(usp);
313 UNLINK((struct siginst *)usp, struct siginst,
314 smp->sm_prinst, si_next);
315 KM_FREE(usp, sizeof(struct unisig), M_DEVBUF);
317 crit_enter();
318 pip->pif_sigmgr = NULL;
319 pip->pif_siginst = NULL;
320 crit_exit();
323 return (err);
328 * Detach a UNISIG-controlled interface
330 * Each ATM physical interface may be detached from its signalling
331 * manager (via the atm_sigmgr_detach function). This function will
332 * handle the detachment for all UNISIG-controlled interfaces. All
333 * circuits will be immediately terminated.
335 * Function must be called from a critical section.
337 * Arguments:
338 * pip pointer to ATM physical interface control block
340 * Returns:
341 * 0 detach successful
342 * errno detach failed - reason indicated
345 static int
346 unisig_detach(struct atm_pif *pip)
348 struct unisig *usp;
349 int err;
351 ATM_DEBUG1("unisig_detach: pip=%p\n", pip);
354 * Get UNISIG protocol instance
356 usp = (struct unisig *)pip->pif_siginst;
359 * Return an error if we're already detaching
361 if (usp->us_state == UNISIG_DETACH) {
362 return(EALREADY);
366 * Pass the detach event to the signalling manager
367 * state machine
369 err = unisig_sigmgr_state(usp, UNISIG_SIGMGR_DETACH,
370 (KBuffer *)0);
373 * Log the fact that we've detached
375 if (!err)
376 log(LOG_INFO, "unisig: detached from interface %s%d\n",
377 pip->pif_name, pip->pif_unit);
379 return (0);
384 * Open a UNISIG ATM Connection
386 * All service user requests to open a VC connection (via
387 * atm_open_connection) over an ATM interface attached to the UNISIG
388 * signalling manager are handled here.
390 * Function will be called from a critical section.
392 * Arguments:
393 * cvp pointer to user's requested connection parameters
394 * errp pointer to an int for extended error information
396 * Returns:
397 * CALL_PROCEEDING connection establishment is in progress
398 * CALL_FAILED connection establishment failed
399 * CALL_CONNECTED connection has been successfully established
402 static int
403 unisig_setup(Atm_connvc *cvp, int *errp)
405 struct atm_pif *pip = cvp->cvc_attr.nif->nif_pif;
406 struct unisig *usp = (struct unisig *)pip->pif_siginst;
407 int rc = 0;
409 ATM_DEBUG1("unisig_setup: cvp=%p\n", cvp);
412 * Intialize the returned error code
414 *errp = 0;
417 * Open the connection
419 switch (cvp->cvc_attr.called.addr.address_format) {
420 case T_ATM_PVC_ADDR:
422 * Create a PVC
424 *errp = unisig_open_vcc(usp, cvp);
425 rc = (*errp ? CALL_FAILED : CALL_CONNECTED);
426 break;
428 case T_ATM_ENDSYS_ADDR:
429 case T_ATM_E164_ADDR:
432 * Create an SVC
434 *errp = unisig_open_vcc(usp, cvp);
435 rc = (*errp ? CALL_FAILED : CALL_PROCEEDING);
436 break;
438 default:
439 *errp = EPROTONOSUPPORT;
440 rc = CALL_FAILED;
443 return (rc);
448 * Close a UNISIG ATM Connection
450 * All service user requests to terminate a previously open VC
451 * connection (via the atm_close_connection function), which is running
452 * over an interface attached to the UNISIG signalling manager, are
453 * handled here.
455 * Function will be called from a critical section.
457 * Arguments:
458 * vcp pointer to connection's VC control block
459 * errp pointer to an int for extended error information
461 * Returns:
462 * CALL_PROCEEDING connection termination is in progress
463 * CALL_FAILED connection termination failed
464 * CALL_CLEARED connection has been successfully terminated
467 static int
468 unisig_release(struct vccb *vcp, int *errp)
470 int rc = 0;
471 struct atm_pif *pip = vcp->vc_pif;
472 struct unisig *usp = (struct unisig *)pip->pif_siginst;
474 ATM_DEBUG1("unisig_release: vcp=%p\n", vcp);
477 * Initialize returned error code
479 *errp = 0;
482 * Validate the connection type (PVC or SVC)
484 if (!(vcp->vc_type & (VCC_PVC | VCC_SVC))) {
485 *errp = EPROTONOSUPPORT;
486 return(CALL_FAILED);
490 * Close the VCCB
492 *errp = unisig_close_vcc(usp, (struct unisig_vccb *)vcp);
495 * Set the return code
497 if (*errp) {
498 rc = CALL_FAILED;
499 } else if (vcp->vc_sstate == UNI_NULL ||
500 vcp->vc_sstate == UNI_FREE) {
501 rc = CALL_CLEARED;
502 } else {
503 rc = CALL_PROCEEDING;
506 return (rc);
511 * Accept a UNISIG Open from a remote host
513 * A user calls this routine (via the atm_accept_call function)
514 * after it is notified that an open request was received for it.
516 * Function will be called from a critical section.
518 * Arguments:
519 * vcp pointer to user's VCCB
520 * errp pointer to an int for extended error information
522 * Returns:
523 * CALL_PROCEEDING connection establishment is in progress
524 * CALL_FAILED connection establishment failed
525 * CALL_CONNECTED connection has been successfully established
528 static int
529 unisig_accept(struct vccb *vcp, int *errp)
531 struct unisig_vccb *uvp = (struct unisig_vccb *)vcp;
532 struct atm_pif *pip = uvp->uv_pif;
533 struct unisig *usp = (struct unisig *)pip->pif_siginst;
535 ATM_DEBUG1("unisig_accept: vcp=%p\n", vcp);
538 * Initialize the returned error code
540 *errp = 0;
543 * Return an error if we're detaching
545 if (usp->us_state == UNISIG_DETACH) {
546 *errp = ENETDOWN;
547 goto free;
551 * Return an error if we lost the connection
553 if (uvp->uv_sstate == UNI_FREE) {
554 *errp = ENETDOWN;
555 goto free;
559 * Pass the acceptance to the VC state machine
561 *errp = unisig_vc_state(usp, uvp, UNI_VC_ACCEPT_CALL,
562 (struct unisig_msg *) 0);
563 if (*errp)
564 goto failed;
566 return(CALL_PROCEEDING);
568 failed:
570 * On error, free the VCCB and return CALL_FAILED
573 free:
574 uvp->uv_sstate = UNI_FREE;
575 uvp->uv_ustate = VCCU_CLOSED;
576 DEQUEUE(uvp, struct unisig_vccb, uv_sigelem, usp->us_vccq);
577 unisig_free((struct vccb *)uvp);
579 return(CALL_FAILED);
584 * Reject a UNISIG Open from a remote host
586 * A user calls this routine (via the atm_reject_call function)
587 * after it is notified that an open request was received for it.
589 * Function will be called from a critical section.
591 * Arguments:
592 * uvp pointer to user's VCCB
593 * errp pointer to an int for extended error information
595 * Returns:
596 * CALL_CLEARED call request rejected
597 * CALL_FAILED call rejection failed
600 static int
601 unisig_reject(struct vccb *vcp, int *errp)
603 struct unisig_vccb *uvp = (struct unisig_vccb *)vcp;
604 struct atm_pif *pip = uvp->uv_pif;
605 struct unisig *usp = (struct unisig *)pip->pif_siginst;
607 ATM_DEBUG1("unisig_reject: uvp=%p\n", uvp);
610 * Initialize the returned error code
612 *errp = 0;
616 * Return an error if we're detaching
618 if (usp->us_state == UNISIG_DETACH) {
619 *errp = ENETDOWN;
620 goto failed;
624 * Call the VC state machine
626 *errp = unisig_vc_state(usp, uvp, UNI_VC_REJECT_CALL,
627 (struct unisig_msg *) 0);
628 if (*errp)
629 goto failed;
631 return(CALL_CLEARED);
633 failed:
635 * On error, free the VCCB and return CALL_FAILED
637 uvp->uv_sstate = UNI_FREE;
638 uvp->uv_ustate = VCCU_CLOSED;
639 DEQUEUE(uvp, struct unisig_vccb, uv_sigelem, usp->us_vccq);
640 unisig_free((struct vccb *)uvp);
641 return(CALL_FAILED);
646 * Abort a UNISIG ATM Connection
648 * All (non-user) requests to abort a previously open VC connection (via
649 * the atm_abort_connection function), which is running over an
650 * interface attached to the UNISIG signalling manager, are handled here.
651 * The VCC owner will be notified of the request, in order to initiate
652 * termination of the connection.
654 * Function will be called from a critical section.
656 * Arguments:
657 * vcp pointer to connection's VC control block
659 * Returns:
660 * 0 connection release was successful
661 * errno connection release failed - reason indicated
664 static int
665 unisig_abort(struct vccb *vcp)
668 ATM_DEBUG1("unisig_abort: vcp=%p\n", vcp);
671 * Only abort once
673 if (vcp->vc_ustate == VCCU_ABORT) {
674 return (EALREADY);
678 * Cancel any timer that might be running
680 UNISIG_VC_CANCEL(vcp);
683 * Set immediate timer to schedule connection termination
685 vcp->vc_ustate = VCCU_ABORT;
686 UNISIG_VC_TIMER(vcp, 0);
688 return (0);
693 * Free UNISIG ATM connection resources
695 * All service user requests to free the resources of a closed VCC
696 * connection (via the atm_free_connection function), which is running
697 * over an interface attached to the UNISIG signalling manager, are
698 *handled here.
700 * Function will be called from a critical section.
702 * Arguments:
703 * vcp pointer to connection's VC control block
705 * Returns:
706 * 0 connection free was successful
707 * errno connection free failed - reason indicated
711 unisig_free(struct vccb *vcp)
713 struct atm_pif *pip = vcp->vc_pif;
714 struct unisig *usp = (struct unisig *)pip->pif_siginst;
716 ATM_DEBUG1("unisig_free: vcp = %p\n", vcp);
719 * Make sure VCC has been closed
721 if ((vcp->vc_ustate != VCCU_CLOSED &&
722 vcp->vc_ustate != VCCU_ABORT) ||
723 vcp->vc_sstate != UNI_FREE) {
724 ATM_DEBUG2("unisig_free: bad state, sstate=%d, ustate=%d\n",
725 vcp->vc_sstate, vcp->vc_ustate);
726 return(EEXIST);
730 * Remove VCCB from protocol queue
732 DEQUEUE(vcp, struct vccb, vc_sigelem, usp->us_vccq);
735 * Free VCCB storage
737 vcp->vc_ustate = VCCU_NULL;
738 vcp->vc_sstate = UNI_NULL;
739 atm_free((caddr_t)vcp);
742 * If we're detaching and this was the last VCC queued,
743 * get rid of the protocol instance
745 if ((usp->us_state == UNISIG_DETACH) &&
746 (Q_HEAD(usp->us_vccq, struct vccb) == NULL)) {
747 struct sigmgr *smp = pip->pif_sigmgr;
749 crit_enter();
750 pip->pif_sigmgr = NULL;
751 pip->pif_siginst = NULL;
752 crit_exit();
754 UNLINK((struct siginst *)usp, struct siginst,
755 smp->sm_prinst, si_next);
756 KM_FREE(usp, sizeof(struct unisig), M_DEVBUF);
759 return (0);
764 * UNISIG IOCTL support
766 * Function will be called from a critical section.
768 * Arguments:
769 * code PF_ATM sub-operation code
770 * data pointer to code specific parameter data area
771 * arg1 pointer to code specific argument
773 * Returns:
774 * 0 request procesed
775 * errno error processing request - reason indicated
778 static int
779 unisig_ioctl(int code, caddr_t data, caddr_t arg1)
781 struct atmdelreq *adp;
782 struct atminfreq *aip;
783 struct atmsetreq *asp;
784 struct unisig *usp;
785 struct unisig_vccb *uvp;
786 struct air_vcc_rsp rsp;
787 struct atm_pif *pip;
788 Atm_connection *cop;
789 u_int vpi, vci;
790 int err = 0, buf_len, i;
791 caddr_t buf_addr;
793 ATM_DEBUG1("unisig_ioctl: code=%d\n", code);
795 switch (code) {
797 case AIOCS_DEL_PVC:
798 case AIOCS_DEL_SVC:
800 * Delete a VCC
802 adp = (struct atmdelreq *)data;
803 usp = (struct unisig *)arg1;
806 * Don't let a user close the UNISIG signalling VC
808 vpi = adp->adr_pvc_vpi;
809 vci = adp->adr_pvc_vci;
810 if ((vpi == UNISIG_SIG_VPI && vci == UNISIG_SIG_VCI))
811 return(EINVAL);
814 * Find requested VCC
816 for (uvp = Q_HEAD(usp->us_vccq, struct unisig_vccb); uvp;
817 uvp = Q_NEXT(uvp, struct unisig_vccb, uv_sigelem)) {
818 if ((uvp->uv_vpi == vpi) && (uvp->uv_vci == vci))
819 break;
821 if (uvp == NULL)
822 return (ENOENT);
825 * Check VCC type
827 switch (code) {
828 case AIOCS_DEL_PVC:
829 if (!(uvp->uv_type & VCC_PVC)) {
830 return(EINVAL);
832 break;
833 case AIOCS_DEL_SVC:
834 if (!(uvp->uv_type & VCC_SVC)) {
835 return(EINVAL);
837 break;
841 * Schedule VCC termination
843 unisig_cause_attr_from_user(&uvp->uv_connvc->cvc_attr,
844 T_ATM_CAUSE_UNSPECIFIED_NORMAL);
845 err = unisig_abort((struct vccb *)uvp);
846 break;
848 case AIOCS_INF_VCC:
850 * Return VCC information
852 aip = (struct atminfreq *)data;
853 usp = (struct unisig *)arg1;
855 buf_addr = aip->air_buf_addr;
856 buf_len = aip->air_buf_len;
859 * Loop through the VCC queue
861 for (uvp = Q_HEAD(usp->us_vccq, struct unisig_vccb); uvp;
862 uvp = Q_NEXT(uvp, struct unisig_vccb, uv_sigelem)) {
864 * Make sure there's room in the user's buffer
866 if (buf_len < sizeof(rsp)) {
867 err = ENOSPC;
868 break;
872 * Fill out the response struct for the VCC
874 ksnprintf(rsp.avp_intf,
875 sizeof(rsp.avp_intf), "%s%d",
876 usp->us_pif->pif_name,
877 usp->us_pif->pif_unit);
878 rsp.avp_vpi = uvp->uv_vpi;
879 rsp.avp_vci = uvp->uv_vci;
880 rsp.avp_type = uvp->uv_type;
881 rsp.avp_aal = uvp->uv_connvc->cvc_attr.aal.type;
882 rsp.avp_sig_proto = uvp->uv_proto;
883 cop = uvp->uv_connvc->cvc_conn;
884 if (cop)
885 rsp.avp_encaps = cop->co_mpx;
886 else
887 rsp.avp_encaps = 0;
888 rsp.avp_state = uvp->uv_sstate;
889 if (uvp->uv_connvc->cvc_flags & CVCF_CALLER) {
890 rsp.avp_daddr = uvp->uv_connvc->cvc_attr.called.addr;
891 } else {
892 rsp.avp_daddr = uvp->uv_connvc->cvc_attr.calling.addr;
894 rsp.avp_dsubaddr.address_format = T_ATM_ABSENT;
895 rsp.avp_dsubaddr.address_length = 0;
896 rsp.avp_ipdus = uvp->uv_ipdus;
897 rsp.avp_opdus = uvp->uv_opdus;
898 rsp.avp_ibytes = uvp->uv_ibytes;
899 rsp.avp_obytes = uvp->uv_obytes;
900 rsp.avp_ierrors = uvp->uv_ierrors;
901 rsp.avp_oerrors = uvp->uv_oerrors;
902 rsp.avp_tstamp = uvp->uv_tstamp;
903 KM_ZERO(rsp.avp_owners,
904 sizeof(rsp.avp_owners));
905 for (i = 0; cop && i < sizeof(rsp.avp_owners);
906 cop = cop->co_next,
907 i += T_ATM_APP_NAME_LEN+1) {
908 strncpy(&rsp.avp_owners[i],
909 cop->co_endpt->ep_getname(cop->co_toku),
910 T_ATM_APP_NAME_LEN);
914 * Copy the response into the user's buffer
916 if ((err = copyout((caddr_t)&rsp, buf_addr,
917 sizeof(rsp))) != 0)
918 break;
919 buf_addr += sizeof(rsp);
920 buf_len -= sizeof(rsp);
924 * Update the buffer pointer and length
926 aip->air_buf_addr = buf_addr;
927 aip->air_buf_len = buf_len;
928 break;
930 case AIOCS_INF_ARP:
931 case AIOCS_INF_ASV:
932 case AIOCS_SET_ASV:
934 * Get ARP table information or get/set ARP server address
936 err = uniarp_ioctl(code, data, arg1);
937 break;
939 case AIOCS_SET_PRF:
941 * Set NSAP prefix
943 asp = (struct atmsetreq *)data;
944 usp = (struct unisig *)arg1;
945 pip = usp->us_pif;
946 if (usp->us_addr.address_format != T_ATM_ABSENT) {
947 if (KM_CMP(asp->asr_prf_pref, usp->us_addr.address,
948 sizeof(asp->asr_prf_pref)) != 0)
949 err = EALREADY;
950 break;
952 usp->us_addr.address_format = T_ATM_ENDSYS_ADDR;
953 usp->us_addr.address_length = sizeof(Atm_addr_nsap);
954 KM_COPY(&pip->pif_macaddr,
955 ((Atm_addr_nsap *)usp->us_addr.address)->aan_esi,
956 sizeof(pip->pif_macaddr));
957 KM_COPY((caddr_t) asp->asr_prf_pref,
958 &((Atm_addr_nsap *)usp->us_addr.address)->aan_afi,
959 sizeof(asp->asr_prf_pref));
960 log(LOG_INFO, "uni: set address %s on interface %s\n",
961 unisig_addr_print(&usp->us_addr),
962 asp->asr_prf_intf);
965 * Pass event to signalling manager state machine
967 err = unisig_sigmgr_state(usp, UNISIG_SIGMGR_ADDR_SET,
968 (KBuffer *) NULL);
971 * Clean up if there was an error
973 if (err) {
974 usp->us_addr.address_format = T_ATM_ABSENT;
975 usp->us_addr.address_length = 0;
976 break;
980 * Inform ARP code of new address
982 uniarp_ifaddr((struct siginst *)usp);
983 break;
985 default:
986 err = EOPNOTSUPP;
989 return (err);