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.12 2006/01/14 13:36:39 swildner 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 atm_proto_notsupp1, /* pru_abort */
54 pru_accept_notsupp, /* pru_accept */
55 atm_dgram_attach, /* pru_attach */
56 atm_proto_notsupp2, /* pru_bind */
57 pru_connect_notsupp, /* pru_connect */
58 pru_connect2_notsupp, /* pru_connect2 */
59 atm_dgram_control, /* pru_control */
60 atm_proto_notsupp1, /* pru_detach */
61 atm_proto_notsupp1, /* pru_disconnect */
62 pru_listen_notsupp, /* pru_listen */
63 atm_proto_notsupp3, /* pru_peeraddr */
64 pru_rcvd_notsupp, /* pru_rcvd */
65 pru_rcvoob_notsupp, /* pru_rcvoob */
66 atm_proto_notsupp4, /* pru_send */
67 pru_sense_null, /* pru_sense */
68 atm_proto_notsupp1, /* pru_shutdown */
69 atm_proto_notsupp3, /* pru_sockaddr */
73 * Handy common code macros
80 * Stack queue should have been drained \
82 if (atm_stackq_head != NULL) \
83 panic("atm_usrreq: stack queue not empty"); \
94 * Drain any deferred calls \
101 #define ATM_RETERR(errno) { \
108 * Attach protocol to socket
111 * so pointer to socket
112 * proto protocol identifier
113 * p pointer to process
116 * 0 request processed
117 * errno error processing request - reason indicated
121 atm_dgram_attach(struct socket *so, int proto, struct pru_attach_info *ai)
126 * Nothing to do here for ioctl()-only sockets
133 * Process ioctl system calls
136 * so pointer to socket
138 * data pointer to code specific parameter data area
139 * ifp pointer to ifnet structure if it's an interface ioctl
140 * p pointer to process
143 * 0 request processed
144 * errno error processing request - reason indicated
148 atm_dgram_control(struct socket *so, u_long cmd, caddr_t data,
149 struct ifnet *ifp, struct thread *td)
154 * First, figure out which ioctl we're dealing with and
155 * then process it based on the sub-op code
160 struct atmcfgreq *acp = (struct atmcfgreq *)data;
166 switch (acp->acr_opcode) {
170 * Attach signalling manager
172 if ((pip = atm_pifname(acp->acr_att_intf)) == NULL)
174 err = atm_sigmgr_attach(pip, acp->acr_att_proto);
179 * Detach signalling manager
181 if ((pip = atm_pifname(acp->acr_det_intf)) == NULL)
183 err = atm_sigmgr_detach(pip);
193 struct atmaddreq *aap = (struct atmaddreq *)data;
199 switch (aap->aar_opcode) {
203 * Add a PVC definition
207 * Locate requested endpoint service
209 epp = aap->aar_pvc_sap > ENDPT_MAX ? NULL :
210 atm_endpoints[aap->aar_pvc_sap];
212 ATM_RETERR(ENOPROTOOPT);
215 * Let endpoint service handle it from here
217 err = (*epp->ep_ioctl)(AIOCS_ADD_PVC, data, NULL);
224 epp = atm_endpoints[ENDPT_IP];
226 ATM_RETERR(ENOPROTOOPT);
229 * Let IP/ATM endpoint handle this
231 err = (*epp->ep_ioctl) (AIOCS_ADD_ARP, data, NULL);
241 struct atmdelreq *adp = (struct atmdelreq *)data;
249 switch (adp->adr_opcode) {
254 * Delete a PVC or SVC
258 * Locate appropriate sigmgr
260 if ((pip = atm_pifname(adp->adr_pvc_intf)) == NULL)
262 if ((smp = pip->pif_sigmgr) == NULL)
266 * Let sigmgr handle it from here
268 err = (*smp->sm_ioctl)(adp->adr_opcode, data,
269 (caddr_t)pip->pif_siginst);
274 * Delete an ARP mapping
276 epp = atm_endpoints[ENDPT_IP];
278 ATM_RETERR(ENOPROTOOPT);
281 * Let IP/ATM endpoint handle this
283 err = (*epp->ep_ioctl) (AIOCS_DEL_ARP, data, NULL);
293 struct atmsetreq *asp = (struct atmsetreq *)data;
302 switch (asp->asr_opcode) {
306 * Set an ARP server address
310 * Locate appropriate sigmgr
312 if ((nip = atm_nifname(asp->asr_arp_intf)) == NULL)
315 if ((smp = pip->pif_sigmgr) == NULL)
319 * Let sigmgr handle it from here
321 err = (*smp->sm_ioctl)(AIOCS_SET_ASV, data,
327 * Set physical interface MAC/ESI address
331 * Locate physical interface
333 if ((pip = atm_pifname(asp->asr_mac_intf)) == NULL)
337 * Interface must be detached
339 if (pip->pif_sigmgr != NULL)
340 ATM_RETERR(EADDRINUSE);
343 * Just plunk the address into the pif
345 KM_COPY((caddr_t)&asp->asr_mac_addr,
346 (caddr_t)&pip->pif_macaddr,
347 sizeof(struct mac_addr));
352 * Define network interfaces
354 if ((pip = atm_pifname(asp->asr_nif_intf)) == NULL)
358 * Validate interface count - logical interfaces
359 * are differentiated by the atm address selector.
361 if ((asp->asr_nif_cnt <= 0) || (asp->asr_nif_cnt > 256))
365 * Make sure prefix name is unique
367 TAILQ_FOREACH(ifp2, &ifnet, if_link) {
368 if (!strcmp(ifp2->if_dname, asp->asr_nif_pref)) {
370 * If this is for the interface we're
371 * (re-)defining, let it through
373 for (nip = pip->pif_nif; nip;
374 nip = nip->nif_pnext) {
375 if (&nip->nif_if == ifp2)
385 * Let interface handle it from here
387 err = (*pip->pif_ioctl)(AIOCS_SET_NIF, data,
393 * Set interface NSAP Prefix
397 * Locate appropriate sigmgr
399 if ((pip = atm_pifname(asp->asr_prf_intf)) == NULL)
401 if ((smp = pip->pif_sigmgr) == NULL)
405 * Let sigmgr handle it from here
407 err = (*smp->sm_ioctl)(AIOCS_SET_PRF, data,
408 (caddr_t)pip->pif_siginst);
418 err = atm_dgram_info(data);
431 * Process AIOCINFO ioctl system calls
433 * Called from a critical section.
436 * data pointer to AIOCINFO parameter structure
439 * 0 request processed
440 * errno error processing request - reason indicated
444 atm_dgram_info(caddr_t data)
446 struct atminfreq *aip = (struct atminfreq *)data;
451 int len = aip->air_buf_len;
454 switch (aip->air_opcode) {
459 * Get vendor interface information
461 if (aip->air_vinfo_intf[0] != '\0') {
463 * Interface specified
465 if ((pip = atm_pifname(aip->air_vinfo_intf))) {
466 err = (*pip->pif_ioctl)(aip->air_opcode, data,
473 * Want info for every interface
475 for (pip = atm_interface_head; pip;
476 pip = pip->pif_next) {
477 err = (*pip->pif_ioctl)(aip->air_opcode, data,
487 * Get IP Map information
489 epp = atm_endpoints[ENDPT_IP];
491 err = (*epp->ep_ioctl) (AIOCS_INF_IPM, data, NULL);
499 * Get ARP table information
501 for (pip = atm_interface_head; pip; pip = pip->pif_next) {
502 if ((smp = pip->pif_sigmgr) != NULL) {
503 err = (*smp->sm_ioctl)(AIOCS_INF_ARP,
504 data, (caddr_t)pip->pif_siginst);
513 * Get ARP server information
515 if (aip->air_asrv_intf[0] != '\0') {
517 * Interface specified
519 if ((nip = atm_nifname(aip->air_asrv_intf))) {
520 if ((smp = nip->nif_pif->pif_sigmgr) != NULL) {
521 err = (*smp->sm_ioctl)(AIOCS_INF_ASV,
529 * Want info for all arp servers
531 for (pip = atm_interface_head; pip;
532 pip = pip->pif_next) {
533 if ((smp = pip->pif_sigmgr) != NULL) {
534 for (nip = pip->pif_nif; nip;
535 nip = nip->nif_pnext) {
536 err = (*smp->sm_ioctl)
537 (AIOCS_INF_ASV, data,
551 * Get physical interface info
553 if (aip->air_int_intf[0] != '\0') {
555 * Interface specified
557 if ((pip = atm_pifname(aip->air_int_intf))) {
558 err = (*pip->pif_ioctl)(AIOCS_INF_INT,
565 * Want info for every physical interface
567 for (pip = atm_interface_head; pip;
568 pip = pip->pif_next) {
569 err = (*pip->pif_ioctl)(AIOCS_INF_INT,
579 * Get VCC information
581 if (aip->air_vcc_intf[0] != '\0') {
583 * Interface specified
585 if ((pip = atm_pifname(aip->air_vcc_intf))) {
586 if ((smp = pip->pif_sigmgr) != NULL) {
587 err = (*smp->sm_ioctl)(AIOCS_INF_VCC,
589 (caddr_t)pip->pif_siginst);
596 * Want info for every interface
598 for (pip = atm_interface_head; pip;
599 pip = pip->pif_next) {
600 if ((smp = pip->pif_sigmgr) != NULL) {
601 err = (*smp->sm_ioctl)(AIOCS_INF_VCC,
603 (caddr_t)pip->pif_siginst);
613 * Get network interface info
615 if (aip->air_int_intf[0] != '\0') {
617 * Interface specified
619 if ((nip = atm_nifname(aip->air_int_intf))) {
621 err = (*pip->pif_ioctl)(AIOCS_INF_NIF,
628 * Want info for every network interface
630 for (pip = atm_interface_head; pip;
631 pip = pip->pif_next) {
632 for (nip = pip->pif_nif; nip;
633 nip = nip->nif_pnext) {
634 err = (*pip->pif_ioctl)(AIOCS_INF_NIF,
647 * Get physical interface statistics
649 if (aip->air_physt_intf[0] != '\0') {
651 * Interface specified
653 if ((pip = atm_pifname(aip->air_physt_intf))) {
654 err = (*pip->pif_ioctl)(AIOCS_INF_PIS,
661 * Want statistics for every physical interface
663 for (pip = atm_interface_head; pip;
664 pip = pip->pif_next) {
665 err = (*pip->pif_ioctl)(AIOCS_INF_PIS,
675 * Get ATM software version
677 if (len < sizeof(atm_version)) {
681 if ((err = copyout((caddr_t)&atm_version,
683 sizeof(atm_version))) != 0) {
686 aip->air_buf_addr += sizeof(atm_version);
687 aip->air_buf_len -= sizeof(atm_version);
695 * Calculate returned buffer length
697 aip->air_buf_len = len - aip->air_buf_len;