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 * @(#) $Id: atm_usrreq.c,v 1.4 1999/01/27 22:42:20 dillon Exp $
34 * ATM DGRAM socket protocol processing
38 #include <netatm/kern_include.h>
41 __RCSID("@(#) $Id: atm_usrreq.c,v 1.4 1999/01/27 22:42:20 dillon Exp $");
48 static int atm_dgram_attach __P((struct socket *, int, struct proc *));
49 static int atm_dgram_control __P((struct socket *, u_long, caddr_t,
50 struct ifnet *, struct proc *));
51 static int atm_dgram_info __P((caddr_t));
55 * New-style socket request routines
57 #if (defined(__FreeBSD__) && (BSD >= 199506))
58 struct pr_usrreqs atm_dgram_usrreqs = {
59 atm_proto_notsupp1, /* pru_abort */
60 pru_accept_notsupp, /* pru_accept */
61 atm_dgram_attach, /* pru_attach */
62 atm_proto_notsupp2, /* pru_bind */
63 pru_connect_notsupp, /* pru_connect */
64 pru_connect2_notsupp, /* pru_connect2 */
65 atm_dgram_control, /* pru_control */
66 atm_proto_notsupp1, /* pru_detach */
67 atm_proto_notsupp1, /* pru_disconnect */
68 pru_listen_notsupp, /* pru_listen */
69 atm_proto_notsupp3, /* pru_peeraddr */
70 pru_rcvd_notsupp, /* pru_rcvd */
71 pru_rcvoob_notsupp, /* pru_rcvoob */
72 atm_proto_notsupp4, /* pru_send */
73 pru_sense_null, /* pru_sense */
74 atm_proto_notsupp1, /* pru_shutdown */
75 atm_proto_notsupp3, /* pru_sockaddr */
81 * Handy common code macros
88 * Stack queue should have been drained \
90 if (atm_stackq_head != NULL) \
91 panic("atm_usrreq: stack queue not empty"); \
100 #define ATM_OUTRO() \
102 * Drain any deferred calls \
109 #define ATM_RETERR(errno) { \
116 * Attach protocol to socket
119 * so pointer to socket
120 * proto protocol identifier
121 * p pointer to process
124 * 0 request processed
125 * errno error processing request - reason indicated
129 atm_dgram_attach(so, proto, p)
137 * Nothing to do here for ioctl()-only sockets
144 * Process ioctl system calls
147 * so pointer to socket
149 * data pointer to code specific parameter data area
150 * ifp pointer to ifnet structure if it's an interface ioctl
151 * p pointer to process
154 * 0 request processed
155 * errno error processing request - reason indicated
159 atm_dgram_control(so, cmd, data, ifp, p)
169 * First, figure out which ioctl we're dealing with and
170 * then process it based on the sub-op code
175 struct atmcfgreq *acp = (struct atmcfgreq *)data;
178 if (p && (suser(p) != 0))
181 switch (acp->acr_opcode) {
185 * Attach signalling manager
187 if ((pip = atm_pifname(acp->acr_att_intf)) == NULL)
189 err = atm_sigmgr_attach(pip, acp->acr_att_proto);
194 * Detach signalling manager
196 if ((pip = atm_pifname(acp->acr_det_intf)) == NULL)
198 err = atm_sigmgr_detach(pip);
208 struct atmaddreq *aap = (struct atmaddreq *)data;
211 if (p && (suser(p) != 0))
214 switch (aap->aar_opcode) {
218 * Add a PVC definition
222 * Locate requested endpoint service
224 epp = aap->aar_pvc_sap > ENDPT_MAX ? NULL :
225 atm_endpoints[aap->aar_pvc_sap];
227 ATM_RETERR(ENOPROTOOPT);
230 * Let endpoint service handle it from here
232 err = (*epp->ep_ioctl)(AIOCS_ADD_PVC, data, NULL);
239 epp = atm_endpoints[ENDPT_IP];
241 ATM_RETERR(ENOPROTOOPT);
244 * Let IP/ATM endpoint handle this
246 err = (*epp->ep_ioctl) (AIOCS_ADD_ARP, data, NULL);
256 struct atmdelreq *adp = (struct atmdelreq *)data;
261 if (p && (suser(p) != 0))
264 switch (adp->adr_opcode) {
269 * Delete a PVC or SVC
273 * Locate appropriate sigmgr
275 if ((pip = atm_pifname(adp->adr_pvc_intf)) == NULL)
277 if ((smp = pip->pif_sigmgr) == NULL)
281 * Let sigmgr handle it from here
283 err = (*smp->sm_ioctl)(adp->adr_opcode, data,
284 (caddr_t)pip->pif_siginst);
289 * Delete an ARP mapping
291 epp = atm_endpoints[ENDPT_IP];
293 ATM_RETERR(ENOPROTOOPT);
296 * Let IP/ATM endpoint handle this
298 err = (*epp->ep_ioctl) (AIOCS_DEL_ARP, data, NULL);
308 struct atmsetreq *asp = (struct atmsetreq *)data;
314 if (p && (suser(p) != 0))
317 switch (asp->asr_opcode) {
321 * Set an ARP server address
325 * Locate appropriate sigmgr
327 if ((nip = atm_nifname(asp->asr_arp_intf)) == NULL)
330 if ((smp = pip->pif_sigmgr) == NULL)
334 * Let sigmgr handle it from here
336 err = (*smp->sm_ioctl)(AIOCS_SET_ASV, data,
342 * Set physical interface MAC/ESI address
346 * Locate physical interface
348 if ((pip = atm_pifname(asp->asr_mac_intf)) == NULL)
352 * Interface must be detached
354 if (pip->pif_sigmgr != NULL)
355 ATM_RETERR(EADDRINUSE);
358 * Just plunk the address into the pif
360 KM_COPY((caddr_t)&asp->asr_mac_addr,
361 (caddr_t)&pip->pif_macaddr,
362 sizeof(struct mac_addr));
367 * Define network interfaces
369 if ((pip = atm_pifname(asp->asr_nif_intf)) == NULL)
373 * Validate interface count - logical interfaces
374 * are differentiated by the atm address selector.
376 if ((asp->asr_nif_cnt <= 0) || (asp->asr_nif_cnt > 256))
380 * Make sure prefix name is unique
382 TAILQ_FOREACH(ifp2, &ifnet, if_link) {
383 if (!strcmp(ifp2->if_name, asp->asr_nif_pref)) {
385 * If this is for the interface we're
386 * (re-)defining, let it through
388 for (nip = pip->pif_nif; nip;
389 nip = nip->nif_pnext) {
390 if (&nip->nif_if == ifp2)
400 * Let interface handle it from here
402 err = (*pip->pif_ioctl)(AIOCS_SET_NIF, data,
408 * Set interface NSAP Prefix
412 * Locate appropriate sigmgr
414 if ((pip = atm_pifname(asp->asr_prf_intf)) == NULL)
416 if ((smp = pip->pif_sigmgr) == NULL)
420 * Let sigmgr handle it from here
422 err = (*smp->sm_ioctl)(AIOCS_SET_PRF, data,
423 (caddr_t)pip->pif_siginst);
433 err = atm_dgram_info(data);
446 * Process AIOCINFO ioctl system calls
451 * data pointer to AIOCINFO parameter structure
454 * 0 request processed
455 * errno error processing request - reason indicated
462 struct atminfreq *aip = (struct atminfreq *)data;
467 int len = aip->air_buf_len;
470 switch (aip->air_opcode) {
475 * Get vendor interface information
477 if (aip->air_vinfo_intf[0] != '\0') {
479 * Interface specified
481 if ((pip = atm_pifname(aip->air_vinfo_intf))) {
482 err = (*pip->pif_ioctl)(aip->air_opcode, data,
489 * Want info for every interface
491 for (pip = atm_interface_head; pip;
492 pip = pip->pif_next) {
493 err = (*pip->pif_ioctl)(aip->air_opcode, data,
503 * Get IP Map information
505 epp = atm_endpoints[ENDPT_IP];
507 err = (*epp->ep_ioctl) (AIOCS_INF_IPM, data, NULL);
515 * Get ARP table information
517 for (pip = atm_interface_head; pip; pip = pip->pif_next) {
518 if ((smp = pip->pif_sigmgr) != NULL) {
519 err = (*smp->sm_ioctl)(AIOCS_INF_ARP,
520 data, (caddr_t)pip->pif_siginst);
529 * Get ARP server information
531 if (aip->air_asrv_intf[0] != '\0') {
533 * Interface specified
535 if ((nip = atm_nifname(aip->air_asrv_intf))) {
536 if ((smp = nip->nif_pif->pif_sigmgr) != NULL) {
537 err = (*smp->sm_ioctl)(AIOCS_INF_ASV,
545 * Want info for all arp servers
547 for (pip = atm_interface_head; pip;
548 pip = pip->pif_next) {
549 if ((smp = pip->pif_sigmgr) != NULL) {
550 for (nip = pip->pif_nif; nip;
551 nip = nip->nif_pnext) {
552 err = (*smp->sm_ioctl)
553 (AIOCS_INF_ASV, data,
567 * Get physical interface info
569 if (aip->air_int_intf[0] != '\0') {
571 * Interface specified
573 if ((pip = atm_pifname(aip->air_int_intf))) {
574 err = (*pip->pif_ioctl)(AIOCS_INF_INT,
581 * Want info for every physical interface
583 for (pip = atm_interface_head; pip;
584 pip = pip->pif_next) {
585 err = (*pip->pif_ioctl)(AIOCS_INF_INT,
595 * Get VCC information
597 if (aip->air_vcc_intf[0] != '\0') {
599 * Interface specified
601 if ((pip = atm_pifname(aip->air_vcc_intf))) {
602 if ((smp = pip->pif_sigmgr) != NULL) {
603 err = (*smp->sm_ioctl)(AIOCS_INF_VCC,
605 (caddr_t)pip->pif_siginst);
612 * Want info for every interface
614 for (pip = atm_interface_head; pip;
615 pip = pip->pif_next) {
616 if ((smp = pip->pif_sigmgr) != NULL) {
617 err = (*smp->sm_ioctl)(AIOCS_INF_VCC,
619 (caddr_t)pip->pif_siginst);
629 * Get network interface info
631 if (aip->air_int_intf[0] != '\0') {
633 * Interface specified
635 if ((nip = atm_nifname(aip->air_int_intf))) {
637 err = (*pip->pif_ioctl)(AIOCS_INF_NIF,
644 * Want info for every network interface
646 for (pip = atm_interface_head; pip;
647 pip = pip->pif_next) {
648 for (nip = pip->pif_nif; nip;
649 nip = nip->nif_pnext) {
650 err = (*pip->pif_ioctl)(AIOCS_INF_NIF,
663 * Get physical interface statistics
665 if (aip->air_physt_intf[0] != '\0') {
667 * Interface specified
669 if ((pip = atm_pifname(aip->air_physt_intf))) {
670 err = (*pip->pif_ioctl)(AIOCS_INF_PIS,
677 * Want statistics for every physical interface
679 for (pip = atm_interface_head; pip;
680 pip = pip->pif_next) {
681 err = (*pip->pif_ioctl)(AIOCS_INF_PIS,
691 * Get ATM software version
693 if (len < sizeof(atm_version)) {
697 if ((err = copyout((caddr_t)&atm_version,
699 sizeof(atm_version))) != 0) {
702 aip->air_buf_addr += sizeof(atm_version);
703 aip->air_buf_len -= sizeof(atm_version);
711 * Calculate returned buffer length
713 aip->air_buf_len = len - aip->air_buf_len;