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 void atm_dgram_attach(netmsg_t msg);
44 static void atm_dgram_control(netmsg_t msg);
45 static int atm_dgram_info (caddr_t);
48 * New-style socket request routines
50 struct pr_usrreqs atm_dgram_usrreqs = {
51 .pru_abort = pr_generic_notsupp,
52 .pru_accept = pr_generic_notsupp,
53 .pru_attach = atm_dgram_attach,
54 .pru_bind = pr_generic_notsupp,
55 .pru_connect = pr_generic_notsupp,
56 .pru_connect2 = pr_generic_notsupp,
57 .pru_control = atm_dgram_control,
58 .pru_detach = pr_generic_notsupp,
59 .pru_disconnect = pr_generic_notsupp,
60 .pru_listen = pr_generic_notsupp,
61 .pru_peeraddr = pr_generic_notsupp,
62 .pru_rcvd = pr_generic_notsupp,
63 .pru_rcvoob = pr_generic_notsupp,
64 .pru_send = pr_generic_notsupp,
65 .pru_sense = pru_sense_null,
66 .pru_shutdown = pr_generic_notsupp,
67 .pru_sockaddr = pr_generic_notsupp,
69 .pru_soreceive = soreceive
73 * Handy common code macros
81 * Stack queue should have been drained \
83 if (atm_stackq_head != NULL) \
84 panic("atm_usrreq: stack queue not empty"); \
99 * Drain any deferred calls \
103 lwkt_replymsg(&msg->lmsg, error); \
109 * Attach protocol to socket
112 * so pointer to socket
113 * proto protocol identifier
114 * p pointer to process
117 * 0 request processed
118 * errno error processing request - reason indicated
122 atm_dgram_attach(netmsg_t msg)
129 * Nothing to do here for ioctl()-only sockets
138 * Process ioctl system calls
141 * so pointer to socket
143 * data pointer to code specific parameter data area
144 * ifp pointer to ifnet structure if it's an interface ioctl
145 * p pointer to process
148 * 0 request processed
149 * errno error processing request - reason indicated
153 atm_dgram_control(netmsg_t msg)
155 u_long cmd = msg->control.nm_cmd;
156 caddr_t data = msg->control.nm_data;
157 struct thread *td = msg->control.nm_td;
164 * First, figure out which ioctl we're dealing with and
165 * then process it based on the sub-op code
169 struct atmcfgreq *acp = (struct atmcfgreq *)data;
172 if (priv_check(td, PRIV_ROOT)) {
177 switch (acp->acr_opcode) {
181 * Attach signalling manager
183 if ((pip = atm_pifname(acp->acr_att_intf)) == NULL) {
187 error = atm_sigmgr_attach(pip, acp->acr_att_proto);
192 * Detach signalling manager
194 if ((pip = atm_pifname(acp->acr_det_intf)) == NULL) {
198 error = atm_sigmgr_detach(pip);
209 struct atmaddreq *aap = (struct atmaddreq *)data;
212 if (priv_check(td, PRIV_ROOT)) {
217 switch (aap->aar_opcode) {
221 * Add a PVC definition
225 * Locate requested endpoint service
227 epp = aap->aar_pvc_sap > ENDPT_MAX ? NULL :
228 atm_endpoints[aap->aar_pvc_sap];
235 * Let endpoint service handle it from here
237 error = (*epp->ep_ioctl)(AIOCS_ADD_PVC, data, NULL);
244 epp = atm_endpoints[ENDPT_IP];
251 * Let IP/ATM endpoint handle this
253 error = (*epp->ep_ioctl) (AIOCS_ADD_ARP, data, NULL);
263 struct atmdelreq *adp = (struct atmdelreq *)data;
268 if (priv_check(td, PRIV_ROOT)) {
273 switch (adp->adr_opcode) {
278 * Delete a PVC or SVC
282 * Locate appropriate sigmgr
284 if ((pip = atm_pifname(adp->adr_pvc_intf)) == NULL) {
288 if ((smp = pip->pif_sigmgr) == NULL) {
294 * Let sigmgr handle it from here
296 error = (*smp->sm_ioctl)(adp->adr_opcode, data,
297 (caddr_t)pip->pif_siginst);
302 * Delete an ARP mapping
304 epp = atm_endpoints[ENDPT_IP];
311 * Let IP/ATM endpoint handle this
313 error = (*epp->ep_ioctl) (AIOCS_DEL_ARP, data, NULL);
323 struct atmsetreq *asp = (struct atmsetreq *)data;
329 if (priv_check(td, PRIV_ROOT)) {
334 switch (asp->asr_opcode) {
338 * Set an ARP server address
342 * Locate appropriate sigmgr
344 if ((nip = atm_nifname(asp->asr_arp_intf)) == NULL) {
349 if ((smp = pip->pif_sigmgr) == NULL) {
355 * Let sigmgr handle it from here
357 error = (*smp->sm_ioctl)(AIOCS_SET_ASV, data,
363 * Set physical interface MAC/ESI address
367 * Locate physical interface
369 if ((pip = atm_pifname(asp->asr_mac_intf)) == NULL) {
375 * Interface must be detached
377 if (pip->pif_sigmgr != NULL) {
383 * Just plunk the address into the pif
385 KM_COPY((caddr_t)&asp->asr_mac_addr,
386 (caddr_t)&pip->pif_macaddr,
387 sizeof(struct mac_addr));
392 * Define network interfaces
394 if ((pip = atm_pifname(asp->asr_nif_intf)) == NULL) {
400 * Validate interface count - logical interfaces
401 * are differentiated by the atm address selector.
403 if ((asp->asr_nif_cnt <= 0) ||
404 (asp->asr_nif_cnt > 256)) {
410 * Make sure prefix name is unique
412 TAILQ_FOREACH(ifp2, &ifnet, if_link) {
413 if (!strcmp(ifp2->if_dname, asp->asr_nif_pref)) {
415 * If this is for the interface we're
416 * (re-)defining, let it through
418 for (nip = pip->pif_nif; nip;
419 nip = nip->nif_pnext) {
420 if (&nip->nif_if == ifp2)
431 * Let interface handle it from here
433 error = (*pip->pif_ioctl)(AIOCS_SET_NIF, data,
439 * Set interface NSAP Prefix
443 * Locate appropriate sigmgr
445 if ((pip = atm_pifname(asp->asr_prf_intf)) == NULL) {
449 if ((smp = pip->pif_sigmgr) == NULL) {
455 * Let sigmgr handle it from here
457 error = (*smp->sm_ioctl)(AIOCS_SET_PRF, data,
458 (caddr_t)pip->pif_siginst);
469 error = atm_dgram_info(data);
481 * Process AIOCINFO ioctl system calls
483 * Called from a critical section.
486 * data pointer to AIOCINFO parameter structure
489 * 0 request processed
490 * errno error processing request - reason indicated
494 atm_dgram_info(caddr_t data)
496 struct atminfreq *aip = (struct atminfreq *)data;
501 int len = aip->air_buf_len;
504 switch (aip->air_opcode) {
509 * Get vendor interface information
511 if (aip->air_vinfo_intf[0] != '\0') {
513 * Interface specified
515 if ((pip = atm_pifname(aip->air_vinfo_intf))) {
516 err = (*pip->pif_ioctl)(aip->air_opcode, data,
523 * Want info for every interface
525 for (pip = atm_interface_head; pip;
526 pip = pip->pif_next) {
527 err = (*pip->pif_ioctl)(aip->air_opcode, data,
537 * Get IP Map information
539 epp = atm_endpoints[ENDPT_IP];
541 err = (*epp->ep_ioctl) (AIOCS_INF_IPM, data, NULL);
549 * Get ARP table information
551 for (pip = atm_interface_head; pip; pip = pip->pif_next) {
552 if ((smp = pip->pif_sigmgr) != NULL) {
553 err = (*smp->sm_ioctl)(AIOCS_INF_ARP,
554 data, (caddr_t)pip->pif_siginst);
563 * Get ARP server information
565 if (aip->air_asrv_intf[0] != '\0') {
567 * Interface specified
569 if ((nip = atm_nifname(aip->air_asrv_intf))) {
570 if ((smp = nip->nif_pif->pif_sigmgr) != NULL) {
571 err = (*smp->sm_ioctl)(AIOCS_INF_ASV,
579 * Want info for all arp servers
581 for (pip = atm_interface_head; pip;
582 pip = pip->pif_next) {
583 if ((smp = pip->pif_sigmgr) != NULL) {
584 for (nip = pip->pif_nif; nip;
585 nip = nip->nif_pnext) {
586 err = (*smp->sm_ioctl)
587 (AIOCS_INF_ASV, data,
601 * Get physical interface info
603 if (aip->air_int_intf[0] != '\0') {
605 * Interface specified
607 if ((pip = atm_pifname(aip->air_int_intf))) {
608 err = (*pip->pif_ioctl)(AIOCS_INF_INT,
615 * Want info for every physical interface
617 for (pip = atm_interface_head; pip;
618 pip = pip->pif_next) {
619 err = (*pip->pif_ioctl)(AIOCS_INF_INT,
629 * Get VCC information
631 if (aip->air_vcc_intf[0] != '\0') {
633 * Interface specified
635 if ((pip = atm_pifname(aip->air_vcc_intf))) {
636 if ((smp = pip->pif_sigmgr) != NULL) {
637 err = (*smp->sm_ioctl)(AIOCS_INF_VCC,
639 (caddr_t)pip->pif_siginst);
646 * Want info for every interface
648 for (pip = atm_interface_head; pip;
649 pip = pip->pif_next) {
650 if ((smp = pip->pif_sigmgr) != NULL) {
651 err = (*smp->sm_ioctl)(AIOCS_INF_VCC,
653 (caddr_t)pip->pif_siginst);
663 * Get network interface info
665 if (aip->air_int_intf[0] != '\0') {
667 * Interface specified
669 if ((nip = atm_nifname(aip->air_int_intf))) {
671 err = (*pip->pif_ioctl)(AIOCS_INF_NIF,
678 * Want info for every network interface
680 for (pip = atm_interface_head; pip;
681 pip = pip->pif_next) {
682 for (nip = pip->pif_nif; nip;
683 nip = nip->nif_pnext) {
684 err = (*pip->pif_ioctl)(AIOCS_INF_NIF,
697 * Get physical interface statistics
699 if (aip->air_physt_intf[0] != '\0') {
701 * Interface specified
703 if ((pip = atm_pifname(aip->air_physt_intf))) {
704 err = (*pip->pif_ioctl)(AIOCS_INF_PIS,
711 * Want statistics for every physical interface
713 for (pip = atm_interface_head; pip;
714 pip = pip->pif_next) {
715 err = (*pip->pif_ioctl)(AIOCS_INF_PIS,
725 * Get ATM software version
727 if (len < sizeof(atm_version)) {
731 if ((err = copyout((caddr_t)&atm_version,
733 sizeof(atm_version))) != 0) {
736 aip->air_buf_addr += sizeof(atm_version);
737 aip->air_buf_len -= sizeof(atm_version);
745 * Calculate returned buffer length
747 aip->air_buf_len = len - aip->air_buf_len;