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/atm_usrreq.c,v 1.6 1999/08/28 00:48:39 peter Exp $
27 * @(#) $DragonFly: src/sys/netproto/atm/atm_usrreq.c,v 1.13 2007/04/21 02:26:48 dillon Exp $
34 * ATM DGRAM socket protocol processing
38 #include "kern_include.h"
43 static int atm_dgram_attach (struct socket
*, int,
44 struct pru_attach_info
*);
45 static int atm_dgram_control (struct socket
*, u_long
, caddr_t
,
46 struct ifnet
*, struct thread
*);
47 static int atm_dgram_info (caddr_t
);
50 * New-style socket request routines
52 struct pr_usrreqs atm_dgram_usrreqs
= {
53 .pru_abort
= atm_proto_notsupp1
,
54 .pru_accept
= pru_accept_notsupp
,
55 .pru_attach
= atm_dgram_attach
,
56 .pru_bind
= atm_proto_notsupp2
,
57 .pru_connect
= pru_connect_notsupp
,
58 .pru_connect2
= pru_connect2_notsupp
,
59 .pru_control
= atm_dgram_control
,
60 .pru_detach
= atm_proto_notsupp1
,
61 .pru_disconnect
= atm_proto_notsupp1
,
62 .pru_listen
= pru_listen_notsupp
,
63 .pru_peeraddr
= atm_proto_notsupp3
,
64 .pru_rcvd
= pru_rcvd_notsupp
,
65 .pru_rcvoob
= pru_rcvoob_notsupp
,
66 .pru_send
= atm_proto_notsupp4
,
67 .pru_sense
= pru_sense_null
,
68 .pru_shutdown
= atm_proto_notsupp1
,
69 .pru_sockaddr
= atm_proto_notsupp3
,
71 .pru_soreceive
= soreceive
,
76 * Handy common code macros
83 * Stack queue should have been drained \
85 if (atm_stackq_head != NULL) \
86 panic("atm_usrreq: stack queue not empty"); \
97 * Drain any deferred calls \
104 #define ATM_RETERR(errno) { \
111 * Attach protocol to socket
114 * so pointer to socket
115 * proto protocol identifier
116 * p pointer to process
119 * 0 request processed
120 * errno error processing request - reason indicated
124 atm_dgram_attach(struct socket
*so
, int proto
, struct pru_attach_info
*ai
)
129 * Nothing to do here for ioctl()-only sockets
136 * Process ioctl system calls
139 * so pointer to socket
141 * data pointer to code specific parameter data area
142 * ifp pointer to ifnet structure if it's an interface ioctl
143 * p pointer to process
146 * 0 request processed
147 * errno error processing request - reason indicated
151 atm_dgram_control(struct socket
*so
, u_long cmd
, caddr_t data
,
152 struct ifnet
*ifp
, struct thread
*td
)
157 * First, figure out which ioctl we're dealing with and
158 * then process it based on the sub-op code
163 struct atmcfgreq
*acp
= (struct atmcfgreq
*)data
;
166 if (priv_check(td
, PRIV_ROOT
))
169 switch (acp
->acr_opcode
) {
173 * Attach signalling manager
175 if ((pip
= atm_pifname(acp
->acr_att_intf
)) == NULL
)
177 err
= atm_sigmgr_attach(pip
, acp
->acr_att_proto
);
182 * Detach signalling manager
184 if ((pip
= atm_pifname(acp
->acr_det_intf
)) == NULL
)
186 err
= atm_sigmgr_detach(pip
);
196 struct atmaddreq
*aap
= (struct atmaddreq
*)data
;
199 if (priv_check(td
, PRIV_ROOT
))
202 switch (aap
->aar_opcode
) {
206 * Add a PVC definition
210 * Locate requested endpoint service
212 epp
= aap
->aar_pvc_sap
> ENDPT_MAX
? NULL
:
213 atm_endpoints
[aap
->aar_pvc_sap
];
215 ATM_RETERR(ENOPROTOOPT
);
218 * Let endpoint service handle it from here
220 err
= (*epp
->ep_ioctl
)(AIOCS_ADD_PVC
, data
, NULL
);
227 epp
= atm_endpoints
[ENDPT_IP
];
229 ATM_RETERR(ENOPROTOOPT
);
232 * Let IP/ATM endpoint handle this
234 err
= (*epp
->ep_ioctl
) (AIOCS_ADD_ARP
, data
, NULL
);
244 struct atmdelreq
*adp
= (struct atmdelreq
*)data
;
249 if (priv_check(td
, PRIV_ROOT
))
252 switch (adp
->adr_opcode
) {
257 * Delete a PVC or SVC
261 * Locate appropriate sigmgr
263 if ((pip
= atm_pifname(adp
->adr_pvc_intf
)) == NULL
)
265 if ((smp
= pip
->pif_sigmgr
) == NULL
)
269 * Let sigmgr handle it from here
271 err
= (*smp
->sm_ioctl
)(adp
->adr_opcode
, data
,
272 (caddr_t
)pip
->pif_siginst
);
277 * Delete an ARP mapping
279 epp
= atm_endpoints
[ENDPT_IP
];
281 ATM_RETERR(ENOPROTOOPT
);
284 * Let IP/ATM endpoint handle this
286 err
= (*epp
->ep_ioctl
) (AIOCS_DEL_ARP
, data
, NULL
);
296 struct atmsetreq
*asp
= (struct atmsetreq
*)data
;
302 if (priv_check(td
, PRIV_ROOT
))
305 switch (asp
->asr_opcode
) {
309 * Set an ARP server address
313 * Locate appropriate sigmgr
315 if ((nip
= atm_nifname(asp
->asr_arp_intf
)) == NULL
)
318 if ((smp
= pip
->pif_sigmgr
) == NULL
)
322 * Let sigmgr handle it from here
324 err
= (*smp
->sm_ioctl
)(AIOCS_SET_ASV
, data
,
330 * Set physical interface MAC/ESI address
334 * Locate physical interface
336 if ((pip
= atm_pifname(asp
->asr_mac_intf
)) == NULL
)
340 * Interface must be detached
342 if (pip
->pif_sigmgr
!= NULL
)
343 ATM_RETERR(EADDRINUSE
);
346 * Just plunk the address into the pif
348 KM_COPY((caddr_t
)&asp
->asr_mac_addr
,
349 (caddr_t
)&pip
->pif_macaddr
,
350 sizeof(struct mac_addr
));
355 * Define network interfaces
357 if ((pip
= atm_pifname(asp
->asr_nif_intf
)) == NULL
)
361 * Validate interface count - logical interfaces
362 * are differentiated by the atm address selector.
364 if ((asp
->asr_nif_cnt
<= 0) || (asp
->asr_nif_cnt
> 256))
368 * Make sure prefix name is unique
370 TAILQ_FOREACH(ifp2
, &ifnet
, if_link
) {
371 if (!strcmp(ifp2
->if_dname
, asp
->asr_nif_pref
)) {
373 * If this is for the interface we're
374 * (re-)defining, let it through
376 for (nip
= pip
->pif_nif
; nip
;
377 nip
= nip
->nif_pnext
) {
378 if (&nip
->nif_if
== ifp2
)
388 * Let interface handle it from here
390 err
= (*pip
->pif_ioctl
)(AIOCS_SET_NIF
, data
,
396 * Set interface NSAP Prefix
400 * Locate appropriate sigmgr
402 if ((pip
= atm_pifname(asp
->asr_prf_intf
)) == NULL
)
404 if ((smp
= pip
->pif_sigmgr
) == NULL
)
408 * Let sigmgr handle it from here
410 err
= (*smp
->sm_ioctl
)(AIOCS_SET_PRF
, data
,
411 (caddr_t
)pip
->pif_siginst
);
421 err
= atm_dgram_info(data
);
434 * Process AIOCINFO ioctl system calls
436 * Called from a critical section.
439 * data pointer to AIOCINFO parameter structure
442 * 0 request processed
443 * errno error processing request - reason indicated
447 atm_dgram_info(caddr_t data
)
449 struct atminfreq
*aip
= (struct atminfreq
*)data
;
454 int len
= aip
->air_buf_len
;
457 switch (aip
->air_opcode
) {
462 * Get vendor interface information
464 if (aip
->air_vinfo_intf
[0] != '\0') {
466 * Interface specified
468 if ((pip
= atm_pifname(aip
->air_vinfo_intf
))) {
469 err
= (*pip
->pif_ioctl
)(aip
->air_opcode
, data
,
476 * Want info for every interface
478 for (pip
= atm_interface_head
; pip
;
479 pip
= pip
->pif_next
) {
480 err
= (*pip
->pif_ioctl
)(aip
->air_opcode
, data
,
490 * Get IP Map information
492 epp
= atm_endpoints
[ENDPT_IP
];
494 err
= (*epp
->ep_ioctl
) (AIOCS_INF_IPM
, data
, NULL
);
502 * Get ARP table information
504 for (pip
= atm_interface_head
; pip
; pip
= pip
->pif_next
) {
505 if ((smp
= pip
->pif_sigmgr
) != NULL
) {
506 err
= (*smp
->sm_ioctl
)(AIOCS_INF_ARP
,
507 data
, (caddr_t
)pip
->pif_siginst
);
516 * Get ARP server information
518 if (aip
->air_asrv_intf
[0] != '\0') {
520 * Interface specified
522 if ((nip
= atm_nifname(aip
->air_asrv_intf
))) {
523 if ((smp
= nip
->nif_pif
->pif_sigmgr
) != NULL
) {
524 err
= (*smp
->sm_ioctl
)(AIOCS_INF_ASV
,
532 * Want info for all arp servers
534 for (pip
= atm_interface_head
; pip
;
535 pip
= pip
->pif_next
) {
536 if ((smp
= pip
->pif_sigmgr
) != NULL
) {
537 for (nip
= pip
->pif_nif
; nip
;
538 nip
= nip
->nif_pnext
) {
539 err
= (*smp
->sm_ioctl
)
540 (AIOCS_INF_ASV
, data
,
554 * Get physical interface info
556 if (aip
->air_int_intf
[0] != '\0') {
558 * Interface specified
560 if ((pip
= atm_pifname(aip
->air_int_intf
))) {
561 err
= (*pip
->pif_ioctl
)(AIOCS_INF_INT
,
568 * Want info for every physical interface
570 for (pip
= atm_interface_head
; pip
;
571 pip
= pip
->pif_next
) {
572 err
= (*pip
->pif_ioctl
)(AIOCS_INF_INT
,
582 * Get VCC information
584 if (aip
->air_vcc_intf
[0] != '\0') {
586 * Interface specified
588 if ((pip
= atm_pifname(aip
->air_vcc_intf
))) {
589 if ((smp
= pip
->pif_sigmgr
) != NULL
) {
590 err
= (*smp
->sm_ioctl
)(AIOCS_INF_VCC
,
592 (caddr_t
)pip
->pif_siginst
);
599 * Want info for every interface
601 for (pip
= atm_interface_head
; pip
;
602 pip
= pip
->pif_next
) {
603 if ((smp
= pip
->pif_sigmgr
) != NULL
) {
604 err
= (*smp
->sm_ioctl
)(AIOCS_INF_VCC
,
606 (caddr_t
)pip
->pif_siginst
);
616 * Get network interface info
618 if (aip
->air_int_intf
[0] != '\0') {
620 * Interface specified
622 if ((nip
= atm_nifname(aip
->air_int_intf
))) {
624 err
= (*pip
->pif_ioctl
)(AIOCS_INF_NIF
,
631 * Want info for every network interface
633 for (pip
= atm_interface_head
; pip
;
634 pip
= pip
->pif_next
) {
635 for (nip
= pip
->pif_nif
; nip
;
636 nip
= nip
->nif_pnext
) {
637 err
= (*pip
->pif_ioctl
)(AIOCS_INF_NIF
,
650 * Get physical interface statistics
652 if (aip
->air_physt_intf
[0] != '\0') {
654 * Interface specified
656 if ((pip
= atm_pifname(aip
->air_physt_intf
))) {
657 err
= (*pip
->pif_ioctl
)(AIOCS_INF_PIS
,
664 * Want statistics for every physical interface
666 for (pip
= atm_interface_head
; pip
;
667 pip
= pip
->pif_next
) {
668 err
= (*pip
->pif_ioctl
)(AIOCS_INF_PIS
,
678 * Get ATM software version
680 if (len
< sizeof(atm_version
)) {
684 if ((err
= copyout((caddr_t
)&atm_version
,
686 sizeof(atm_version
))) != 0) {
689 aip
->air_buf_addr
+= sizeof(atm_version
);
690 aip
->air_buf_len
-= sizeof(atm_version
);
698 * Calculate returned buffer length
700 aip
->air_buf_len
= len
- aip
->air_buf_len
;