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.8 2004/03/05 16:57:16 hsu 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);
51 * New-style socket request routines
53 #if (defined(__DragonFly__) && (BSD >= 199506))
54 struct pr_usrreqs atm_dgram_usrreqs = {
55 atm_proto_notsupp1, /* pru_abort */
56 pru_accept_notsupp, /* pru_accept */
57 atm_dgram_attach, /* pru_attach */
58 atm_proto_notsupp2, /* pru_bind */
59 pru_connect_notsupp, /* pru_connect */
60 pru_connect2_notsupp, /* pru_connect2 */
61 atm_dgram_control, /* pru_control */
62 atm_proto_notsupp1, /* pru_detach */
63 atm_proto_notsupp1, /* pru_disconnect */
64 pru_listen_notsupp, /* pru_listen */
65 atm_proto_notsupp3, /* pru_peeraddr */
66 pru_rcvd_notsupp, /* pru_rcvd */
67 pru_rcvoob_notsupp, /* pru_rcvoob */
68 atm_proto_notsupp4, /* pru_send */
69 pru_sense_null, /* pru_sense */
70 atm_proto_notsupp1, /* pru_shutdown */
71 atm_proto_notsupp3, /* pru_sockaddr */
77 * Handy common code macros
84 * Stack queue should have been drained \
86 if (atm_stackq_head != NULL) \
87 panic("atm_usrreq: stack queue not empty"); \
98 * Drain any deferred calls \
105 #define ATM_RETERR(errno) { \
112 * Attach protocol to socket
115 * so pointer to socket
116 * proto protocol identifier
117 * p pointer to process
120 * 0 request processed
121 * errno error processing request - reason indicated
125 atm_dgram_attach(struct socket *so, int proto, struct pru_attach_info *ai)
130 * Nothing to do here for ioctl()-only sockets
137 * Process ioctl system calls
140 * so pointer to socket
142 * data pointer to code specific parameter data area
143 * ifp pointer to ifnet structure if it's an interface ioctl
144 * p pointer to process
147 * 0 request processed
148 * errno error processing request - reason indicated
152 atm_dgram_control(so, cmd, data, ifp, td)
162 * First, figure out which ioctl we're dealing with and
163 * then process it based on the sub-op code
168 struct atmcfgreq *acp = (struct atmcfgreq *)data;
174 switch (acp->acr_opcode) {
178 * Attach signalling manager
180 if ((pip = atm_pifname(acp->acr_att_intf)) == NULL)
182 err = atm_sigmgr_attach(pip, acp->acr_att_proto);
187 * Detach signalling manager
189 if ((pip = atm_pifname(acp->acr_det_intf)) == NULL)
191 err = atm_sigmgr_detach(pip);
201 struct atmaddreq *aap = (struct atmaddreq *)data;
207 switch (aap->aar_opcode) {
211 * Add a PVC definition
215 * Locate requested endpoint service
217 epp = aap->aar_pvc_sap > ENDPT_MAX ? NULL :
218 atm_endpoints[aap->aar_pvc_sap];
220 ATM_RETERR(ENOPROTOOPT);
223 * Let endpoint service handle it from here
225 err = (*epp->ep_ioctl)(AIOCS_ADD_PVC, data, NULL);
232 epp = atm_endpoints[ENDPT_IP];
234 ATM_RETERR(ENOPROTOOPT);
237 * Let IP/ATM endpoint handle this
239 err = (*epp->ep_ioctl) (AIOCS_ADD_ARP, data, NULL);
249 struct atmdelreq *adp = (struct atmdelreq *)data;
257 switch (adp->adr_opcode) {
262 * Delete a PVC or SVC
266 * Locate appropriate sigmgr
268 if ((pip = atm_pifname(adp->adr_pvc_intf)) == NULL)
270 if ((smp = pip->pif_sigmgr) == NULL)
274 * Let sigmgr handle it from here
276 err = (*smp->sm_ioctl)(adp->adr_opcode, data,
277 (caddr_t)pip->pif_siginst);
282 * Delete an ARP mapping
284 epp = atm_endpoints[ENDPT_IP];
286 ATM_RETERR(ENOPROTOOPT);
289 * Let IP/ATM endpoint handle this
291 err = (*epp->ep_ioctl) (AIOCS_DEL_ARP, data, NULL);
301 struct atmsetreq *asp = (struct atmsetreq *)data;
310 switch (asp->asr_opcode) {
314 * Set an ARP server address
318 * Locate appropriate sigmgr
320 if ((nip = atm_nifname(asp->asr_arp_intf)) == NULL)
323 if ((smp = pip->pif_sigmgr) == NULL)
327 * Let sigmgr handle it from here
329 err = (*smp->sm_ioctl)(AIOCS_SET_ASV, data,
335 * Set physical interface MAC/ESI address
339 * Locate physical interface
341 if ((pip = atm_pifname(asp->asr_mac_intf)) == NULL)
345 * Interface must be detached
347 if (pip->pif_sigmgr != NULL)
348 ATM_RETERR(EADDRINUSE);
351 * Just plunk the address into the pif
353 KM_COPY((caddr_t)&asp->asr_mac_addr,
354 (caddr_t)&pip->pif_macaddr,
355 sizeof(struct mac_addr));
360 * Define network interfaces
362 if ((pip = atm_pifname(asp->asr_nif_intf)) == NULL)
366 * Validate interface count - logical interfaces
367 * are differentiated by the atm address selector.
369 if ((asp->asr_nif_cnt <= 0) || (asp->asr_nif_cnt > 256))
373 * Make sure prefix name is unique
375 TAILQ_FOREACH(ifp2, &ifnet, if_link) {
376 if (!strcmp(ifp2->if_dname, asp->asr_nif_pref)) {
378 * If this is for the interface we're
379 * (re-)defining, let it through
381 for (nip = pip->pif_nif; nip;
382 nip = nip->nif_pnext) {
383 if (&nip->nif_if == ifp2)
393 * Let interface handle it from here
395 err = (*pip->pif_ioctl)(AIOCS_SET_NIF, data,
401 * Set interface NSAP Prefix
405 * Locate appropriate sigmgr
407 if ((pip = atm_pifname(asp->asr_prf_intf)) == NULL)
409 if ((smp = pip->pif_sigmgr) == NULL)
413 * Let sigmgr handle it from here
415 err = (*smp->sm_ioctl)(AIOCS_SET_PRF, data,
416 (caddr_t)pip->pif_siginst);
426 err = atm_dgram_info(data);
439 * Process AIOCINFO ioctl system calls
444 * data pointer to AIOCINFO parameter structure
447 * 0 request processed
448 * errno error processing request - reason indicated
455 struct atminfreq *aip = (struct atminfreq *)data;
460 int len = aip->air_buf_len;
463 switch (aip->air_opcode) {
468 * Get vendor interface information
470 if (aip->air_vinfo_intf[0] != '\0') {
472 * Interface specified
474 if ((pip = atm_pifname(aip->air_vinfo_intf))) {
475 err = (*pip->pif_ioctl)(aip->air_opcode, data,
482 * Want info for every interface
484 for (pip = atm_interface_head; pip;
485 pip = pip->pif_next) {
486 err = (*pip->pif_ioctl)(aip->air_opcode, data,
496 * Get IP Map information
498 epp = atm_endpoints[ENDPT_IP];
500 err = (*epp->ep_ioctl) (AIOCS_INF_IPM, data, NULL);
508 * Get ARP table information
510 for (pip = atm_interface_head; pip; pip = pip->pif_next) {
511 if ((smp = pip->pif_sigmgr) != NULL) {
512 err = (*smp->sm_ioctl)(AIOCS_INF_ARP,
513 data, (caddr_t)pip->pif_siginst);
522 * Get ARP server information
524 if (aip->air_asrv_intf[0] != '\0') {
526 * Interface specified
528 if ((nip = atm_nifname(aip->air_asrv_intf))) {
529 if ((smp = nip->nif_pif->pif_sigmgr) != NULL) {
530 err = (*smp->sm_ioctl)(AIOCS_INF_ASV,
538 * Want info for all arp servers
540 for (pip = atm_interface_head; pip;
541 pip = pip->pif_next) {
542 if ((smp = pip->pif_sigmgr) != NULL) {
543 for (nip = pip->pif_nif; nip;
544 nip = nip->nif_pnext) {
545 err = (*smp->sm_ioctl)
546 (AIOCS_INF_ASV, data,
560 * Get physical interface info
562 if (aip->air_int_intf[0] != '\0') {
564 * Interface specified
566 if ((pip = atm_pifname(aip->air_int_intf))) {
567 err = (*pip->pif_ioctl)(AIOCS_INF_INT,
574 * Want info for every physical interface
576 for (pip = atm_interface_head; pip;
577 pip = pip->pif_next) {
578 err = (*pip->pif_ioctl)(AIOCS_INF_INT,
588 * Get VCC information
590 if (aip->air_vcc_intf[0] != '\0') {
592 * Interface specified
594 if ((pip = atm_pifname(aip->air_vcc_intf))) {
595 if ((smp = pip->pif_sigmgr) != NULL) {
596 err = (*smp->sm_ioctl)(AIOCS_INF_VCC,
598 (caddr_t)pip->pif_siginst);
605 * Want info for every interface
607 for (pip = atm_interface_head; pip;
608 pip = pip->pif_next) {
609 if ((smp = pip->pif_sigmgr) != NULL) {
610 err = (*smp->sm_ioctl)(AIOCS_INF_VCC,
612 (caddr_t)pip->pif_siginst);
622 * Get network interface info
624 if (aip->air_int_intf[0] != '\0') {
626 * Interface specified
628 if ((nip = atm_nifname(aip->air_int_intf))) {
630 err = (*pip->pif_ioctl)(AIOCS_INF_NIF,
637 * Want info for every network interface
639 for (pip = atm_interface_head; pip;
640 pip = pip->pif_next) {
641 for (nip = pip->pif_nif; nip;
642 nip = nip->nif_pnext) {
643 err = (*pip->pif_ioctl)(AIOCS_INF_NIF,
656 * Get physical interface statistics
658 if (aip->air_physt_intf[0] != '\0') {
660 * Interface specified
662 if ((pip = atm_pifname(aip->air_physt_intf))) {
663 err = (*pip->pif_ioctl)(AIOCS_INF_PIS,
670 * Want statistics for every physical interface
672 for (pip = atm_interface_head; pip;
673 pip = pip->pif_next) {
674 err = (*pip->pif_ioctl)(AIOCS_INF_PIS,
684 * Get ATM software version
686 if (len < sizeof(atm_version)) {
690 if ((err = copyout((caddr_t)&atm_version,
692 sizeof(atm_version))) != 0) {
695 aip->air_buf_addr += sizeof(atm_version);
696 aip->air_buf_len -= sizeof(atm_version);
704 * Calculate returned buffer length
706 aip->air_buf_len = len - aip->air_buf_len;