ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

raw.c
Go to the documentation of this file.
00001 
00009 /*
00010  * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
00011  * All rights reserved.
00012  *
00013  * Redistribution and use in source and binary forms, with or without modification,
00014  * are permitted provided that the following conditions are met:
00015  *
00016  * 1. Redistributions of source code must retain the above copyright notice,
00017  *    this list of conditions and the following disclaimer.
00018  * 2. Redistributions in binary form must reproduce the above copyright notice,
00019  *    this list of conditions and the following disclaimer in the documentation
00020  *    and/or other materials provided with the distribution.
00021  * 3. The name of the author may not be used to endorse or promote products
00022  *    derived from this software without specific prior written permission.
00023  *
00024  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
00025  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00026  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
00027  * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00028  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
00029  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00030  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00031  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
00032  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
00033  * OF SUCH DAMAGE.
00034  *
00035  * This file is part of the lwIP TCP/IP stack.
00036  *
00037  * Author: Adam Dunkels <adam@sics.se>
00038  *
00039  */
00040 
00041 #include "lwip/opt.h"
00042 
00043 #if LWIP_RAW /* don't build if not configured for use in lwipopts.h */
00044 
00045 #include "lwip/def.h"
00046 #include "lwip/memp.h"
00047 #include "lwip/ip_addr.h"
00048 #include "lwip/netif.h"
00049 #include "lwip/raw.h"
00050 #include "lwip/stats.h"
00051 #include "arch/perf.h"
00052 
00053 #include <string.h>
00054 
00056 static struct raw_pcb *raw_pcbs;
00057 
00075 u8_t
00076 raw_input(struct pbuf *p, struct netif *inp)
00077 {
00078   struct raw_pcb *pcb, *prev;
00079   struct ip_hdr *iphdr;
00080   s16_t proto;
00081   u8_t eaten = 0;
00082 
00083   LWIP_UNUSED_ARG(inp);
00084 
00085   iphdr = (struct ip_hdr *)p->payload;
00086   proto = IPH_PROTO(iphdr);
00087 
00088   prev = NULL;
00089   pcb = raw_pcbs;
00090   /* loop through all raw pcbs until the packet is eaten by one */
00091   /* this allows multiple pcbs to match against the packet by design */
00092   while ((eaten == 0) && (pcb != NULL)) {
00093     if ((pcb->protocol == proto) &&
00094         (ip_addr_isany(&pcb->local_ip) ||
00095          ip_addr_cmp(&(pcb->local_ip), &current_iphdr_dest))) {
00096 #if IP_SOF_BROADCAST_RECV
00097       /* broadcast filter? */
00098       if ((pcb->so_options & SOF_BROADCAST) || !ip_addr_isbroadcast(&current_iphdr_dest, inp))
00099 #endif /* IP_SOF_BROADCAST_RECV */
00100       {
00101         /* receive callback function available? */
00102         if (pcb->recv != NULL) {
00103           /* the receive callback function did not eat the packet? */
00104           if (pcb->recv(pcb->recv_arg, pcb, p, ip_current_src_addr()) != 0) {
00105             /* receive function ate the packet */
00106             p = NULL;
00107             eaten = 1;
00108             if (prev != NULL) {
00109             /* move the pcb to the front of raw_pcbs so that is
00110                found faster next time */
00111               prev->next = pcb->next;
00112               pcb->next = raw_pcbs;
00113               raw_pcbs = pcb;
00114             }
00115           }
00116         }
00117         /* no receive callback function was set for this raw PCB */
00118       }
00119       /* drop the packet */
00120     }
00121     prev = pcb;
00122     pcb = pcb->next;
00123   }
00124   return eaten;
00125 }
00126 
00141 err_t
00142 raw_bind(struct raw_pcb *pcb, ip_addr_t *ipaddr)
00143 {
00144   ip_addr_set(&pcb->local_ip, ipaddr);
00145   return ERR_OK;
00146 }
00147 
00161 err_t
00162 raw_connect(struct raw_pcb *pcb, ip_addr_t *ipaddr)
00163 {
00164   ip_addr_set(&pcb->remote_ip, ipaddr);
00165   return ERR_OK;
00166 }
00167 
00168 
00182 void
00183 raw_recv(struct raw_pcb *pcb, raw_recv_fn recv, void *recv_arg)
00184 {
00185   /* remember recv() callback and user data */
00186   pcb->recv = recv;
00187   pcb->recv_arg = recv_arg;
00188 }
00189 
00202 err_t
00203 raw_sendto(struct raw_pcb *pcb, struct pbuf *p, ip_addr_t *ipaddr)
00204 {
00205   err_t err;
00206   struct netif *netif;
00207   ip_addr_t *src_ip;
00208   struct pbuf *q; /* q will be sent down the stack */
00209   
00210   LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_TRACE, ("raw_sendto\n"));
00211   
00212   /* not enough space to add an IP header to first pbuf in given p chain? */
00213   if (pbuf_header(p, IP_HLEN)) {
00214     /* allocate header in new pbuf */
00215     q = pbuf_alloc(PBUF_IP, 0, PBUF_RAM);
00216     /* new header pbuf could not be allocated? */
00217     if (q == NULL) {
00218       LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("raw_sendto: could not allocate header\n"));
00219       return ERR_MEM;
00220     }
00221     if (p->tot_len != 0) {
00222       /* chain header q in front of given pbuf p */
00223       pbuf_chain(q, p);
00224     }
00225     /* { first pbuf q points to header pbuf } */
00226     LWIP_DEBUGF(RAW_DEBUG, ("raw_sendto: added header pbuf %p before given pbuf %p\n", (void *)q, (void *)p));
00227   }  else {
00228     /* first pbuf q equals given pbuf */
00229     q = p;
00230     if(pbuf_header(q, -IP_HLEN)) {
00231       LWIP_ASSERT("Can't restore header we just removed!", 0);
00232       return ERR_MEM;
00233     }
00234   }
00235 
00236   if ((netif = ip_route(ipaddr)) == NULL) {
00237     LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_LEVEL_WARNING, ("raw_sendto: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
00238       ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr)));
00239     /* free any temporary header pbuf allocated by pbuf_header() */
00240     if (q != p) {
00241       pbuf_free(q);
00242     }
00243     return ERR_RTE;
00244   }
00245 
00246 #if IP_SOF_BROADCAST
00247   /* broadcast filter? */
00248   if (((pcb->so_options & SOF_BROADCAST) == 0) && ip_addr_isbroadcast(ipaddr, netif)) {
00249     LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_LEVEL_WARNING, ("raw_sendto: SOF_BROADCAST not enabled on pcb %p\n", (void *)pcb));
00250     /* free any temporary header pbuf allocated by pbuf_header() */
00251     if (q != p) {
00252       pbuf_free(q);
00253     }
00254     return ERR_VAL;
00255   }
00256 #endif /* IP_SOF_BROADCAST */
00257 
00258   if (ip_addr_isany(&pcb->local_ip)) {
00259     /* use outgoing network interface IP address as source address */
00260     src_ip = &(netif->ip_addr);
00261   } else {
00262     /* use RAW PCB local IP address as source address */
00263     src_ip = &(pcb->local_ip);
00264   }
00265 
00266 #if LWIP_NETIF_HWADDRHINT
00267   netif->addr_hint = &(pcb->addr_hint);
00268 #endif /* LWIP_NETIF_HWADDRHINT*/
00269   err = ip_output_if (q, src_ip, ipaddr, pcb->ttl, pcb->tos, pcb->protocol, netif);
00270 #if LWIP_NETIF_HWADDRHINT
00271   netif->addr_hint = NULL;
00272 #endif /* LWIP_NETIF_HWADDRHINT*/
00273 
00274   /* did we chain a header earlier? */
00275   if (q != p) {
00276     /* free the header */
00277     pbuf_free(q);
00278   }
00279   return err;
00280 }
00281 
00289 err_t
00290 raw_send(struct raw_pcb *pcb, struct pbuf *p)
00291 {
00292   return raw_sendto(pcb, p, &pcb->remote_ip);
00293 }
00294 
00303 void
00304 raw_remove(struct raw_pcb *pcb)
00305 {
00306   struct raw_pcb *pcb2;
00307   /* pcb to be removed is first in list? */
00308   if (raw_pcbs == pcb) {
00309     /* make list start at 2nd pcb */
00310     raw_pcbs = raw_pcbs->next;
00311     /* pcb not 1st in list */
00312   } else {
00313     for(pcb2 = raw_pcbs; pcb2 != NULL; pcb2 = pcb2->next) {
00314       /* find pcb in raw_pcbs list */
00315       if (pcb2->next != NULL && pcb2->next == pcb) {
00316         /* remove pcb from list */
00317         pcb2->next = pcb->next;
00318       }
00319     }
00320   }
00321   memp_free(MEMP_RAW_PCB, pcb);
00322 }
00323 
00334 struct raw_pcb *
00335 raw_new(u8_t proto)
00336 {
00337   struct raw_pcb *pcb;
00338 
00339   LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_TRACE, ("raw_new\n"));
00340 
00341   pcb = (struct raw_pcb *)memp_malloc(MEMP_RAW_PCB);
00342   /* could allocate RAW PCB? */
00343   if (pcb != NULL) {
00344     /* initialize PCB to all zeroes */
00345     memset(pcb, 0, sizeof(struct raw_pcb));
00346     pcb->protocol = proto;
00347     pcb->ttl = RAW_TTL;
00348     pcb->next = raw_pcbs;
00349     raw_pcbs = pcb;
00350   }
00351   return pcb;
00352 }
00353 
00354 #endif /* LWIP_RAW */

Generated on Sat May 26 2012 04:34:57 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.