source: rtems/c/src/lib/libbsp/powerpc/mpc8260ads/network/if_hdlcsubr.c @ 65c6425

4.115
Last change on this file since 65c6425 was 65c6425, checked in by Joel Sherrill <joel.sherrill@…>, on 05/03/12 at 17:24:46

Remove CVS Id Strings (manual edits after script)

These modifications were required by hand after running the script.
In some cases, the file names did not match patterns. In others,
the format of the file did not match any common patterns.

  • Property mode set to 100644
File size: 8.8 KB
Line 
1/*
2 * Created from if_ethersubr.c by Andy Dachs <a.dachs@sstl.co.uk>
3 * Surrey Satellite Technology Limited (SSTL), 2001
4 * Modified (hacked) to support IP frames transmitted over HDLC. This
5 * all needs tidying up in future but it does actually work for point
6 * to point communications. I have an SDL WANic400 synchronous
7 * communications card that comes with Windows NT drivers.  The drivers
8 * support a mode that they call "Ethernet Emulation".  That simply
9 * puts the IP frame in an HDLC frame without any ethernet header. i.e.
10 * <HDLC Flag><IpFrame><CRC><HDLC Flag>.  There is no addressing beyond
11 * the IP header information so is only suitable for point to point links
12 * with a single protocol. "At some point" I will add a Frame Relay header
13 * but at the moment I have difficulties getting the WANic card driver's
14 * Frame Relay driver to work.
15 *
16 * Copyright (c) 1982, 1989, 1993
17 *      The Regents of the University of California.  All rights reserved.
18 *
19 * Redistribution and use in source and binary forms, with or without
20 * modification, are permitted provided that the following conditions
21 * are met:
22 * 1. Redistributions of source code must retain the above copyright
23 *    notice, this list of conditions and the following disclaimer.
24 * 2. Redistributions in binary form must reproduce the above copyright
25 *    notice, this list of conditions and the following disclaimer in the
26 *    documentation and/or other materials provided with the distribution.
27 * 3. All advertising materials mentioning features or use of this software
28 *    must display the following acknowledgement:
29 *      This product includes software developed by the University of
30 *      California, Berkeley and its contributors.
31 * 4. Neither the name of the University nor the names of its contributors
32 *    may be used to endorse or promote products derived from this software
33 *    without specific prior written permission.
34 *
35 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
36 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
38 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
39 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
40 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
41 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
42 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
43 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
44 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
45 * SUCH DAMAGE.
46 *
47 *      @(#)if_ethersubr.c      8.1 (Berkeley) 6/10/93
48 */
49
50#include <rtems/rtems_bsdnet.h>
51
52#include <sys/param.h>
53/*#include <sys/systm.h>
54#include <sys/kernel.h> */
55#define KERNEL
56#include <sys/malloc.h>
57#include <sys/mbuf.h>
58#include <sys/protosw.h>
59#include <sys/socket.h>
60#include <sys/ioctl.h>
61#include <errno.h>
62#include <sys/syslog.h>
63#include <sys/sysctl.h>
64
65#include <net/if.h>
66#include <net/netisr.h>
67#include <net/route.h>
68#include <net/if_llc.h>
69#include <net/if_dl.h>
70#include <net/if_types.h>
71#include <net/ethernet.h>
72
73#include <netinet/in.h>
74#include <netinet/in_var.h>
75#include <netinet/if_ether.h>
76
77#include <stdio.h>
78
79#include "if_hdlcsubr.h"
80
81/*
82u_char  etherbroadcastaddr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
83*/
84#define senderr(e) { error = (e); goto bad;}
85
86/*
87 * HDLC output routine.
88 * Just transmit the packet (hardware adds flags and CRC)
89 */
90int
91hdlc_output(ifp, m0, dst, rt0)
92        register struct ifnet *ifp;
93        struct mbuf *m0;
94        struct sockaddr *dst;
95        struct rtentry *rt0;
96{
97        short type;
98        int s, error = 0;
99#if 0
100        u_char  edst[6];
101#endif
102        register struct mbuf *m = m0;
103        register struct rtentry *rt;
104        struct mbuf *mcopy = (struct mbuf *)0;
105/*      register struct ether_header *eh; */
106        int off, len = m->m_pkthdr.len;
107
108/*      printk( "hdlc output" ); */
109/*      struct arpcom *ac = (struct arpcom *)ifp; */
110
111        if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
112                senderr(ENETDOWN);
113        rt = rt0;
114        if (rt) {
115                if ((rt->rt_flags & RTF_UP) == 0) {
116                        rt0 = rt = rtalloc1(dst, 1, 0UL);
117                        if (rt0)
118                                rt->rt_refcnt--;
119                        else
120                                senderr(EHOSTUNREACH);
121                }
122                if (rt->rt_flags & RTF_GATEWAY) {
123                        if (rt->rt_gwroute == 0)
124                                goto lookup;
125                        if (((rt = rt->rt_gwroute)->rt_flags & RTF_UP) == 0) {
126                                rtfree(rt); rt = rt0;
127                        lookup: rt->rt_gwroute = rtalloc1(rt->rt_gateway, 1,
128                                                          0UL);
129                                if ((rt = rt->rt_gwroute) == 0)
130                                        senderr(EHOSTUNREACH);
131                        }
132                }
133                if (rt->rt_flags & RTF_REJECT)
134                        if (rt->rt_rmx.rmx_expire == 0 ||
135                            rtems_bsdnet_seconds_since_boot() < rt->rt_rmx.rmx_expire)
136                                senderr(rt == rt0 ? EHOSTDOWN : EHOSTUNREACH);
137        }
138        switch (dst->sa_family) {
139
140        case AF_INET:
141#if 0
142                if (!arpresolve(ac, rt, m, dst, edst, rt0))
143                        return (0);     /* if not yet resolved */
144#endif
145
146                /* If broadcasting on a simplex interface, loopback a copy */
147                if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX))
148                        mcopy = m_copy(m, 0, (int)M_COPYALL);
149                off = m->m_pkthdr.len - m->m_len;
150                type = htons(ETHERTYPE_IP);
151                break;
152#if 0
153        case AF_UNSPEC:
154                eh = (struct ether_header *)dst->sa_data;
155                (void)memcpy(edst, eh->ether_dhost, sizeof (edst));
156                type = eh->ether_type;
157                break;
158#endif
159        default:
160                printf("%s%d: can't handle af%d\n", ifp->if_name, ifp->if_unit,
161                        dst->sa_family);
162                senderr(EAFNOSUPPORT);
163        }
164
165        if (mcopy)
166                (void) looutput(ifp, mcopy, dst, rt);
167#if 0
168        /*
169         * Add local net header.  If no space in first mbuf,
170         * allocate another.
171         */
172        M_PREPEND(m, sizeof (struct ether_header), M_DONTWAIT);
173#endif
174
175        if (m == 0)
176                senderr(ENOBUFS);
177
178#if 0
179        eh = mtod(m, struct ether_header *);
180        (void)memcpy(&eh->ether_type, &type,
181                sizeof(eh->ether_type));
182        (void)memcpy(eh->ether_dhost, edst, sizeof (edst));
183        (void)memcpy(eh->ether_shost, ac->ac_enaddr,
184            sizeof(eh->ether_shost));
185#endif
186
187        s = splimp();
188        /*
189         * Queue message on interface, and start output if interface
190         * not yet active.
191         */
192        if (IF_QFULL(&ifp->if_snd)) {
193                IF_DROP(&ifp->if_snd);
194                splx(s);
195                senderr(ENOBUFS);
196        }
197        IF_ENQUEUE(&ifp->if_snd, m);
198        if ((ifp->if_flags & IFF_OACTIVE) == 0)
199                (*ifp->if_start)(ifp);
200        splx(s);
201
202        ifp->if_obytes += len /*+ sizeof (struct ether_header)*/;
203        if (m->m_flags & M_MCAST)
204                ifp->if_omcasts++;
205        return (error);
206
207bad:
208        if (m)
209                m_freem(m);
210        return (error);
211}
212
213/*
214 * Process a received Ethernet packet;
215 * the packet is in the mbuf chain m without
216 * the ether header, which is provided separately.
217 */
218void
219hdlc_input(ifp, m)
220        struct ifnet *ifp;
221        struct mbuf *m;
222{
223        register struct ifqueue *inq;
224        int s;
225
226        struct ether_header eh;
227
228        if ((ifp->if_flags & IFF_UP) == 0) {
229                m_freem(m);
230                return;
231        }
232        ifp->if_ibytes += m->m_pkthdr.len;
233/*
234        if (memcmp((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost,
235            sizeof(etherbroadcastaddr)) == 0)
236                m->m_flags |= M_BCAST;
237        else if (eh->ether_dhost[0] & 1)
238                m->m_flags |= M_MCAST;
239*/
240        if (m->m_flags & (M_BCAST|M_MCAST))
241                ifp->if_imcasts++;
242
243        /*
244         * RTEMS addition -- allow application to `tap into'
245         * the incoming packet stream.
246         */
247        if (ifp->if_tap && (*ifp->if_tap)(ifp, &eh, m)) {
248                m_freem(m);
249                return;
250        }
251
252        schednetisr(NETISR_IP);
253        inq = &ipintrq;
254
255        s = splimp();
256        if (IF_QFULL(inq)) {
257          IF_DROP(inq);
258          m_freem(m);
259        } else
260          IF_ENQUEUE(inq, m);
261        splx(s);
262}
263
264/*
265 * Perform common duties while attaching to interface list
266 */
267void
268hdlc_ifattach(ifp)
269        register struct ifnet *ifp;
270{
271        register struct ifaddr *ifa;
272        register struct sockaddr_dl *sdl;
273
274        ifp->if_type = IFT_ETHER;
275        ifp->if_addrlen = 0;
276        ifp->if_hdrlen  = 0;
277        ifp->if_mtu  = 2048;
278        if (ifp->if_baudrate == 0)
279            ifp->if_baudrate = 8000000;
280        for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next)
281                if ((sdl = (struct sockaddr_dl *)ifa->ifa_addr) &&
282                    sdl->sdl_family == AF_LINK) {
283                        sdl->sdl_type = IFT_ETHER;
284                        sdl->sdl_alen = ifp->if_addrlen;
285/*
286                        memcpy(LLADDR(sdl),
287                              (caddr_t)((struct arpcom *)ifp)->ac_enaddr,
288                              ifp->if_addrlen);
289*/
290                        break;
291                }
292}
293
294/* SYSCTL_NODE(_net_link, IFT_ETHER, ether, CTLFLAG_RW, 0, "Ethernet"); */
295
296int
297hdlc_ioctl(struct ifnet *ifp, int command, caddr_t data)
298{
299        struct ifaddr *ifa = (struct ifaddr *) data;
300        struct ifreq *ifr = (struct ifreq *) data;
301        int error = 0;
302
303        switch (command) {
304        case SIOCSIFADDR:
305                ifp->if_flags |= IFF_UP;
306
307                switch (ifa->ifa_addr->sa_family) {
308#if 0
309#ifdef INET
310                case AF_INET:
311                        ifp->if_init(ifp->if_softc);    /* before arpwhohas */
312
313                        arp_ifinit((struct arpcom *)ifp, ifa);
314                        break;
315#endif
316#endif
317                default:
318                        ifp->if_init(ifp->if_softc);
319                        break;
320                }
321                break;
322
323        case SIOCGIFADDR:
324                {
325                        struct sockaddr *sa;
326
327                        sa = (struct sockaddr *) & ifr->ifr_data;
328/*
329                        memcpy((caddr_t) sa->sa_data,
330                              ((struct arpcom *)ifp->if_softc)->ac_enaddr,
331                              ETHER_ADDR_LEN);
332*/
333                }
334                break;
335
336        case SIOCSIFMTU:
337                /*
338                 * Set the interface MTU.
339                 */
340                if (ifr->ifr_mtu > ETHERMTU) {
341                        error = EINVAL;
342                } else {
343                        ifp->if_mtu = ifr->ifr_mtu;
344                }
345                break;
346        }
347        return (error);
348}
Note: See TracBrowser for help on using the repository browser.