Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00056 #include "uip.h"
00057 #include "uip_arch.h"
00058 #include "uip-fw.h"
00059
00060 #include <string.h>
00061
00062
00063
00064
00065 static struct uip_fw_netif *netifs = NULL;
00066
00067
00068
00069
00070 static struct uip_fw_netif *defaultnetif = NULL;
00071
00072 struct tcpip_hdr {
00073
00074 u8_t vhl,
00075 tos;
00076 u16_t len,
00077 ipid,
00078 ipoffset;
00079 u8_t ttl,
00080 proto;
00081 u16_t ipchksum;
00082 u16_t srcipaddr[2],
00083 destipaddr[2];
00084
00085
00086 u16_t srcport,
00087 destport;
00088 u8_t seqno[4],
00089 ackno[4],
00090 tcpoffset,
00091 flags,
00092 wnd[2];
00093 u16_t tcpchksum;
00094 u8_t urgp[2];
00095 u8_t optdata[4];
00096 } PACK_STRUCT_END;
00097
00098 struct icmpip_hdr {
00099
00100 u8_t vhl,
00101 tos,
00102 len[2],
00103 ipid[2],
00104 ipoffset[2],
00105 ttl,
00106 proto;
00107 u16_t ipchksum;
00108 u16_t srcipaddr[2],
00109 destipaddr[2];
00110
00111 u8_t type, icode;
00112 u16_t icmpchksum;
00113 u16_t id, seqno;
00114 u8_t payload[1];
00115 } PACK_STRUCT_END;
00116
00117
00118 #define ICMP_ECHO 8
00119
00120
00121 #define ICMP_TE 11
00122
00123
00124
00125
00126 #define BUF ((struct tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
00127
00128
00129
00130
00131 #define ICMPBUF ((struct icmpip_hdr *)&uip_buf[UIP_LLH_LEN])
00132
00133
00134
00135
00136
00137 struct fwcache_entry {
00138 u16_t timer;
00139
00140 u16_t srcipaddr[2];
00141 u16_t destipaddr[2];
00142 u16_t ipid;
00143 u8_t proto;
00144 u8_t unused;
00145
00146 #if notdef
00147 u16_t payload[2];
00148 #endif
00149
00150 #if UIP_REASSEMBLY > 0
00151 u16_t len, offset;
00152 #endif
00153 };
00154
00155
00156
00157
00158 #ifdef UIP_CONF_FWCACHE_SIZE
00159 #define FWCACHE_SIZE UIP_CONF_FWCACHE_SIZE
00160 #else
00161 #define FWCACHE_SIZE 2
00162 #endif
00163
00164
00165
00166
00167
00168
00169 static struct fwcache_entry fwcache[FWCACHE_SIZE];
00170
00175 #define FW_TIME 20
00176
00177
00181
00182 void
00183 uip_fw_init(void)
00184 {
00185 struct uip_fw_netif *t;
00186 defaultnetif = NULL;
00187 while(netifs != NULL) {
00188 t = netifs;
00189 netifs = netifs->next;
00190 t->next = NULL;
00191 }
00192 }
00193
00205
00206 static unsigned char
00207 ipaddr_maskcmp(u16_t *ipaddr, u16_t *netipaddr, u16_t *netmask)
00208 {
00209 return (ipaddr[0] & netmask [0]) == (netipaddr[0] & netmask[0]) &&
00210 (ipaddr[1] & netmask[1]) == (netipaddr[1] & netmask[1]);
00211 }
00212
00220
00221 static void
00222 time_exceeded(void)
00223 {
00224 u16_t tmp16;
00225
00226
00227 if(ICMPBUF->proto == UIP_PROTO_ICMP) {
00228 uip_len = 0;
00229 return;
00230 }
00231
00232 memcpy(&(ICMPBUF->payload[0]), ICMPBUF, 28);
00233
00234
00235 ICMPBUF->type = ICMP_TE;
00236 ICMPBUF->icode = 0;
00237
00238
00239 ICMPBUF->icmpchksum = 0;
00240 ICMPBUF->icmpchksum = ~uip_chksum((u16_t *)&(ICMPBUF->type), 36);
00241
00242
00243
00244 tmp16= BUF->destipaddr[0];
00245 BUF->destipaddr[0] = BUF->srcipaddr[0];
00246 BUF->srcipaddr[0] = tmp16;
00247 tmp16 = BUF->destipaddr[1];
00248 BUF->destipaddr[1] = BUF->srcipaddr[1];
00249 BUF->srcipaddr[1] = tmp16;
00250
00251
00252 BUF->srcipaddr[0] = uip_hostaddr[0];
00253 BUF->srcipaddr[1] = uip_hostaddr[1];
00254
00255
00256
00257 uip_len = 56;
00258 ICMPBUF->len[0] = 0;
00259 ICMPBUF->len[1] = uip_len;
00260
00261
00262 ICMPBUF->vhl = 0x45;
00263 ICMPBUF->tos = 0;
00264 ICMPBUF->ipoffset[0] = ICMPBUF->ipoffset[1] = 0;
00265 ICMPBUF->ttl = UIP_TTL;
00266 ICMPBUF->proto = UIP_PROTO_ICMP;
00267
00268
00269 ICMPBUF->ipchksum = 0;
00270 ICMPBUF->ipchksum = ~(uip_ipchksum());
00271
00272
00273 }
00274
00280
00281 static void
00282 fwcache_register(void)
00283 {
00284 struct fwcache_entry *fw;
00285 int i, oldest;
00286
00287 oldest = FW_TIME;
00288 fw = NULL;
00289
00290
00291 for(i = 0; i < FWCACHE_SIZE; ++i) {
00292 if(fwcache[i].timer == 0) {
00293 fw = &fwcache[i];
00294 break;
00295 } else if(fwcache[i].timer <= oldest) {
00296 fw = &fwcache[i];
00297 oldest = fwcache[i].timer;
00298 }
00299 }
00300
00301 fw->timer = FW_TIME;
00302 fw->ipid = BUF->ipid;
00303 fw->srcipaddr[0] = BUF->srcipaddr[0];
00304 fw->srcipaddr[1] = BUF->srcipaddr[1];
00305 fw->destipaddr[0] = BUF->destipaddr[0];
00306 fw->destipaddr[1] = BUF->destipaddr[1];
00307 fw->proto = BUF->proto;
00308 #if notdef
00309 fw->payload[0] = BUF->srcport;
00310 fw->payload[1] = BUF->destport;
00311 #endif
00312 #if UIP_REASSEMBLY > 0
00313 fw->len = BUF->len;
00314 fw->offset = BUF->ipoffset;
00315 #endif
00316 }
00317
00322
00323 static struct uip_fw_netif *
00324 find_netif(void)
00325 {
00326 struct uip_fw_netif *netif;
00327
00328
00329 for(netif = netifs; netif != NULL; netif = netif->next) {
00330 if(ipaddr_maskcmp(BUF->destipaddr, netif->ipaddr,
00331 netif->netmask)) {
00332
00333 return netif;
00334 }
00335 }
00336
00337
00338 return defaultnetif;
00339 }
00340
00356
00357 u8_t
00358 uip_fw_output(void)
00359 {
00360 struct uip_fw_netif *netif;
00361
00362 if(uip_len == 0) {
00363 return UIP_FW_ZEROLEN;
00364 }
00365
00366 fwcache_register();
00367
00368 #if UIP_BROADCAST
00369
00370 if(
00371 BUF->destipaddr[0] == 0xffff &&
00372 BUF->destipaddr[1] == 0xffff) {
00373 if(defaultnetif != NULL) {
00374 defaultnetif->output();
00375 }
00376 for(netif = netifs; netif != NULL; netif = netif->next) {
00377 netif->output();
00378 }
00379 return UIP_FW_OK;
00380 }
00381 #endif
00382
00383 netif = find_netif();
00384
00385
00386
00387
00388 if(netif == NULL) {
00389 return UIP_FW_NOROUTE;
00390 }
00391
00392
00393 return netif->output();
00394 }
00395
00404
00405 u8_t
00406 uip_fw_forward(void)
00407 {
00408 struct fwcache_entry *fw;
00409
00410
00411
00412 if(BUF->destipaddr[0] == uip_hostaddr[0] &&
00413 BUF->destipaddr[1] == uip_hostaddr[1]) {
00414 return UIP_FW_LOCAL;
00415 }
00416
00417
00418
00419 #if UIP_PINGADDRCONF
00420 if((uip_hostaddr[0] | uip_hostaddr[1]) == 0 &&
00421 BUF->proto == UIP_PROTO_ICMP &&
00422 ICMPBUF->type == ICMP_ECHO) {
00423 return UIP_FW_LOCAL;
00424 }
00425 #endif
00426
00427
00428
00429
00430 for(fw = fwcache; fw < &fwcache[FWCACHE_SIZE]; ++fw) {
00431 if(fw->timer != 0 &&
00432 #if UIP_REASSEMBLY > 0
00433 fw->len == BUF->len &&
00434 fw->offset == BUF->ipoffset &&
00435 #endif
00436 fw->ipid == BUF->ipid &&
00437 fw->srcipaddr[0] == BUF->srcipaddr[0] &&
00438 fw->srcipaddr[1] == BUF->srcipaddr[1] &&
00439 fw->destipaddr[0] == BUF->destipaddr[0] &&
00440 fw->destipaddr[1] == BUF->destipaddr[1] &&
00441 #if notdef
00442 fw->payload[0] == BUF->srcport &&
00443 fw->payload[1] == BUF->destport &&
00444 #endif
00445 fw->proto == BUF->proto) {
00446
00447 return UIP_FW_FORWARDED;
00448 }
00449 }
00450
00451
00452
00453
00454 if(BUF->ttl <= 1) {
00455
00456 if(BUF->destipaddr[0] == 0xffff && BUF->destipaddr[1] == 0xffff) {
00457 return UIP_FW_LOCAL;
00458 }
00459 time_exceeded();
00460 }
00461
00462
00463 BUF->ttl = BUF->ttl - 1;
00464
00465
00466 if(BUF->ipchksum >= HTONS(0xffff - 0x0100)) {
00467 BUF->ipchksum = BUF->ipchksum + HTONS(0x0100) + 1;
00468 } else {
00469 BUF->ipchksum = BUF->ipchksum + HTONS(0x0100);
00470 }
00471
00472 if(uip_len > 0) {
00473 uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_TCPIP_HLEN];
00474 uip_fw_output();
00475 }
00476
00477 #if UIP_BROADCAST
00478 if(BUF->destipaddr[0] == 0xffff && BUF->destipaddr[1] == 0xffff) {
00479 return UIP_FW_LOCAL;
00480 }
00481 #endif
00482
00483
00484
00485 return UIP_FW_FORWARDED;
00486 }
00487
00494
00495 void
00496 uip_fw_register(struct uip_fw_netif *netif)
00497 {
00498 netif->next = netifs;
00499 netifs = netif;
00500 }
00501
00511
00512 void
00513 uip_fw_default(struct uip_fw_netif *netif)
00514 {
00515 defaultnetif = netif;
00516 }
00517
00521
00522 void
00523 uip_fw_periodic(void)
00524 {
00525 struct fwcache_entry *fw;
00526 for(fw = fwcache; fw < &fwcache[FWCACHE_SIZE]; ++fw) {
00527 if(fw->timer > 0) {
00528 --fw->timer;
00529 }
00530 }
00531 }
00532