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/ipatm/ipatm_usrreq.c,v 1.5.2.1 2003/02/15 09:25:13 phk Exp $
27 * @(#) $DragonFly: src/sys/netproto/atm/ipatm/ipatm_usrreq.c,v 1.7 2006/01/14 13:36:39 swildner Exp $
34 * Process user requests
38 #include <netproto/atm/kern_include.h>
40 #include "ipatm_var.h"
41 #include "ipatm_serv.h"
44 * Process IP PF_ATM ioctls
49 * code PF_ATM sub-operation code
50 * data pointer to code specific parameter data area
51 * arg1 pointer to code specific argument
55 * errno error processing request - reason indicated
59 ipatm_ioctl(int code, caddr_t data, caddr_t arg1)
61 struct atmaddreq *aap;
62 struct atmdelreq *adp;
63 struct atminfreq *aip;
64 struct air_ip_vcc_rsp aivr;
81 aap = (struct atmaddreq *)data;
84 * Find the IP network interface
86 if ((nip = atm_nifname(aap->aar_pvc_intf)) == NULL) {
91 for (inp = ipatm_nif_head; inp; inp = inp->inf_next) {
92 if (inp->inf_nif == nip)
101 * Validate PVC params
103 if (aap->aar_pvc_aal == ATM_AAL5) {
104 if ((aap->aar_pvc_encaps != ATM_ENC_LLC) &&
105 (aap->aar_pvc_encaps != ATM_ENC_NULL)) {
109 } else if (aap->aar_pvc_aal == ATM_AAL3_4) {
110 if (aap->aar_pvc_encaps != ATM_ENC_NULL) {
119 if (aap->aar_pvc_flags & PVC_DYN) {
121 * For dynamic PVC destination addressing, the
122 * network interface must have support for this
124 if ((inp->inf_serv == NULL) ||
125 (inp->inf_serv->is_arp_pvcopen == NULL)) {
130 u_long dst = ((struct sockaddr_in *)&aap->aar_pvc_dst)
133 if (dst == INADDR_ANY) {
140 * Build connection request
143 pv.ipp_vpi = aap->aar_pvc_vpi;
144 pv.ipp_vci = aap->aar_pvc_vci;
145 pv.ipp_encaps = aap->aar_pvc_encaps;
146 pv.ipp_aal = aap->aar_pvc_aal;
147 if (aap->aar_pvc_flags & PVC_DYN) {
148 pv.ipp_dst.sin_addr.s_addr = INADDR_ANY;
150 pv.ipp_dst = *(struct sockaddr_in *)&aap->aar_pvc_dst;
155 err = ipatm_openpvc(&pv, &ivp);
162 aap = (struct atmaddreq *)data;
165 * Validate IP address
167 if (aap->aar_arp_dst.sa_family != AF_INET) {
171 ip = SATOSIN(&aap->aar_arp_dst)->sin_addr;
173 if (aap->aar_arp_intf[0] == '\0') {
175 * Find the IP network interface associated with
176 * the supplied IP address
178 for (inp = ipatm_nif_head; inp; inp = inp->inf_next) {
179 if (ipatm_chknif(ip, inp) == 0)
188 * Find the specified IP network interface
190 if ((nip = atm_nifname(aap->aar_arp_intf)) == NULL) {
194 for (inp = ipatm_nif_head; inp; inp = inp->inf_next) {
195 if (inp->inf_nif == nip)
204 if ((ip.s_addr == INADDR_ANY) ||
205 in_broadcast(ip, &inp->inf_nif->nif_if) ||
206 IN_MULTICAST(ntohl(ip.s_addr))) {
212 * Notify the responsible ARP service
214 * XXX: if there is one. No idea how this happens, but at
215 * least don't panic on a NULL pointer if it does.
217 if (inp->inf_serv == NULL) {
221 err = (*inp->inf_serv->is_ioctl)(code, data, inp->inf_isintf);
226 * Delete an ARP mapping
228 adp = (struct atmdelreq *)data;
231 * Validate IP address
233 if (adp->adr_arp_dst.sa_family != AF_INET) {
237 ip = SATOSIN(&adp->adr_arp_dst)->sin_addr;
239 if (adp->adr_arp_intf[0] == '\0') {
241 * Find the IP network interface associated with
242 * the supplied IP address
244 for (inp = ipatm_nif_head; inp; inp = inp->inf_next) {
245 if (ipatm_chknif(ip, inp) == 0)
254 * Find the specified IP network interface
256 if ((nip = atm_nifname(adp->adr_arp_intf)) == NULL) {
260 for (inp = ipatm_nif_head; inp; inp = inp->inf_next) {
261 if (inp->inf_nif == nip)
270 if ((ip.s_addr == INADDR_ANY) ||
271 in_broadcast(ip, &inp->inf_nif->nif_if) ||
272 IN_MULTICAST(ntohl(ip.s_addr))) {
278 * Notify the responsible ARP service
280 err = (*inp->inf_serv->is_ioctl)(code, data, inp->inf_isintf);
285 * Get IP VCC information
287 aip = (struct atminfreq *)data;
289 if (aip->air_ip_addr.sa_family != AF_INET)
291 ip = SATOSIN(&aip->air_ip_addr)->sin_addr;
293 cp = aip->air_buf_addr;
294 space = aip->air_buf_len;
297 * Loop through all our interfaces
299 for (inp = ipatm_nif_head; inp; inp = inp->inf_next) {
303 for (ivp = Q_HEAD(inp->inf_vcq, struct ipvcc); ivp;
304 ivp = Q_NEXT(ivp, struct ipvcc, iv_elem)) {
306 if ((ip.s_addr != INADDR_ANY) &&
307 (ip.s_addr != ivp->iv_dst.s_addr))
311 * Make sure there's room in user buffer
313 if (space < sizeof(aivr)) {
319 * Fill in info to be returned
321 KM_ZERO((caddr_t)&aivr, sizeof(aivr));
322 SATOSIN(&aivr.aip_dst_addr)->sin_family =
324 SATOSIN(&aivr.aip_dst_addr)->sin_addr.s_addr =
326 strlcpy(aivr.aip_intf,
327 inp->inf_nif->nif_if.if_xname,
328 sizeof(aivr.aip_intf));
329 if ((ivp->iv_conn) &&
330 (ivp->iv_conn->co_connvc) &&
331 (vcp = ivp->iv_conn->co_connvc->cvc_vcc)) {
332 aivr.aip_vpi = vcp->vc_vpi;
333 aivr.aip_vci = vcp->vc_vci;
334 aivr.aip_sig_proto = vcp->vc_proto;
336 aivr.aip_flags = ivp->iv_flags;
337 aivr.aip_state = ivp->iv_state;
340 * Copy data to user buffer and
341 * update buffer controls
343 err = copyout((caddr_t)&aivr, cp, sizeof(aivr));
347 space -= sizeof(aivr);
354 * Update buffer pointer/count
356 aip->air_buf_addr = cp;
357 aip->air_buf_len = space;
369 * Get Connection's Application/Owner Name
372 * tok ipatm connection token (pointer to ipvcc)
375 * addr pointer to string containing our name
379 ipatm_getname(void *tok)