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>
39 #include <sys/protosw.h>
40 #include <sys/socket.h>
42 #include <netatm/port.h>
43 #include <netatm/queue.h>
44 #include <netatm/atm.h>
45 #include <netatm/atm_sys.h>
46 #include <netatm/atm_sap.h>
47 #include <netatm/atm_cm.h>
48 #include <netatm/atm_if.h>
49 #include <netatm/atm_ioctl.h>
50 #include <netatm/atm_sigmgr.h>
51 #include <netatm/atm_stack.h>
52 #include <netatm/atm_pcb.h>
53 #include <netatm/atm_var.h>
59 static int atm_dgram_attach(struct socket *, int, struct thread *);
60 static int atm_dgram_control(struct socket *, u_long, caddr_t,
61 struct ifnet *, struct thread *);
62 static int atm_dgram_info(caddr_t);
66 * New-style socket request routines
68 struct pr_usrreqs atm_dgram_usrreqs = {
69 .pru_abort = atm_proto_notsupp5,
70 .pru_attach = atm_dgram_attach,
71 .pru_bind = atm_proto_notsupp2,
72 .pru_control = atm_dgram_control,
73 .pru_detach = atm_proto_notsupp5,
74 .pru_disconnect = atm_proto_notsupp1,
75 .pru_peeraddr = atm_proto_notsupp3,
76 .pru_send = atm_proto_notsupp4,
77 .pru_shutdown = atm_proto_notsupp1,
78 .pru_sockaddr = atm_proto_notsupp3,
80 .pru_soreceive = NULL,
86 * Handy common code macros
93 * Stack queue should have been drained \
95 if (atm_stackq_head != NULL) \
96 panic("atm_usrreq: stack queue not empty"); \
105 #define ATM_OUTRO() \
107 * Drain any deferred calls \
114 #define ATM_RETERR(errno) { \
121 * Attach protocol to socket
124 * so pointer to socket
125 * proto protocol identifier
126 * p pointer to process
129 * 0 request processed
130 * errno error processing request - reason indicated
134 atm_dgram_attach(so, proto, td)
142 * Nothing to do here for ioctl()-only sockets
149 * Process ioctl system calls
152 * so pointer to socket
154 * data pointer to code specific parameter data area
155 * ifp pointer to ifnet structure if it's an interface ioctl
156 * p pointer to process
159 * 0 request processed
160 * errno error processing request - reason indicated
164 atm_dgram_control(so, cmd, data, ifp, td)
174 * First, figure out which ioctl we're dealing with and
175 * then process it based on the sub-op code
180 struct atmcfgreq *acp = (struct atmcfgreq *)data;
183 if (td && (suser(td) != 0))
186 switch (acp->acr_opcode) {
190 * Attach signalling manager
192 if ((pip = atm_pifname(acp->acr_att_intf)) == NULL)
194 err = atm_sigmgr_attach(pip, acp->acr_att_proto);
199 * Detach signalling manager
201 if ((pip = atm_pifname(acp->acr_det_intf)) == NULL)
203 err = atm_sigmgr_detach(pip);
213 struct atmaddreq *aap = (struct atmaddreq *)data;
216 if (td && (suser(td) != 0))
219 switch (aap->aar_opcode) {
223 * Add a PVC definition
227 * Locate requested endpoint service
229 epp = aap->aar_pvc_sap > ENDPT_MAX ? NULL :
230 atm_endpoints[aap->aar_pvc_sap];
232 ATM_RETERR(ENOPROTOOPT);
235 * Let endpoint service handle it from here
237 err = (*epp->ep_ioctl)(AIOCS_ADD_PVC, data, NULL);
244 epp = atm_endpoints[ENDPT_IP];
246 ATM_RETERR(ENOPROTOOPT);
249 * Let IP/ATM endpoint handle this
251 err = (*epp->ep_ioctl) (AIOCS_ADD_ARP, data, NULL);
261 struct atmdelreq *adp = (struct atmdelreq *)data;
266 if (td && (suser(td) != 0))
269 switch (adp->adr_opcode) {
274 * Delete a PVC or SVC
278 * Locate appropriate sigmgr
280 if ((pip = atm_pifname(adp->adr_pvc_intf)) == NULL)
282 if ((smp = pip->pif_sigmgr) == NULL)
286 * Let sigmgr handle it from here
288 err = (*smp->sm_ioctl)(adp->adr_opcode, data,
289 (caddr_t)pip->pif_siginst);
294 * Delete an ARP mapping
296 epp = atm_endpoints[ENDPT_IP];
298 ATM_RETERR(ENOPROTOOPT);
301 * Let IP/ATM endpoint handle this
303 err = (*epp->ep_ioctl) (AIOCS_DEL_ARP, data, NULL);
313 struct atmsetreq *asp = (struct atmsetreq *)data;
319 if (td && (suser(td) != 0))
322 switch (asp->asr_opcode) {
326 * Set an ARP server address
330 * Locate appropriate sigmgr
332 if ((nip = atm_nifname(asp->asr_arp_intf)) == NULL)
335 if ((smp = pip->pif_sigmgr) == NULL)
339 * Let sigmgr handle it from here
341 err = (*smp->sm_ioctl)(AIOCS_SET_ASV, data,
347 * Set physical interface MAC/ESI address
351 * Locate physical interface
353 if ((pip = atm_pifname(asp->asr_mac_intf)) == NULL)
357 * Interface must be detached
359 if (pip->pif_sigmgr != NULL)
360 ATM_RETERR(EADDRINUSE);
363 * Just plunk the address into the pif
365 bcopy((caddr_t)&asp->asr_mac_addr,
366 (caddr_t)&pip->pif_macaddr,
367 sizeof(struct mac_addr));
372 * Define network interfaces
374 if ((pip = atm_pifname(asp->asr_nif_intf)) == NULL)
378 * Validate interface count - logical interfaces
379 * are differentiated by the atm address selector.
381 if (asp->asr_nif_cnt == 0 || asp->asr_nif_cnt > 256)
385 * Make sure prefix name is unique
388 TAILQ_FOREACH(ifp2, &ifnet, if_link) {
389 if (!strcmp(ifp2->if_dname, asp->asr_nif_pref)) {
391 * If this is for the interface we're
392 * (re-)defining, let it through
394 for (nip = pip->pif_nif; nip;
395 nip = nip->nif_pnext) {
396 if (ANIF2IFP(nip) == ifp2)
408 * Let interface handle it from here
410 err = (*pip->pif_ioctl)(AIOCS_SET_NIF, data,
416 * Set interface NSAP Prefix
420 * Locate appropriate sigmgr
422 if ((pip = atm_pifname(asp->asr_prf_intf)) == NULL)
424 if ((smp = pip->pif_sigmgr) == NULL)
428 * Let sigmgr handle it from here
430 err = (*smp->sm_ioctl)(AIOCS_SET_PRF, data,
431 (caddr_t)pip->pif_siginst);
441 err = atm_dgram_info(data);
454 * Process AIOCINFO ioctl system calls
459 * data pointer to AIOCINFO parameter structure
462 * 0 request processed
463 * errno error processing request - reason indicated
470 struct atminfreq *aip = (struct atminfreq *)data;
475 int len = aip->air_buf_len;
478 switch (aip->air_opcode) {
483 * Get vendor interface information
485 if (aip->air_vinfo_intf[0] != '\0') {
487 * Interface specified
489 if ((pip = atm_pifname(aip->air_vinfo_intf))) {
490 err = (*pip->pif_ioctl)(aip->air_opcode, data,
497 * Want info for every interface
499 for (pip = atm_interface_head; pip;
500 pip = pip->pif_next) {
501 err = (*pip->pif_ioctl)(aip->air_opcode, data,
511 * Get IP Map information
513 epp = atm_endpoints[ENDPT_IP];
515 err = (*epp->ep_ioctl) (AIOCS_INF_IPM, data, NULL);
523 * Get ARP table information
525 for (pip = atm_interface_head; pip; pip = pip->pif_next) {
526 if ((smp = pip->pif_sigmgr) != NULL) {
527 err = (*smp->sm_ioctl)(AIOCS_INF_ARP,
528 data, (caddr_t)pip->pif_siginst);
537 * Get ARP server information
539 if (aip->air_asrv_intf[0] != '\0') {
541 * Interface specified
543 if ((nip = atm_nifname(aip->air_asrv_intf))) {
544 if ((smp = nip->nif_pif->pif_sigmgr) != NULL) {
545 err = (*smp->sm_ioctl)(AIOCS_INF_ASV,
553 * Want info for all arp servers
555 for (pip = atm_interface_head; pip;
556 pip = pip->pif_next) {
557 if ((smp = pip->pif_sigmgr) != NULL) {
558 for (nip = pip->pif_nif; nip;
559 nip = nip->nif_pnext) {
560 err = (*smp->sm_ioctl)
561 (AIOCS_INF_ASV, data,
575 * Get physical interface info
577 if (aip->air_int_intf[0] != '\0') {
579 * Interface specified
581 if ((pip = atm_pifname(aip->air_int_intf))) {
582 err = (*pip->pif_ioctl)(AIOCS_INF_INT,
589 * Want info for every physical interface
591 for (pip = atm_interface_head; pip;
592 pip = pip->pif_next) {
593 err = (*pip->pif_ioctl)(AIOCS_INF_INT,
603 * Get VCC information
605 if (aip->air_vcc_intf[0] != '\0') {
607 * Interface specified
609 if ((pip = atm_pifname(aip->air_vcc_intf))) {
610 if ((smp = pip->pif_sigmgr) != NULL) {
611 err = (*smp->sm_ioctl)(AIOCS_INF_VCC,
613 (caddr_t)pip->pif_siginst);
620 * Want info for every interface
622 for (pip = atm_interface_head; pip;
623 pip = pip->pif_next) {
624 if ((smp = pip->pif_sigmgr) != NULL) {
625 err = (*smp->sm_ioctl)(AIOCS_INF_VCC,
627 (caddr_t)pip->pif_siginst);
637 * Get network interface info
639 if (aip->air_int_intf[0] != '\0') {
641 * Interface specified
643 if ((nip = atm_nifname(aip->air_int_intf))) {
645 err = (*pip->pif_ioctl)(AIOCS_INF_NIF,
652 * Want info for every network interface
654 for (pip = atm_interface_head; pip;
655 pip = pip->pif_next) {
656 for (nip = pip->pif_nif; nip;
657 nip = nip->nif_pnext) {
658 err = (*pip->pif_ioctl)(AIOCS_INF_NIF,
671 * Get physical interface statistics
673 if (aip->air_physt_intf[0] != '\0') {
675 * Interface specified
677 if ((pip = atm_pifname(aip->air_physt_intf))) {
678 err = (*pip->pif_ioctl)(AIOCS_INF_PIS,
685 * Want statistics for every physical interface
687 for (pip = atm_interface_head; pip;
688 pip = pip->pif_next) {
689 err = (*pip->pif_ioctl)(AIOCS_INF_PIS,
699 * Get ATM software version
701 if (len < sizeof(atm_version)) {
705 if ((err = copyout((caddr_t)&atm_version,
707 sizeof(atm_version))) != 0) {
710 aip->air_buf_addr += sizeof(atm_version);
711 aip->air_buf_len -= sizeof(atm_version);
719 * Calculate returned buffer length
721 aip->air_buf_len = len - aip->air_buf_len;