Nut/OS  4.10.3
API Reference
route.c
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2001-2003 by egnite Software GmbH. All rights reserved.
00003  *
00004  * Redistribution and use in source and binary forms, with or without
00005  * modification, are permitted provided that the following conditions
00006  * are met:
00007  *
00008  * 1. Redistributions of source code must retain the above copyright
00009  *    notice, this list of conditions and the following disclaimer.
00010  * 2. Redistributions in binary form must reproduce the above copyright
00011  *    notice, this list of conditions and the following disclaimer in the
00012  *    documentation and/or other materials provided with the distribution.
00013  * 3. Neither the name of the copyright holders nor the names of
00014  *    contributors may be used to endorse or promote products derived
00015  *    from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH AND CONTRIBUTORS
00018  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00019  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00020  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL EGNITE
00021  * SOFTWARE GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00022  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00023  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
00024  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
00025  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00026  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
00027  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00028  * SUCH DAMAGE.
00029  *
00030  * For additional information see http://www.ethernut.de/
00031  *
00032  * -
00033  * Portions Copyright (C) 2000 David J. Hudson <dave@humbug.demon.co.uk>
00034  *
00035  * This file is distributed in the hope that it will be useful, but WITHOUT
00036  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00037  * FITNESS FOR A PARTICULAR PURPOSE.
00038  *
00039  * You can redistribute this file and/or modify it under the terms of the GNU
00040  * General Public License (GPL) as published by the Free Software Foundation;
00041  * either version 2 of the License, or (at your discretion) any later version.
00042  * See the accompanying file "copying-gpl.txt" for more details.
00043  *
00044  * As a special exception to the GPL, permission is granted for additional
00045  * uses of the text contained in this file.  See the accompanying file
00046  * "copying-liquorice.txt" for details.
00047  * -
00048  * Portions Copyright (c) 1983, 1993 by
00049  *  The Regents of the University of California.  All rights reserved.
00050  *
00051  * Redistribution and use in source and binary forms, with or without
00052  * modification, are permitted provided that the following conditions
00053  * are met:
00054  * 1. Redistributions of source code must retain the above copyright
00055  *    notice, this list of conditions and the following disclaimer.
00056  * 2. Redistributions in binary form must reproduce the above copyright
00057  *    notice, this list of conditions and the following disclaimer in the
00058  *    documentation and/or other materials provided with the distribution.
00059  * 3. Neither the name of the University nor the names of its contributors
00060  *    may be used to endorse or promote products derived from this software
00061  *    without specific prior written permission.
00062  *
00063  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00064  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00065  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00066  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00067  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00068  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00069  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00070  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00071  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00072  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00073  * SUCH DAMAGE.
00074  * -
00075  * Portions Copyright (c) 1993 by Digital Equipment Corporation.
00076  *
00077  * Permission to use, copy, modify, and distribute this software for any
00078  * purpose with or without fee is hereby granted, provided that the above
00079  * copyright notice and this permission notice appear in all copies, and that
00080  * the name of Digital Equipment Corporation not be used in advertising or
00081  * publicity pertaining to distribution of the document or software without
00082  * specific, written prior permission.
00083  * 
00084  * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
00085  * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
00086  * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
00087  * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
00088  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
00089  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
00090  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
00091  * SOFTWARE.
00092  */
00093 
00094 /*
00095  * $Log$
00096  * Revision 1.8  2009/02/13 14:52:05  haraldkipp
00097  * Include memdebug.h for heap management debugging support.
00098  *
00099  * Revision 1.7  2009/02/06 15:40:29  haraldkipp
00100  * Using newly available strdup() and calloc().
00101  * Replaced NutHeap routines by standard malloc/free.
00102  * Replaced pointer value 0 by NULL.
00103  *
00104  * Revision 1.6  2008/08/11 07:00:32  haraldkipp
00105  * BSD types replaced by stdint types (feature request #1282721).
00106  *
00107  * Revision 1.5  2005/07/23 14:30:40  haraldkipp
00108  * Removed unnecessary critical sections and atomic inc-/decrements.
00109  * Fixed a bug in NutIpRouteList(), which filled the first entry only.
00110  * Corrected the comment about unavailabilty of removing routes.
00111  *
00112  * Revision 1.4  2005/04/30 16:42:42  chaac
00113  * Fixed bug in handling of NUTDEBUG. Added include for cfg/os.h. If NUTDEBUG
00114  * is defined in NutConf, it will make effect where it is used.
00115  *
00116  * Revision 1.3  2004/12/17 15:27:19  haraldkipp
00117  * Added Adam Pierce's routing management functions.
00118  *
00119  * Revision 1.2  2004/10/10 16:37:03  drsung
00120  * Detection of directed broadcasts to local network added.
00121  *
00122  * Revision 1.1.1.1  2003/05/09 14:41:38  haraldkipp
00123  * Initial using 3.2.1
00124  *
00125  * Revision 1.12  2003/03/31 14:53:28  harald
00126  * Prepare release 3.1
00127  *
00128  * Revision 1.11  2003/02/04 18:14:57  harald
00129  * Version 3 released
00130  *
00131  * Revision 1.10  2002/06/26 17:29:36  harald
00132  * First pre-release with 2.4 stack
00133  *
00134  */
00135 
00136 #include <cfg/os.h>
00137 #include <sys/heap.h>
00138 
00139 #include <net/if_var.h>
00140 #include <net/route.h>
00141 
00142 #include <netinet/ip.h>
00143 
00144 #include <stdlib.h>
00145 #include <string.h>
00146 #include <memdebug.h>
00147 
00148 #ifdef NUTDEBUG
00149 #include <sys/osdebug.h>
00150 #endif
00151 
00156 
00157 RTENTRY *rteList;           
00176 int NutIpRouteAdd(uint32_t ip, uint32_t mask, uint32_t gate, NUTDEVICE * dev)
00177 {
00178     int rc = -1;
00179     RTENTRY *rte;
00180     RTENTRY *rtp;
00181     RTENTRY **rtpp;
00182 
00183     /*
00184      * Insert a new entry into the list, which is
00185      * sorted based on the mask. Host routes are
00186      * in front, default routes at the end and
00187      * networks in between.
00188      */
00189     rtp = rteList;
00190     rtpp = &rteList;
00191     while (rtp && rtp->rt_mask > mask) {
00192         rtpp = &rtp->rt_next;
00193         rtp = rtp->rt_next;
00194     }
00195     if ((rte = malloc(sizeof(RTENTRY))) != NULL) {
00196         rte->rt_ip = ip & mask;
00197         rte->rt_mask = mask;
00198         rte->rt_gateway = gate;
00199         rte->rt_dev = dev;
00200         rte->rt_next = rtp;
00201         *rtpp = rte;
00202         rc = 0;
00203     }
00204     return rc;
00205 }
00206 
00214 int NutIpRouteDelAll(NUTDEVICE * dev)
00215 {
00216     RTENTRY **rtpp;
00217     RTENTRY *rte;
00218 
00219     rtpp = &rteList;
00220 
00221     while (*rtpp) {
00222         rte = *rtpp;
00223 
00224         if (rte->rt_dev == dev || dev == 0) {
00225             *rtpp = rte->rt_next;
00226             free(rte);
00227         } else
00228             *rtpp = (*rtpp)->rt_next;
00229     }
00230     return 0;
00231 }
00232 
00233 
00247 int NutIpRouteDel(uint32_t ip, uint32_t mask, uint32_t gate, NUTDEVICE * dev)
00248 {
00249     int rc = -1;
00250     RTENTRY **rtpp;
00251     RTENTRY *rte;
00252 
00253     for (rtpp = &rteList; *rtpp; *rtpp = (*rtpp)->rt_next) {
00254         rte = *rtpp;
00255 
00256         if (rte->rt_ip == ip && rte->rt_mask == mask && rte->rt_gateway == gate && rte->rt_dev == dev) {
00257             *rtpp = rte->rt_next;
00258             free(rte);
00259             rc = 0;
00260         }
00261     }
00262     return rc;
00263 }
00264 
00274 RTENTRY *NutIpRouteList(int *numEntries)
00275 {
00276     RTENTRY *rc;
00277     RTENTRY *rte;
00278 
00279     /* First count the number of entries. */
00280     *numEntries = 0;
00281     for (rte = rteList; rte; rte = rte->rt_next) {
00282         (*numEntries)++;
00283     }
00284 
00285     /* Allocate space for the result. */
00286     rc = (RTENTRY *) malloc(sizeof(RTENTRY) * (*numEntries));
00287 
00288     /* Fill in the result. */
00289     if (rc) {
00290         for (rte = rteList; rte; rc++, rte = rte->rt_next) {
00291             memcpy(rc, rte, sizeof(RTENTRY));
00292         }
00293     }
00294     else {
00295         *numEntries = 0;
00296     }
00297     return rc;
00298 }
00299 
00314 static RTENTRY *NutIpRouteRecQuery(uint32_t ip, uint32_t * gate, uint8_t level)
00315 {
00316     RTENTRY *rte = 0;
00317 
00318     if (level < 4) {
00319         for (rte = rteList; rte; rte = rte->rt_next) {
00320             if ((ip & rte->rt_mask) == rte->rt_ip)
00321                 break;
00322         }
00323         if (rte) {
00324             if (gate && rte->rt_gateway)
00325                 *gate = rte->rt_gateway;
00326             if (rte->rt_dev == 0)
00327                 rte = NutIpRouteRecQuery(rte->rt_gateway, gate, level + 1);
00328         }
00329     }
00330     return rte;
00331 }
00332 
00349 NUTDEVICE *NutIpRouteQuery(uint32_t ip, uint32_t * gate)
00350 {
00351     RTENTRY *rte;
00352 
00353     if (gate)
00354         *gate = 0;
00355     /* Return the first interface if the IP is broadcast. This solves the
00356        long existing problem with bad checksums on UDP broadcasts. Many
00357        thanks to Nicolas Moreau for this patch. */
00358     if ((ip == 0xFFFFFFFF) || (IP_IS_MULTICAST(ip)))
00359         rte = rteList;
00360     else
00361         rte = NutIpRouteRecQuery(ip, gate, 0);
00362 
00363     return rte ? rte->rt_dev : 0;
00364 }
00365