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;
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;
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;
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;
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;