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.11 2005/06/02 22:37:45 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 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(so, cmd, data, ifp, td)
158 * First, figure out which ioctl we're dealing with and
159 * then process it based on the sub-op code
164 struct atmcfgreq *acp = (struct atmcfgreq *)data;
170 switch (acp->acr_opcode) {
174 * Attach signalling manager
176 if ((pip = atm_pifname(acp->acr_att_intf)) == NULL)
178 err = atm_sigmgr_attach(pip, acp->acr_att_proto);
183 * Detach signalling manager
185 if ((pip = atm_pifname(acp->acr_det_intf)) == NULL)
187 err = atm_sigmgr_detach(pip);
197 struct atmaddreq *aap = (struct atmaddreq *)data;
203 switch (aap->aar_opcode) {
207 * Add a PVC definition
211 * Locate requested endpoint service
213 epp = aap->aar_pvc_sap > ENDPT_MAX ? NULL :
214 atm_endpoints[aap->aar_pvc_sap];
216 ATM_RETERR(ENOPROTOOPT);
219 * Let endpoint service handle it from here
221 err = (*epp->ep_ioctl)(AIOCS_ADD_PVC, data, NULL);
228 epp = atm_endpoints[ENDPT_IP];
230 ATM_RETERR(ENOPROTOOPT);
233 * Let IP/ATM endpoint handle this
235 err = (*epp->ep_ioctl) (AIOCS_ADD_ARP, data, NULL);
245 struct atmdelreq *adp = (struct atmdelreq *)data;
253 switch (adp->adr_opcode) {
258 * Delete a PVC or SVC
262 * Locate appropriate sigmgr
264 if ((pip = atm_pifname(adp->adr_pvc_intf)) == NULL)
266 if ((smp = pip->pif_sigmgr) == NULL)
270 * Let sigmgr handle it from here
272 err = (*smp->sm_ioctl)(adp->adr_opcode, data,
273 (caddr_t)pip->pif_siginst);
278 * Delete an ARP mapping
280 epp = atm_endpoints[ENDPT_IP];
282 ATM_RETERR(ENOPROTOOPT);
285 * Let IP/ATM endpoint handle this
287 err = (*epp->ep_ioctl) (AIOCS_DEL_ARP, data, NULL);
297 struct atmsetreq *asp = (struct atmsetreq *)data;
306 switch (asp->asr_opcode) {
310 * Set an ARP server address
314 * Locate appropriate sigmgr
316 if ((nip = atm_nifname(asp->asr_arp_intf)) == NULL)
319 if ((smp = pip->pif_sigmgr) == NULL)
323 * Let sigmgr handle it from here
325 err = (*smp->sm_ioctl)(AIOCS_SET_ASV, data,
331 * Set physical interface MAC/ESI address
335 * Locate physical interface
337 if ((pip = atm_pifname(asp->asr_mac_intf)) == NULL)
341 * Interface must be detached
343 if (pip->pif_sigmgr != NULL)
344 ATM_RETERR(EADDRINUSE);
347 * Just plunk the address into the pif
349 KM_COPY((caddr_t)&asp->asr_mac_addr,
350 (caddr_t)&pip->pif_macaddr,
351 sizeof(struct mac_addr));
356 * Define network interfaces
358 if ((pip = atm_pifname(asp->asr_nif_intf)) == NULL)
362 * Validate interface count - logical interfaces
363 * are differentiated by the atm address selector.
365 if ((asp->asr_nif_cnt <= 0) || (asp->asr_nif_cnt > 256))
369 * Make sure prefix name is unique
371 TAILQ_FOREACH(ifp2, &ifnet, if_link) {
372 if (!strcmp(ifp2->if_dname, asp->asr_nif_pref)) {
374 * If this is for the interface we're
375 * (re-)defining, let it through
377 for (nip = pip->pif_nif; nip;
378 nip = nip->nif_pnext) {
379 if (&nip->nif_if == ifp2)
389 * Let interface handle it from here
391 err = (*pip->pif_ioctl)(AIOCS_SET_NIF, data,
397 * Set interface NSAP Prefix
401 * Locate appropriate sigmgr
403 if ((pip = atm_pifname(asp->asr_prf_intf)) == NULL)
405 if ((smp = pip->pif_sigmgr) == NULL)
409 * Let sigmgr handle it from here
411 err = (*smp->sm_ioctl)(AIOCS_SET_PRF, data,
412 (caddr_t)pip->pif_siginst);
422 err = atm_dgram_info(data);
435 * Process AIOCINFO ioctl system calls
437 * Called from a critical section.
440 * data pointer to AIOCINFO parameter structure
443 * 0 request processed
444 * errno error processing request - reason indicated
451 struct atminfreq *aip = (struct atminfreq *)data;
456 int len = aip->air_buf_len;
459 switch (aip->air_opcode) {
464 * Get vendor interface information
466 if (aip->air_vinfo_intf[0] != '\0') {
468 * Interface specified
470 if ((pip = atm_pifname(aip->air_vinfo_intf))) {
471 err = (*pip->pif_ioctl)(aip->air_opcode, data,
478 * Want info for every interface
480 for (pip = atm_interface_head; pip;
481 pip = pip->pif_next) {
482 err = (*pip->pif_ioctl)(aip->air_opcode, data,
492 * Get IP Map information
494 epp = atm_endpoints[ENDPT_IP];
496 err = (*epp->ep_ioctl) (AIOCS_INF_IPM, data, NULL);
504 * Get ARP table information
506 for (pip = atm_interface_head; pip; pip = pip->pif_next) {
507 if ((smp = pip->pif_sigmgr) != NULL) {
508 err = (*smp->sm_ioctl)(AIOCS_INF_ARP,
509 data, (caddr_t)pip->pif_siginst);
518 * Get ARP server information
520 if (aip->air_asrv_intf[0] != '\0') {
522 * Interface specified
524 if ((nip = atm_nifname(aip->air_asrv_intf))) {
525 if ((smp = nip->nif_pif->pif_sigmgr) != NULL) {
526 err = (*smp->sm_ioctl)(AIOCS_INF_ASV,
534 * Want info for all arp servers
536 for (pip = atm_interface_head; pip;
537 pip = pip->pif_next) {
538 if ((smp = pip->pif_sigmgr) != NULL) {
539 for (nip = pip->pif_nif; nip;
540 nip = nip->nif_pnext) {
541 err = (*smp->sm_ioctl)
542 (AIOCS_INF_ASV, data,
556 * Get physical interface info
558 if (aip->air_int_intf[0] != '\0') {
560 * Interface specified
562 if ((pip = atm_pifname(aip->air_int_intf))) {
563 err = (*pip->pif_ioctl)(AIOCS_INF_INT,
570 * Want info for every physical interface
572 for (pip = atm_interface_head; pip;
573 pip = pip->pif_next) {
574 err = (*pip->pif_ioctl)(AIOCS_INF_INT,
584 * Get VCC information
586 if (aip->air_vcc_intf[0] != '\0') {
588 * Interface specified
590 if ((pip = atm_pifname(aip->air_vcc_intf))) {
591 if ((smp = pip->pif_sigmgr) != NULL) {
592 err = (*smp->sm_ioctl)(AIOCS_INF_VCC,
594 (caddr_t)pip->pif_siginst);
601 * Want info for every interface
603 for (pip = atm_interface_head; pip;
604 pip = pip->pif_next) {
605 if ((smp = pip->pif_sigmgr) != NULL) {
606 err = (*smp->sm_ioctl)(AIOCS_INF_VCC,
608 (caddr_t)pip->pif_siginst);
618 * Get network interface info
620 if (aip->air_int_intf[0] != '\0') {
622 * Interface specified
624 if ((nip = atm_nifname(aip->air_int_intf))) {
626 err = (*pip->pif_ioctl)(AIOCS_INF_NIF,
633 * Want info for every network interface
635 for (pip = atm_interface_head; pip;
636 pip = pip->pif_next) {
637 for (nip = pip->pif_nif; nip;
638 nip = nip->nif_pnext) {
639 err = (*pip->pif_ioctl)(AIOCS_INF_NIF,
652 * Get physical interface statistics
654 if (aip->air_physt_intf[0] != '\0') {
656 * Interface specified
658 if ((pip = atm_pifname(aip->air_physt_intf))) {
659 err = (*pip->pif_ioctl)(AIOCS_INF_PIS,
666 * Want statistics for every physical interface
668 for (pip = atm_interface_head; pip;
669 pip = pip->pif_next) {
670 err = (*pip->pif_ioctl)(AIOCS_INF_PIS,
680 * Get ATM software version
682 if (len < sizeof(atm_version)) {
686 if ((err = copyout((caddr_t)&atm_version,
688 sizeof(atm_version))) != 0) {
691 aip->air_buf_addr += sizeof(atm_version);
692 aip->air_buf_len -= sizeof(atm_version);
700 * Calculate returned buffer length
702 aip->air_buf_len = len - aip->air_buf_len;