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.9 2004/03/06 01:58:56 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);
50 * New-style socket request routines
52 #if (defined(__DragonFly__) && (BSD >= 199506))
53 struct pr_usrreqs atm_dgram_usrreqs = {
54 atm_proto_notsupp1, /* pru_abort */
55 pru_accept_notsupp, /* pru_accept */
56 atm_dgram_attach, /* pru_attach */
57 atm_proto_notsupp2, /* pru_bind */
58 pru_connect_notsupp, /* pru_connect */
59 pru_connect2_notsupp, /* pru_connect2 */
60 atm_dgram_control, /* pru_control */
61 atm_proto_notsupp1, /* pru_detach */
62 atm_proto_notsupp1, /* pru_disconnect */
63 pru_listen_notsupp, /* pru_listen */
64 atm_proto_notsupp3, /* pru_peeraddr */
65 pru_rcvd_notsupp, /* pru_rcvd */
66 pru_rcvoob_notsupp, /* pru_rcvoob */
67 atm_proto_notsupp4, /* pru_send */
68 pru_sense_null, /* pru_sense */
69 atm_proto_notsupp1, /* pru_shutdown */
70 atm_proto_notsupp3, /* pru_sockaddr */
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(so, cmd, data, ifp, td)
161 * First, figure out which ioctl we're dealing with and
162 * then process it based on the sub-op code
167 struct atmcfgreq *acp = (struct atmcfgreq *)data;
173 switch (acp->acr_opcode) {
177 * Attach signalling manager
179 if ((pip = atm_pifname(acp->acr_att_intf)) == NULL)
181 err = atm_sigmgr_attach(pip, acp->acr_att_proto);
186 * Detach signalling manager
188 if ((pip = atm_pifname(acp->acr_det_intf)) == NULL)
190 err = atm_sigmgr_detach(pip);
200 struct atmaddreq *aap = (struct atmaddreq *)data;
206 switch (aap->aar_opcode) {
210 * Add a PVC definition
214 * Locate requested endpoint service
216 epp = aap->aar_pvc_sap > ENDPT_MAX ? NULL :
217 atm_endpoints[aap->aar_pvc_sap];
219 ATM_RETERR(ENOPROTOOPT);
222 * Let endpoint service handle it from here
224 err = (*epp->ep_ioctl)(AIOCS_ADD_PVC, data, NULL);
231 epp = atm_endpoints[ENDPT_IP];
233 ATM_RETERR(ENOPROTOOPT);
236 * Let IP/ATM endpoint handle this
238 err = (*epp->ep_ioctl) (AIOCS_ADD_ARP, data, NULL);
248 struct atmdelreq *adp = (struct atmdelreq *)data;
256 switch (adp->adr_opcode) {
261 * Delete a PVC or SVC
265 * Locate appropriate sigmgr
267 if ((pip = atm_pifname(adp->adr_pvc_intf)) == NULL)
269 if ((smp = pip->pif_sigmgr) == NULL)
273 * Let sigmgr handle it from here
275 err = (*smp->sm_ioctl)(adp->adr_opcode, data,
276 (caddr_t)pip->pif_siginst);
281 * Delete an ARP mapping
283 epp = atm_endpoints[ENDPT_IP];
285 ATM_RETERR(ENOPROTOOPT);
288 * Let IP/ATM endpoint handle this
290 err = (*epp->ep_ioctl) (AIOCS_DEL_ARP, data, NULL);
300 struct atmsetreq *asp = (struct atmsetreq *)data;
309 switch (asp->asr_opcode) {
313 * Set an ARP server address
317 * Locate appropriate sigmgr
319 if ((nip = atm_nifname(asp->asr_arp_intf)) == NULL)
322 if ((smp = pip->pif_sigmgr) == NULL)
326 * Let sigmgr handle it from here
328 err = (*smp->sm_ioctl)(AIOCS_SET_ASV, data,
334 * Set physical interface MAC/ESI address
338 * Locate physical interface
340 if ((pip = atm_pifname(asp->asr_mac_intf)) == NULL)
344 * Interface must be detached
346 if (pip->pif_sigmgr != NULL)
347 ATM_RETERR(EADDRINUSE);
350 * Just plunk the address into the pif
352 KM_COPY((caddr_t)&asp->asr_mac_addr,
353 (caddr_t)&pip->pif_macaddr,
354 sizeof(struct mac_addr));
359 * Define network interfaces
361 if ((pip = atm_pifname(asp->asr_nif_intf)) == NULL)
365 * Validate interface count - logical interfaces
366 * are differentiated by the atm address selector.
368 if ((asp->asr_nif_cnt <= 0) || (asp->asr_nif_cnt > 256))
372 * Make sure prefix name is unique
374 TAILQ_FOREACH(ifp2, &ifnet, if_link) {
375 if (!strcmp(ifp2->if_dname, asp->asr_nif_pref)) {
377 * If this is for the interface we're
378 * (re-)defining, let it through
380 for (nip = pip->pif_nif; nip;
381 nip = nip->nif_pnext) {
382 if (&nip->nif_if == ifp2)
392 * Let interface handle it from here
394 err = (*pip->pif_ioctl)(AIOCS_SET_NIF, data,
400 * Set interface NSAP Prefix
404 * Locate appropriate sigmgr
406 if ((pip = atm_pifname(asp->asr_prf_intf)) == NULL)
408 if ((smp = pip->pif_sigmgr) == NULL)
412 * Let sigmgr handle it from here
414 err = (*smp->sm_ioctl)(AIOCS_SET_PRF, data,
415 (caddr_t)pip->pif_siginst);
425 err = atm_dgram_info(data);
438 * Process AIOCINFO ioctl system calls
443 * data pointer to AIOCINFO parameter structure
446 * 0 request processed
447 * errno error processing request - reason indicated
454 struct atminfreq *aip = (struct atminfreq *)data;
459 int len = aip->air_buf_len;
462 switch (aip->air_opcode) {
467 * Get vendor interface information
469 if (aip->air_vinfo_intf[0] != '\0') {
471 * Interface specified
473 if ((pip = atm_pifname(aip->air_vinfo_intf))) {
474 err = (*pip->pif_ioctl)(aip->air_opcode, data,
481 * Want info for every interface
483 for (pip = atm_interface_head; pip;
484 pip = pip->pif_next) {
485 err = (*pip->pif_ioctl)(aip->air_opcode, data,
495 * Get IP Map information
497 epp = atm_endpoints[ENDPT_IP];
499 err = (*epp->ep_ioctl) (AIOCS_INF_IPM, data, NULL);
507 * Get ARP table information
509 for (pip = atm_interface_head; pip; pip = pip->pif_next) {
510 if ((smp = pip->pif_sigmgr) != NULL) {
511 err = (*smp->sm_ioctl)(AIOCS_INF_ARP,
512 data, (caddr_t)pip->pif_siginst);
521 * Get ARP server information
523 if (aip->air_asrv_intf[0] != '\0') {
525 * Interface specified
527 if ((nip = atm_nifname(aip->air_asrv_intf))) {
528 if ((smp = nip->nif_pif->pif_sigmgr) != NULL) {
529 err = (*smp->sm_ioctl)(AIOCS_INF_ASV,
537 * Want info for all arp servers
539 for (pip = atm_interface_head; pip;
540 pip = pip->pif_next) {
541 if ((smp = pip->pif_sigmgr) != NULL) {
542 for (nip = pip->pif_nif; nip;
543 nip = nip->nif_pnext) {
544 err = (*smp->sm_ioctl)
545 (AIOCS_INF_ASV, data,
559 * Get physical interface info
561 if (aip->air_int_intf[0] != '\0') {
563 * Interface specified
565 if ((pip = atm_pifname(aip->air_int_intf))) {
566 err = (*pip->pif_ioctl)(AIOCS_INF_INT,
573 * Want info for every physical interface
575 for (pip = atm_interface_head; pip;
576 pip = pip->pif_next) {
577 err = (*pip->pif_ioctl)(AIOCS_INF_INT,
587 * Get VCC information
589 if (aip->air_vcc_intf[0] != '\0') {
591 * Interface specified
593 if ((pip = atm_pifname(aip->air_vcc_intf))) {
594 if ((smp = pip->pif_sigmgr) != NULL) {
595 err = (*smp->sm_ioctl)(AIOCS_INF_VCC,
597 (caddr_t)pip->pif_siginst);
604 * Want info for every interface
606 for (pip = atm_interface_head; pip;
607 pip = pip->pif_next) {
608 if ((smp = pip->pif_sigmgr) != NULL) {
609 err = (*smp->sm_ioctl)(AIOCS_INF_VCC,
611 (caddr_t)pip->pif_siginst);
621 * Get network interface info
623 if (aip->air_int_intf[0] != '\0') {
625 * Interface specified
627 if ((nip = atm_nifname(aip->air_int_intf))) {
629 err = (*pip->pif_ioctl)(AIOCS_INF_NIF,
636 * Want info for every network interface
638 for (pip = atm_interface_head; pip;
639 pip = pip->pif_next) {
640 for (nip = pip->pif_nif; nip;
641 nip = nip->nif_pnext) {
642 err = (*pip->pif_ioctl)(AIOCS_INF_NIF,
655 * Get physical interface statistics
657 if (aip->air_physt_intf[0] != '\0') {
659 * Interface specified
661 if ((pip = atm_pifname(aip->air_physt_intf))) {
662 err = (*pip->pif_ioctl)(AIOCS_INF_PIS,
669 * Want statistics for every physical interface
671 for (pip = atm_interface_head; pip;
672 pip = pip->pif_next) {
673 err = (*pip->pif_ioctl)(AIOCS_INF_PIS,
683 * Get ATM software version
685 if (len < sizeof(atm_version)) {
689 if ((err = copyout((caddr_t)&atm_version,
691 sizeof(atm_version))) != 0) {
694 aip->air_buf_addr += sizeof(atm_version);
695 aip->air_buf_len -= sizeof(atm_version);
703 * Calculate returned buffer length
705 aip->air_buf_len = len - aip->air_buf_len;