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
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056 #include "net/uip.h"
00057 #include "net/uip_arch.h"
00058 #include "net/uip-fw.h"
00059 #include "contiki-conf.h"
00060
00061 #include <string.h>
00062
00063
00064
00065
00066 static struct uip_fw_netif *netifs = NULL;
00067
00068
00069
00070
00071 static struct uip_fw_netif *defaultnetif = NULL;
00072
00073 struct tcpip_hdr {
00074
00075 u8_t vhl,
00076 tos;
00077 u16_t len,
00078 ipid,
00079 ipoffset;
00080 u8_t ttl,
00081 proto;
00082 u16_t ipchksum;
00083 u16_t srcipaddr[2],
00084 destipaddr[2];
00085
00086
00087 u16_t srcport,
00088 destport;
00089 u8_t seqno[4],
00090 ackno[4],
00091 tcpoffset,
00092 flags,
00093 wnd[2];
00094 u16_t tcpchksum;
00095 u8_t urgp[2];
00096 u8_t optdata[4];
00097 };
00098
00099 struct icmpip_hdr {
00100
00101 u8_t vhl,
00102 tos,
00103 len[2],
00104 ipid[2],
00105 ipoffset[2],
00106 ttl,
00107 proto;
00108 u16_t ipchksum;
00109 u16_t srcipaddr[2],
00110 destipaddr[2];
00111
00112 u8_t type, icode;
00113 u16_t icmpchksum;
00114 u16_t id, seqno;
00115 u8_t payload[1];
00116 };
00117
00118
00119 #define ICMP_ECHO 8
00120
00121
00122 #define ICMP_TE 11
00123
00124
00125
00126
00127 #define BUF ((struct tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
00128
00129
00130
00131
00132 #define ICMPBUF ((struct icmpip_hdr *)&uip_buf[UIP_LLH_LEN])
00133
00134
00135
00136
00137
00138 struct fwcache_entry {
00139 u16_t timer;
00140
00141 u16_t srcipaddr[2];
00142 u16_t destipaddr[2];
00143 u16_t ipid;
00144 u8_t proto;
00145 u8_t unused;
00146
00147 #if notdef
00148 u16_t payload[2];
00149 #endif
00150
00151 #if UIP_REASSEMBLY > 0
00152 u16_t len, offset;
00153 #endif
00154 };
00155
00156
00157
00158
00159 #ifdef UIP_CONF_FWCACHE_SIZE
00160 #define FWCACHE_SIZE UIP_CONF_FWCACHE_SIZE
00161 #else
00162 #define FWCACHE_SIZE 2
00163 #endif
00164
00165
00166
00167
00168
00169
00170 static struct fwcache_entry fwcache[FWCACHE_SIZE];
00171
00172
00173
00174
00175
00176 #define FW_TIME 20
00177
00178
00179
00180
00181
00182
00183 void
00184 uip_fw_init(void)
00185 {
00186 struct uip_fw_netif *t;
00187 defaultnetif = NULL;
00188 while(netifs != NULL) {
00189 t = netifs;
00190 netifs = netifs->next;
00191 t->next = NULL;
00192 }
00193 }
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207 static unsigned char
00208 ipaddr_maskcmp(u16_t *ipaddr, u16_t *netipaddr, u16_t *netmask)
00209 {
00210 return (ipaddr[0] & netmask [0]) == (netipaddr[0] & netmask[0]) &&
00211 (ipaddr[1] & netmask[1]) == (netipaddr[1] & netmask[1]);
00212 }
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222 static void
00223 time_exceeded(void)
00224 {
00225 u16_t tmp16;
00226
00227
00228 if(ICMPBUF->proto == UIP_PROTO_ICMP) {
00229 uip_len = 0;
00230 return;
00231 }
00232
00233 memcpy(&(ICMPBUF->payload[0]), ICMPBUF, 28);
00234
00235
00236 ICMPBUF->type = ICMP_TE;
00237 ICMPBUF->icode = 0;
00238
00239
00240 ICMPBUF->icmpchksum = 0;
00241 ICMPBUF->icmpchksum = ~uip_chksum((u16_t *)&(ICMPBUF->type), 36);
00242
00243
00244
00245 tmp16= BUF->destipaddr[0];
00246 BUF->destipaddr[0] = BUF->srcipaddr[0];
00247 BUF->srcipaddr[0] = tmp16;
00248 tmp16 = BUF->destipaddr[1];
00249 BUF->destipaddr[1] = BUF->srcipaddr[1];
00250 BUF->srcipaddr[1] = tmp16;
00251
00252
00253 BUF->srcipaddr[0] = uip_hostaddr[0];
00254 BUF->srcipaddr[1] = uip_hostaddr[1];
00255
00256
00257
00258 uip_len = 56;
00259 ICMPBUF->len[0] = 0;
00260 ICMPBUF->len[1] = uip_len;
00261
00262
00263 ICMPBUF->vhl = 0x45;
00264 ICMPBUF->tos = 0;
00265 ICMPBUF->ipoffset[0] = ICMPBUF->ipoffset[1] = 0;
00266 ICMPBUF->ttl = UIP_TTL;
00267 ICMPBUF->proto = UIP_PROTO_ICMP;
00268
00269
00270 ICMPBUF->ipchksum = 0;
00271 ICMPBUF->ipchksum = ~(uip_ipchksum());
00272
00273
00274 }
00275
00276
00277
00278
00279
00280
00281
00282 static void
00283 fwcache_register(void)
00284 {
00285 struct fwcache_entry *fw;
00286 int i, oldest;
00287
00288 oldest = FW_TIME;
00289 fw = NULL;
00290
00291
00292 for(i = 0; i < FWCACHE_SIZE; ++i) {
00293 if(fwcache[i].timer == 0) {
00294 fw = &fwcache[i];
00295 break;
00296 } else if(fwcache[i].timer <= oldest) {
00297 fw = &fwcache[i];
00298 oldest = fwcache[i].timer;
00299 }
00300 }
00301
00302 fw->timer = FW_TIME;
00303 fw->ipid = BUF->ipid;
00304 fw->srcipaddr[0] = BUF->srcipaddr[0];
00305 fw->srcipaddr[1] = BUF->srcipaddr[1];
00306 fw->destipaddr[0] = BUF->destipaddr[0];
00307 fw->destipaddr[1] = BUF->destipaddr[1];
00308 fw->proto = BUF->proto;
00309 #if notdef
00310 fw->payload[0] = BUF->srcport;
00311 fw->payload[1] = BUF->destport;
00312 #endif
00313 #if UIP_REASSEMBLY > 0
00314 fw->len = BUF->len;
00315 fw->offset = BUF->ipoffset;
00316 #endif
00317 }
00318
00319
00320
00321
00322
00323
00324 static struct uip_fw_netif *
00325 find_netif(void)
00326 {
00327 struct uip_fw_netif *netif;
00328
00329
00330 for(netif = netifs; netif != NULL; netif = netif->next) {
00331 if(ipaddr_maskcmp(BUF->destipaddr, netif->ipaddr,
00332 netif->netmask)) {
00333
00334 return netif;
00335 }
00336 }
00337
00338
00339 return defaultnetif;
00340 }
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358 u8_t
00359 uip_fw_output(void)
00360 {
00361 struct uip_fw_netif *netif;
00362
00363 if(uip_len == 0) {
00364 return UIP_FW_ZEROLEN;
00365 }
00366
00367 fwcache_register();
00368
00369 #if UIP_BROADCAST
00370
00371 if(
00372 BUF->destipaddr[0] == 0xffff &&
00373 BUF->destipaddr[1] == 0xffff) {
00374 if(defaultnetif != NULL) {
00375 defaultnetif->output();
00376 }
00377 for(netif = netifs; netif != NULL; netif = netif->next) {
00378 netif->output();
00379 }
00380 return UIP_FW_OK;
00381 }
00382 #endif
00383
00384 netif = find_netif();
00385
00386
00387
00388
00389 if(netif == NULL) {
00390 return UIP_FW_NOROUTE;
00391 }
00392
00393
00394 return netif->output();
00395 }
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406 u8_t
00407 uip_fw_forward(void)
00408 {
00409 struct fwcache_entry *fw;
00410
00411
00412
00413 if(BUF->destipaddr[0] == uip_hostaddr[0] &&
00414 BUF->destipaddr[1] == uip_hostaddr[1]) {
00415 return UIP_FW_LOCAL;
00416 }
00417
00418
00419
00420 #if UIP_PINGADDRCONF
00421 if((uip_hostaddr[0] | uip_hostaddr[1]) == 0 &&
00422 BUF->proto == UIP_PROTO_ICMP &&
00423 ICMPBUF->type == ICMP_ECHO) {
00424 return UIP_FW_LOCAL;
00425 }
00426 #endif
00427
00428
00429
00430
00431 for(fw = fwcache; fw < &fwcache[FWCACHE_SIZE]; ++fw) {
00432 if(fw->timer != 0 &&
00433 #if UIP_REASSEMBLY > 0
00434 fw->len == BUF->len &&
00435 fw->offset == BUF->ipoffset &&
00436 #endif
00437 fw->ipid == BUF->ipid &&
00438 fw->srcipaddr[0] == BUF->srcipaddr[0] &&
00439 fw->srcipaddr[1] == BUF->srcipaddr[1] &&
00440 fw->destipaddr[0] == BUF->destipaddr[0] &&
00441 fw->destipaddr[1] == BUF->destipaddr[1] &&
00442 #if notdef
00443 fw->payload[0] == BUF->srcport &&
00444 fw->payload[1] == BUF->destport &&
00445 #endif
00446 fw->proto == BUF->proto) {
00447
00448 return UIP_FW_FORWARDED;
00449 }
00450 }
00451
00452
00453
00454
00455 if(BUF->ttl <= 1) {
00456
00457 if(BUF->destipaddr[0] == 0xffff && BUF->destipaddr[1] == 0xffff) {
00458 return UIP_FW_LOCAL;
00459 }
00460 time_exceeded();
00461 }
00462
00463
00464 BUF->ttl = BUF->ttl - 1;
00465
00466
00467 if(BUF->ipchksum >= HTONS(0xffff - 0x0100)) {
00468 BUF->ipchksum = BUF->ipchksum + HTONS(0x0100) + 1;
00469 } else {
00470 BUF->ipchksum = BUF->ipchksum + HTONS(0x0100);
00471 }
00472
00473 if(uip_len > 0) {
00474 uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_TCPIP_HLEN];
00475 uip_fw_output();
00476 }
00477
00478 #if UIP_BROADCAST
00479 if(BUF->destipaddr[0] == 0xffff && BUF->destipaddr[1] == 0xffff) {
00480 return UIP_FW_LOCAL;
00481 }
00482 #endif
00483
00484
00485
00486 return UIP_FW_FORWARDED;
00487 }
00488
00489
00490
00491
00492
00493
00494
00495
00496 void
00497 uip_fw_register(struct uip_fw_netif *netif)
00498 {
00499 netif->next = netifs;
00500 netifs = netif;
00501 }
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513 void
00514 uip_fw_default(struct uip_fw_netif *netif)
00515 {
00516 defaultnetif = netif;
00517 }
00518
00519
00520
00521
00522
00523 void
00524 uip_fw_periodic(void)
00525 {
00526 struct fwcache_entry *fw;
00527 for(fw = fwcache; fw < &fwcache[FWCACHE_SIZE]; ++fw) {
00528 if(fw->timer > 0) {
00529 --fw->timer;
00530 }
00531 }
00532 }
00533
00534
00535