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,
82 .pru_close = atm_proto_notsupp5,
87 * Handy common code macros
94 * Stack queue should have been drained \
96 if (atm_stackq_head != NULL) \
97 panic("atm_usrreq: stack queue not empty"); \
100 #define ATM_INTRO() \
106 #define ATM_OUTRO() \
108 * Drain any deferred calls \
115 #define ATM_RETERR(errno) { \
122 * Attach protocol to socket
125 * so pointer to socket
126 * proto protocol identifier
127 * p pointer to process
130 * 0 request processed
131 * errno error processing request - reason indicated
135 atm_dgram_attach(so, proto, td)
143 * Nothing to do here for ioctl()-only sockets
150 * Process ioctl system calls
153 * so pointer to socket
155 * data pointer to code specific parameter data area
156 * ifp pointer to ifnet structure if it's an interface ioctl
157 * p pointer to process
160 * 0 request processed
161 * errno error processing request - reason indicated
165 atm_dgram_control(so, cmd, data, ifp, td)
175 * First, figure out which ioctl we're dealing with and
176 * then process it based on the sub-op code
181 struct atmcfgreq *acp = (struct atmcfgreq *)data;
184 if (td && (suser(td) != 0))
187 switch (acp->acr_opcode) {
191 * Attach signalling manager
193 if ((pip = atm_pifname(acp->acr_att_intf)) == NULL)
195 err = atm_sigmgr_attach(pip, acp->acr_att_proto);
200 * Detach signalling manager
202 if ((pip = atm_pifname(acp->acr_det_intf)) == NULL)
204 err = atm_sigmgr_detach(pip);
214 struct atmaddreq *aap = (struct atmaddreq *)data;
217 if (td && (suser(td) != 0))
220 switch (aap->aar_opcode) {
224 * Add a PVC definition
228 * Locate requested endpoint service
230 epp = aap->aar_pvc_sap > ENDPT_MAX ? NULL :
231 atm_endpoints[aap->aar_pvc_sap];
233 ATM_RETERR(ENOPROTOOPT);
236 * Let endpoint service handle it from here
238 err = (*epp->ep_ioctl)(AIOCS_ADD_PVC, data, NULL);
245 epp = atm_endpoints[ENDPT_IP];
247 ATM_RETERR(ENOPROTOOPT);
250 * Let IP/ATM endpoint handle this
252 err = (*epp->ep_ioctl) (AIOCS_ADD_ARP, data, NULL);
262 struct atmdelreq *adp = (struct atmdelreq *)data;
267 if (td && (suser(td) != 0))
270 switch (adp->adr_opcode) {
275 * Delete a PVC or SVC
279 * Locate appropriate sigmgr
281 if ((pip = atm_pifname(adp->adr_pvc_intf)) == NULL)
283 if ((smp = pip->pif_sigmgr) == NULL)
287 * Let sigmgr handle it from here
289 err = (*smp->sm_ioctl)(adp->adr_opcode, data,
290 (caddr_t)pip->pif_siginst);
295 * Delete an ARP mapping
297 epp = atm_endpoints[ENDPT_IP];
299 ATM_RETERR(ENOPROTOOPT);
302 * Let IP/ATM endpoint handle this
304 err = (*epp->ep_ioctl) (AIOCS_DEL_ARP, data, NULL);
314 struct atmsetreq *asp = (struct atmsetreq *)data;
320 if (td && (suser(td) != 0))
323 switch (asp->asr_opcode) {
327 * Set an ARP server address
331 * Locate appropriate sigmgr
333 if ((nip = atm_nifname(asp->asr_arp_intf)) == NULL)
336 if ((smp = pip->pif_sigmgr) == NULL)
340 * Let sigmgr handle it from here
342 err = (*smp->sm_ioctl)(AIOCS_SET_ASV, data,
348 * Set physical interface MAC/ESI address
352 * Locate physical interface
354 if ((pip = atm_pifname(asp->asr_mac_intf)) == NULL)
358 * Interface must be detached
360 if (pip->pif_sigmgr != NULL)
361 ATM_RETERR(EADDRINUSE);
364 * Just plunk the address into the pif
366 bcopy((caddr_t)&asp->asr_mac_addr,
367 (caddr_t)&pip->pif_macaddr,
368 sizeof(struct mac_addr));
373 * Define network interfaces
375 if ((pip = atm_pifname(asp->asr_nif_intf)) == NULL)
379 * Validate interface count - logical interfaces
380 * are differentiated by the atm address selector.
382 if (asp->asr_nif_cnt == 0 || asp->asr_nif_cnt > 256)
386 * Make sure prefix name is unique
389 TAILQ_FOREACH(ifp2, &ifnet, if_link) {
390 if (!strcmp(ifp2->if_dname, asp->asr_nif_pref)) {
392 * If this is for the interface we're
393 * (re-)defining, let it through
395 for (nip = pip->pif_nif; nip;
396 nip = nip->nif_pnext) {
397 if (ANIF2IFP(nip) == ifp2)
409 * Let interface handle it from here
411 err = (*pip->pif_ioctl)(AIOCS_SET_NIF, data,
417 * Set interface NSAP Prefix
421 * Locate appropriate sigmgr
423 if ((pip = atm_pifname(asp->asr_prf_intf)) == NULL)
425 if ((smp = pip->pif_sigmgr) == NULL)
429 * Let sigmgr handle it from here
431 err = (*smp->sm_ioctl)(AIOCS_SET_PRF, data,
432 (caddr_t)pip->pif_siginst);
442 err = atm_dgram_info(data);
455 * Process AIOCINFO ioctl system calls
460 * data pointer to AIOCINFO parameter structure
463 * 0 request processed
464 * errno error processing request - reason indicated
471 struct atminfreq *aip = (struct atminfreq *)data;
476 int len = aip->air_buf_len;
479 switch (aip->air_opcode) {
484 * Get vendor interface information
486 if (aip->air_vinfo_intf[0] != '\0') {
488 * Interface specified
490 if ((pip = atm_pifname(aip->air_vinfo_intf))) {
491 err = (*pip->pif_ioctl)(aip->air_opcode, data,
498 * Want info for every interface
500 for (pip = atm_interface_head; pip;
501 pip = pip->pif_next) {
502 err = (*pip->pif_ioctl)(aip->air_opcode, data,
512 * Get IP Map information
514 epp = atm_endpoints[ENDPT_IP];
516 err = (*epp->ep_ioctl) (AIOCS_INF_IPM, data, NULL);
524 * Get ARP table information
526 for (pip = atm_interface_head; pip; pip = pip->pif_next) {
527 if ((smp = pip->pif_sigmgr) != NULL) {
528 err = (*smp->sm_ioctl)(AIOCS_INF_ARP,
529 data, (caddr_t)pip->pif_siginst);
538 * Get ARP server information
540 if (aip->air_asrv_intf[0] != '\0') {
542 * Interface specified
544 if ((nip = atm_nifname(aip->air_asrv_intf))) {
545 if ((smp = nip->nif_pif->pif_sigmgr) != NULL) {
546 err = (*smp->sm_ioctl)(AIOCS_INF_ASV,
554 * Want info for all arp servers
556 for (pip = atm_interface_head; pip;
557 pip = pip->pif_next) {
558 if ((smp = pip->pif_sigmgr) != NULL) {
559 for (nip = pip->pif_nif; nip;
560 nip = nip->nif_pnext) {
561 err = (*smp->sm_ioctl)
562 (AIOCS_INF_ASV, data,
576 * Get physical interface info
578 if (aip->air_int_intf[0] != '\0') {
580 * Interface specified
582 if ((pip = atm_pifname(aip->air_int_intf))) {
583 err = (*pip->pif_ioctl)(AIOCS_INF_INT,
590 * Want info for every physical interface
592 for (pip = atm_interface_head; pip;
593 pip = pip->pif_next) {
594 err = (*pip->pif_ioctl)(AIOCS_INF_INT,
604 * Get VCC information
606 if (aip->air_vcc_intf[0] != '\0') {
608 * Interface specified
610 if ((pip = atm_pifname(aip->air_vcc_intf))) {
611 if ((smp = pip->pif_sigmgr) != NULL) {
612 err = (*smp->sm_ioctl)(AIOCS_INF_VCC,
614 (caddr_t)pip->pif_siginst);
621 * Want info for every interface
623 for (pip = atm_interface_head; pip;
624 pip = pip->pif_next) {
625 if ((smp = pip->pif_sigmgr) != NULL) {
626 err = (*smp->sm_ioctl)(AIOCS_INF_VCC,
628 (caddr_t)pip->pif_siginst);
638 * Get network interface info
640 if (aip->air_int_intf[0] != '\0') {
642 * Interface specified
644 if ((nip = atm_nifname(aip->air_int_intf))) {
646 err = (*pip->pif_ioctl)(AIOCS_INF_NIF,
653 * Want info for every network interface
655 for (pip = atm_interface_head; pip;
656 pip = pip->pif_next) {
657 for (nip = pip->pif_nif; nip;
658 nip = nip->nif_pnext) {
659 err = (*pip->pif_ioctl)(AIOCS_INF_NIF,
672 * Get physical interface statistics
674 if (aip->air_physt_intf[0] != '\0') {
676 * Interface specified
678 if ((pip = atm_pifname(aip->air_physt_intf))) {
679 err = (*pip->pif_ioctl)(AIOCS_INF_PIS,
686 * Want statistics for every physical interface
688 for (pip = atm_interface_head; pip;
689 pip = pip->pif_next) {
690 err = (*pip->pif_ioctl)(AIOCS_INF_PIS,
700 * Get ATM software version
702 if (len < sizeof(atm_version)) {
706 if ((err = copyout((caddr_t)&atm_version,
708 sizeof(atm_version))) != 0) {
711 aip->air_buf_addr += sizeof(atm_version);
712 aip->air_buf_len -= sizeof(atm_version);
720 * Calculate returned buffer length
722 aip->air_buf_len = len - aip->air_buf_len;