📄 ip.cc
字号:
#include "root.h"#include <lib/string.h>#include "ip.h"#include "udp.h"#include "tcp.h"#include "icmp.h"#include "raw.h"#include "arp.h"ipstat_t ipstat;void ipaddhead(pkt_t *pkt, u8_t proto, u32_t saddr, u32_t daddr){ static u32_t initippktid; pkt->addhead(sizeof(iphdr_t)); iphdr_t *ih = (iphdr_t*)pkt->data; ih->ihl = sizeof(iphdr_t) >> 2; ih->ver = IPVER4; ih->tos = 0; ih->totlen = htons(pkt->datalen); ih->id = htons(initippktid++); ih->frag = htons(0); ih->ttl = 255; ih->proto = proto; ih->chksum = 0; ih->saddr = saddr; ih->daddr = daddr; ih->chksum = ipchksum(ih, sizeof(iphdr_t));}/* 1) this function is only used to transmit packet generated by local host 2) upper protocol layer _must_ guarantee the size of packet sent by local host doesn't exceed mtu. */int ipoutput(pkt_t * pkt, u8_t proto, u32_t saddr, u32_t daddr, u16_t *chksum){ netdev_t * netdev; u32_t nexthop; int e = selectroute(daddr, &netdev, &nexthop); if (e) { printd("ipoutput:selectroute failed\n"); delpkt(pkt); return e; } if (saddr == INADDRANY) saddr = netdev->praddr; /* we do the tcp chksum until the saddr is resovled */ if (chksum) { assert(*chksum == 0); *chksum = ipchksumpseudo(saddr, daddr, proto, pkt->datalen, pkt->data); } ipaddhead(pkt, proto, saddr, daddr); assert(pkt->datalen <= netdev->mtu); return netdev->output(pkt, nexthop);}void ipforward(pkt_t * pkt){ iphdr_t * ih = (iphdr_t*) pkt->data; netdev_t *netdev; u32_t nexthop; int e = selectroute(ih->daddr, &netdev, &nexthop); if (e) { printf("ipforward failed\n"); delpkt(pkt); return; } netdev->output(pkt, nexthop);}void ipinput(pkt_t *pkt){ iphdr_t *ih = (iphdr_t*) pkt->data; ipstat.total++; debug(NETFLOWDBG, "saddr=%s daddr=%s\n", inetntoa(ih->saddr), inetntoa(ih->daddr)); /* do some check */ if (ih->ver != IPVER4) { ipstat.badver++; printd("bad version number\n"); delpkt(pkt); return; } if (ih->headlen() != sizeof(iphdr_t)) { printd("don't support IP options yet\n"); delpkt(pkt); return; } if (ipchksum(ih, ih->headlen())) { ipstat.badchksum++; printd("bad check sum"); delpkt(pkt); return; } if (ntohs(ih->totlen) < pkt->datalen) pkt->trimto(ntohs(ih->totlen)); /* reassemble the packet if needed */ if (ih->fraged()) { if (!(pkt = ipreass(pkt))) return; } /* if the packet is not for this host, forward it */ if (!tothishost(ih->daddr)) { ipforward(pkt); return; } /* deliver the packet to upper protocol */ switch (ih->proto) { case IPPROTOTCP: tcpinput(pkt); return; case IPPROTOUDP: udpinput(pkt); return; case IPPROTOICMP: if (icmpinput(pkt)) return; } if (rawinput(pkt)) return; printd("ipinput:unknown protocol %d\n", ih->proto); icmpoutput(pkt, ICTDSTUNREACH, ICCPROTOUNREACH); delpkt(pkt);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -