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.3 2003/06/25 03:56:03 dillon Exp $
34 * ATM DGRAM socket protocol processing
38 #include <netatm/kern_include.h>
43 static int atm_dgram_attach __P((struct socket *, int, struct thread *));
44 static int atm_dgram_control __P((struct socket *, u_long, caddr_t,
45 struct ifnet *, struct thread *));
46 static int atm_dgram_info __P((caddr_t));
50 * New-style socket request routines
52 #if (defined(__FreeBSD__) && (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(so, proto, td)
132 * Nothing to do here for ioctl()-only sockets
139 * Process ioctl system calls
142 * so pointer to socket
144 * data pointer to code specific parameter data area
145 * ifp pointer to ifnet structure if it's an interface ioctl
146 * p pointer to process
149 * 0 request processed
150 * errno error processing request - reason indicated
154 atm_dgram_control(so, cmd, data, ifp, td)
164 * First, figure out which ioctl we're dealing with and
165 * then process it based on the sub-op code
170 struct atmcfgreq *acp = (struct atmcfgreq *)data;
176 switch (acp->acr_opcode) {
180 * Attach signalling manager
182 if ((pip = atm_pifname(acp->acr_att_intf)) == NULL)
184 err = atm_sigmgr_attach(pip, acp->acr_att_proto);
189 * Detach signalling manager
191 if ((pip = atm_pifname(acp->acr_det_intf)) == NULL)
193 err = atm_sigmgr_detach(pip);
203 struct atmaddreq *aap = (struct atmaddreq *)data;
209 switch (aap->aar_opcode) {
213 * Add a PVC definition
217 * Locate requested endpoint service
219 epp = aap->aar_pvc_sap > ENDPT_MAX ? NULL :
220 atm_endpoints[aap->aar_pvc_sap];
222 ATM_RETERR(ENOPROTOOPT);
225 * Let endpoint service handle it from here
227 err = (*epp->ep_ioctl)(AIOCS_ADD_PVC, data, NULL);
234 epp = atm_endpoints[ENDPT_IP];
236 ATM_RETERR(ENOPROTOOPT);
239 * Let IP/ATM endpoint handle this
241 err = (*epp->ep_ioctl) (AIOCS_ADD_ARP, data, NULL);
251 struct atmdelreq *adp = (struct atmdelreq *)data;
259 switch (adp->adr_opcode) {
264 * Delete a PVC or SVC
268 * Locate appropriate sigmgr
270 if ((pip = atm_pifname(adp->adr_pvc_intf)) == NULL)
272 if ((smp = pip->pif_sigmgr) == NULL)
276 * Let sigmgr handle it from here
278 err = (*smp->sm_ioctl)(adp->adr_opcode, data,
279 (caddr_t)pip->pif_siginst);
284 * Delete an ARP mapping
286 epp = atm_endpoints[ENDPT_IP];
288 ATM_RETERR(ENOPROTOOPT);
291 * Let IP/ATM endpoint handle this
293 err = (*epp->ep_ioctl) (AIOCS_DEL_ARP, data, NULL);
303 struct atmsetreq *asp = (struct atmsetreq *)data;
312 switch (asp->asr_opcode) {
316 * Set an ARP server address
320 * Locate appropriate sigmgr
322 if ((nip = atm_nifname(asp->asr_arp_intf)) == NULL)
325 if ((smp = pip->pif_sigmgr) == NULL)
329 * Let sigmgr handle it from here
331 err = (*smp->sm_ioctl)(AIOCS_SET_ASV, data,
337 * Set physical interface MAC/ESI address
341 * Locate physical interface
343 if ((pip = atm_pifname(asp->asr_mac_intf)) == NULL)
347 * Interface must be detached
349 if (pip->pif_sigmgr != NULL)
350 ATM_RETERR(EADDRINUSE);
353 * Just plunk the address into the pif
355 KM_COPY((caddr_t)&asp->asr_mac_addr,
356 (caddr_t)&pip->pif_macaddr,
357 sizeof(struct mac_addr));
362 * Define network interfaces
364 if ((pip = atm_pifname(asp->asr_nif_intf)) == NULL)
368 * Validate interface count - logical interfaces
369 * are differentiated by the atm address selector.
371 if ((asp->asr_nif_cnt <= 0) || (asp->asr_nif_cnt > 256))
375 * Make sure prefix name is unique
377 TAILQ_FOREACH(ifp2, &ifnet, if_link) {
378 if (!strcmp(ifp2->if_name, asp->asr_nif_pref)) {
380 * If this is for the interface we're
381 * (re-)defining, let it through
383 for (nip = pip->pif_nif; nip;
384 nip = nip->nif_pnext) {
385 if (&nip->nif_if == ifp2)
395 * Let interface handle it from here
397 err = (*pip->pif_ioctl)(AIOCS_SET_NIF, data,
403 * Set interface NSAP Prefix
407 * Locate appropriate sigmgr
409 if ((pip = atm_pifname(asp->asr_prf_intf)) == NULL)
411 if ((smp = pip->pif_sigmgr) == NULL)
415 * Let sigmgr handle it from here
417 err = (*smp->sm_ioctl)(AIOCS_SET_PRF, data,
418 (caddr_t)pip->pif_siginst);
428 err = atm_dgram_info(data);
441 * Process AIOCINFO ioctl system calls
446 * data pointer to AIOCINFO parameter structure
449 * 0 request processed
450 * errno error processing request - reason indicated
457 struct atminfreq *aip = (struct atminfreq *)data;
462 int len = aip->air_buf_len;
465 switch (aip->air_opcode) {
470 * Get vendor interface information
472 if (aip->air_vinfo_intf[0] != '\0') {
474 * Interface specified
476 if ((pip = atm_pifname(aip->air_vinfo_intf))) {
477 err = (*pip->pif_ioctl)(aip->air_opcode, data,
484 * Want info for every interface
486 for (pip = atm_interface_head; pip;
487 pip = pip->pif_next) {
488 err = (*pip->pif_ioctl)(aip->air_opcode, data,
498 * Get IP Map information
500 epp = atm_endpoints[ENDPT_IP];
502 err = (*epp->ep_ioctl) (AIOCS_INF_IPM, data, NULL);
510 * Get ARP table information
512 for (pip = atm_interface_head; pip; pip = pip->pif_next) {
513 if ((smp = pip->pif_sigmgr) != NULL) {
514 err = (*smp->sm_ioctl)(AIOCS_INF_ARP,
515 data, (caddr_t)pip->pif_siginst);
524 * Get ARP server information
526 if (aip->air_asrv_intf[0] != '\0') {
528 * Interface specified
530 if ((nip = atm_nifname(aip->air_asrv_intf))) {
531 if ((smp = nip->nif_pif->pif_sigmgr) != NULL) {
532 err = (*smp->sm_ioctl)(AIOCS_INF_ASV,
540 * Want info for all arp servers
542 for (pip = atm_interface_head; pip;
543 pip = pip->pif_next) {
544 if ((smp = pip->pif_sigmgr) != NULL) {
545 for (nip = pip->pif_nif; nip;
546 nip = nip->nif_pnext) {
547 err = (*smp->sm_ioctl)
548 (AIOCS_INF_ASV, data,
562 * Get physical interface info
564 if (aip->air_int_intf[0] != '\0') {
566 * Interface specified
568 if ((pip = atm_pifname(aip->air_int_intf))) {
569 err = (*pip->pif_ioctl)(AIOCS_INF_INT,
576 * Want info for every physical interface
578 for (pip = atm_interface_head; pip;
579 pip = pip->pif_next) {
580 err = (*pip->pif_ioctl)(AIOCS_INF_INT,
590 * Get VCC information
592 if (aip->air_vcc_intf[0] != '\0') {
594 * Interface specified
596 if ((pip = atm_pifname(aip->air_vcc_intf))) {
597 if ((smp = pip->pif_sigmgr) != NULL) {
598 err = (*smp->sm_ioctl)(AIOCS_INF_VCC,
600 (caddr_t)pip->pif_siginst);
607 * Want info for every interface
609 for (pip = atm_interface_head; pip;
610 pip = pip->pif_next) {
611 if ((smp = pip->pif_sigmgr) != NULL) {
612 err = (*smp->sm_ioctl)(AIOCS_INF_VCC,
614 (caddr_t)pip->pif_siginst);
624 * Get network interface info
626 if (aip->air_int_intf[0] != '\0') {
628 * Interface specified
630 if ((nip = atm_nifname(aip->air_int_intf))) {
632 err = (*pip->pif_ioctl)(AIOCS_INF_NIF,
639 * Want info for every network interface
641 for (pip = atm_interface_head; pip;
642 pip = pip->pif_next) {
643 for (nip = pip->pif_nif; nip;
644 nip = nip->nif_pnext) {
645 err = (*pip->pif_ioctl)(AIOCS_INF_NIF,
658 * Get physical interface statistics
660 if (aip->air_physt_intf[0] != '\0') {
662 * Interface specified
664 if ((pip = atm_pifname(aip->air_physt_intf))) {
665 err = (*pip->pif_ioctl)(AIOCS_INF_PIS,
672 * Want statistics for every physical interface
674 for (pip = atm_interface_head; pip;
675 pip = pip->pif_next) {
676 err = (*pip->pif_ioctl)(AIOCS_INF_PIS,
686 * Get ATM software version
688 if (len < sizeof(atm_version)) {
692 if ((err = copyout((caddr_t)&atm_version,
694 sizeof(atm_version))) != 0) {
697 aip->air_buf_addr += sizeof(atm_version);
698 aip->air_buf_len -= sizeof(atm_version);
706 * Calculate returned buffer length
708 aip->air_buf_len = len - aip->air_buf_len;