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.
30 * ATM DGRAM socket protocol processing
33 #include <sys/cdefs.h>
34 __FBSDID("$FreeBSD$");
36 #include <sys/param.h>
37 #include <sys/systm.h>
38 #include <sys/sockio.h>
40 #include <sys/protosw.h>
41 #include <sys/socket.h>
43 #include <netatm/port.h>
44 #include <netatm/queue.h>
45 #include <netatm/atm.h>
46 #include <netatm/atm_sys.h>
47 #include <netatm/atm_sap.h>
48 #include <netatm/atm_cm.h>
49 #include <netatm/atm_if.h>
50 #include <netatm/atm_ioctl.h>
51 #include <netatm/atm_sigmgr.h>
52 #include <netatm/atm_stack.h>
53 #include <netatm/atm_pcb.h>
54 #include <netatm/atm_var.h>
60 static int atm_dgram_attach(struct socket *, int, struct thread *);
61 static int atm_dgram_control(struct socket *, u_long, caddr_t,
62 struct ifnet *, struct thread *);
63 static int atm_dgram_info(caddr_t);
67 * New-style socket request routines
69 struct pr_usrreqs atm_dgram_usrreqs = {
70 .pru_abort = atm_proto_notsupp5,
71 .pru_attach = atm_dgram_attach,
72 .pru_bind = atm_proto_notsupp2,
73 .pru_control = atm_dgram_control,
74 .pru_detach = atm_proto_notsupp5,
75 .pru_disconnect = atm_proto_notsupp1,
76 .pru_peeraddr = atm_proto_notsupp3,
77 .pru_send = atm_proto_notsupp4,
78 .pru_shutdown = atm_proto_notsupp1,
79 .pru_sockaddr = atm_proto_notsupp3,
81 .pru_soreceive = NULL,
83 .pru_close = atm_proto_notsupp5,
88 * Handy common code macros
95 * Stack queue should have been drained \
97 if (atm_stackq_head != NULL) \
98 panic("atm_usrreq: stack queue not empty"); \
101 #define ATM_INTRO() \
107 #define ATM_OUTRO() \
109 * Drain any deferred calls \
116 #define ATM_RETERR(errno) { \
123 * Attach protocol to socket
126 * so pointer to socket
127 * proto protocol identifier
128 * p pointer to process
131 * 0 request processed
132 * errno error processing request - reason indicated
136 atm_dgram_attach(so, proto, td)
144 * Nothing to do here for ioctl()-only sockets
151 * Process ioctl system calls
154 * so pointer to socket
156 * data pointer to code specific parameter data area
157 * ifp pointer to ifnet structure if it's an interface ioctl
158 * p pointer to process
161 * 0 request processed
162 * errno error processing request - reason indicated
166 atm_dgram_control(so, cmd, data, ifp, td)
176 * First, figure out which ioctl we're dealing with and
177 * then process it based on the sub-op code
182 struct atmcfgreq *acp = (struct atmcfgreq *)data;
186 err = priv_check(td, PRIV_NETATM_CFG);
191 switch (acp->acr_opcode) {
195 * Attach signalling manager
197 if ((pip = atm_pifname(acp->acr_att_intf)) == NULL)
199 err = atm_sigmgr_attach(pip, acp->acr_att_proto);
204 * Detach signalling manager
206 if ((pip = atm_pifname(acp->acr_det_intf)) == NULL)
208 err = atm_sigmgr_detach(pip);
218 struct atmaddreq *aap = (struct atmaddreq *)data;
222 err = priv_check(td, PRIV_NETATM_ADD);
227 switch (aap->aar_opcode) {
231 * Add a PVC definition
235 * Locate requested endpoint service
237 epp = aap->aar_pvc_sap > ENDPT_MAX ? NULL :
238 atm_endpoints[aap->aar_pvc_sap];
240 ATM_RETERR(ENOPROTOOPT);
243 * Let endpoint service handle it from here
245 err = (*epp->ep_ioctl)(AIOCS_ADD_PVC, data, NULL);
252 epp = atm_endpoints[ENDPT_IP];
254 ATM_RETERR(ENOPROTOOPT);
257 * Let IP/ATM endpoint handle this
259 err = (*epp->ep_ioctl) (AIOCS_ADD_ARP, data, NULL);
269 struct atmdelreq *adp = (struct atmdelreq *)data;
275 err = priv_check(td, PRIV_NETATM_DEL);
280 switch (adp->adr_opcode) {
285 * Delete a PVC or SVC
289 * Locate appropriate sigmgr
291 if ((pip = atm_pifname(adp->adr_pvc_intf)) == NULL)
293 if ((smp = pip->pif_sigmgr) == NULL)
297 * Let sigmgr handle it from here
299 err = (*smp->sm_ioctl)(adp->adr_opcode, data,
300 (caddr_t)pip->pif_siginst);
305 * Delete an ARP mapping
307 epp = atm_endpoints[ENDPT_IP];
309 ATM_RETERR(ENOPROTOOPT);
312 * Let IP/ATM endpoint handle this
314 err = (*epp->ep_ioctl) (AIOCS_DEL_ARP, data, NULL);
324 struct atmsetreq *asp = (struct atmsetreq *)data;
331 err = priv_check(td, PRIV_NETATM_SET);
336 switch (asp->asr_opcode) {
340 * Set an ARP server address
344 * Locate appropriate sigmgr
346 if ((nip = atm_nifname(asp->asr_arp_intf)) == NULL)
349 if ((smp = pip->pif_sigmgr) == NULL)
353 * Let sigmgr handle it from here
355 err = (*smp->sm_ioctl)(AIOCS_SET_ASV, data,
361 * Set physical interface MAC/ESI address
365 * Locate physical interface
367 if ((pip = atm_pifname(asp->asr_mac_intf)) == NULL)
371 * Interface must be detached
373 if (pip->pif_sigmgr != NULL)
374 ATM_RETERR(EADDRINUSE);
377 * Just plunk the address into the pif
379 bcopy((caddr_t)&asp->asr_mac_addr,
380 (caddr_t)&pip->pif_macaddr,
381 sizeof(struct mac_addr));
386 * Define network interfaces
388 if ((pip = atm_pifname(asp->asr_nif_intf)) == NULL)
392 * Validate interface count - logical interfaces
393 * are differentiated by the atm address selector.
395 if (asp->asr_nif_cnt == 0 || asp->asr_nif_cnt > 256)
399 * Make sure prefix name is unique
402 TAILQ_FOREACH(ifp2, &ifnet, if_link) {
403 if (!strcmp(ifp2->if_dname, asp->asr_nif_pref)) {
405 * If this is for the interface we're
406 * (re-)defining, let it through
408 for (nip = pip->pif_nif; nip;
409 nip = nip->nif_pnext) {
410 if (ANIF2IFP(nip) == ifp2)
422 * Let interface handle it from here
424 err = (*pip->pif_ioctl)(AIOCS_SET_NIF, data,
430 * Set interface NSAP Prefix
434 * Locate appropriate sigmgr
436 if ((pip = atm_pifname(asp->asr_prf_intf)) == NULL)
438 if ((smp = pip->pif_sigmgr) == NULL)
442 * Let sigmgr handle it from here
444 err = (*smp->sm_ioctl)(AIOCS_SET_PRF, data,
445 (caddr_t)pip->pif_siginst);
455 err = atm_dgram_info(data);
468 * Process AIOCINFO ioctl system calls
473 * data pointer to AIOCINFO parameter structure
476 * 0 request processed
477 * errno error processing request - reason indicated
484 struct atminfreq *aip = (struct atminfreq *)data;
489 int len = aip->air_buf_len;
492 switch (aip->air_opcode) {
497 * Get vendor interface information
499 if (aip->air_vinfo_intf[0] != '\0') {
501 * Interface specified
503 if ((pip = atm_pifname(aip->air_vinfo_intf))) {
504 err = (*pip->pif_ioctl)(aip->air_opcode, data,
511 * Want info for every interface
513 for (pip = atm_interface_head; pip;
514 pip = pip->pif_next) {
515 err = (*pip->pif_ioctl)(aip->air_opcode, data,
525 * Get IP Map information
527 epp = atm_endpoints[ENDPT_IP];
529 err = (*epp->ep_ioctl) (AIOCS_INF_IPM, data, NULL);
537 * Get ARP table information
539 for (pip = atm_interface_head; pip; pip = pip->pif_next) {
540 if ((smp = pip->pif_sigmgr) != NULL) {
541 err = (*smp->sm_ioctl)(AIOCS_INF_ARP,
542 data, (caddr_t)pip->pif_siginst);
551 * Get ARP server information
553 if (aip->air_asrv_intf[0] != '\0') {
555 * Interface specified
557 if ((nip = atm_nifname(aip->air_asrv_intf))) {
558 if ((smp = nip->nif_pif->pif_sigmgr) != NULL) {
559 err = (*smp->sm_ioctl)(AIOCS_INF_ASV,
567 * Want info for all arp servers
569 for (pip = atm_interface_head; pip;
570 pip = pip->pif_next) {
571 if ((smp = pip->pif_sigmgr) != NULL) {
572 for (nip = pip->pif_nif; nip;
573 nip = nip->nif_pnext) {
574 err = (*smp->sm_ioctl)
575 (AIOCS_INF_ASV, data,
589 * Get physical interface info
591 if (aip->air_int_intf[0] != '\0') {
593 * Interface specified
595 if ((pip = atm_pifname(aip->air_int_intf))) {
596 err = (*pip->pif_ioctl)(AIOCS_INF_INT,
603 * Want info for every physical interface
605 for (pip = atm_interface_head; pip;
606 pip = pip->pif_next) {
607 err = (*pip->pif_ioctl)(AIOCS_INF_INT,
617 * Get VCC information
619 if (aip->air_vcc_intf[0] != '\0') {
621 * Interface specified
623 if ((pip = atm_pifname(aip->air_vcc_intf))) {
624 if ((smp = pip->pif_sigmgr) != NULL) {
625 err = (*smp->sm_ioctl)(AIOCS_INF_VCC,
627 (caddr_t)pip->pif_siginst);
634 * Want info for every interface
636 for (pip = atm_interface_head; pip;
637 pip = pip->pif_next) {
638 if ((smp = pip->pif_sigmgr) != NULL) {
639 err = (*smp->sm_ioctl)(AIOCS_INF_VCC,
641 (caddr_t)pip->pif_siginst);
651 * Get network interface info
653 if (aip->air_int_intf[0] != '\0') {
655 * Interface specified
657 if ((nip = atm_nifname(aip->air_int_intf))) {
659 err = (*pip->pif_ioctl)(AIOCS_INF_NIF,
666 * Want info for every network interface
668 for (pip = atm_interface_head; pip;
669 pip = pip->pif_next) {
670 for (nip = pip->pif_nif; nip;
671 nip = nip->nif_pnext) {
672 err = (*pip->pif_ioctl)(AIOCS_INF_NIF,
685 * Get physical interface statistics
687 if (aip->air_physt_intf[0] != '\0') {
689 * Interface specified
691 if ((pip = atm_pifname(aip->air_physt_intf))) {
692 err = (*pip->pif_ioctl)(AIOCS_INF_PIS,
699 * Want statistics for every physical interface
701 for (pip = atm_interface_head; pip;
702 pip = pip->pif_next) {
703 err = (*pip->pif_ioctl)(AIOCS_INF_PIS,
713 * Get ATM software version
715 if (len < sizeof(atm_version)) {
719 if ((err = copyout((caddr_t)&atm_version,
721 sizeof(atm_version))) != 0) {
724 aip->air_buf_addr += sizeof(atm_version);
725 aip->air_buf_len -= sizeof(atm_version);
733 * Calculate returned buffer length
735 aip->air_buf_len = len - aip->air_buf_len;