📄 ipsend.c
字号:
/* Beholder RMON ethernet network monitor,Copyright (C) 1993 DNPAP group *//* See file COPYING 'GNU General Public Licence' for copyright details */#include <memory.h>#include <mac.h>#include "ip.h"#include "ipiface.h"#include "iproute.h"#include "iphdr.h"#include "ipsend.h"static BOOLEAN SendRouted(CHAIN *chain, IP_HDR *ipHdr, IP_ROUTE_ROUTE *route);static BOOLEAN SendFragmented(CHAIN *chain, IP_HDR *ipHdr, IP_ROUTE_ROUTE *route);static void SendQueued(MAC_IFACE *iface, ARP_ENTRY *entry, void *specific);BOOLEAN IpSend(CHAIN *chain, IP_HDR *ipHdr){ IP_ROUTE_ROUTE route; IP_IFACE *iface; BOOLEAN success; CHAIN head; if (IpRouteIsBroadcast(ipHdr->dst)) { route.metric = 16; route.addr = ipHdr->dst; route.broadcast = TRUE; success = TRUE; for (iface = ipIfaceList; iface != 0; iface = iface->next) { route.iface = iface; memcpy(&head, chain, sizeof(CHAIN)); success = success && SendRouted(&head, ipHdr, &route); } } else { if (IpRouteFind(ipHdr->dst, &route)) { success = SendRouted(chain, ipHdr, &route); } else { success = FALSE; } } return success;}static BOOLEAN SendRouted(CHAIN *chain, IP_HDR *ipHdr, IP_ROUTE_ROUTE *route){ CHAIN head, tail; WORD mtu, blocks, offset; BYTE flags; BOOLEAN success = FALSE; ipHdr->ihl = 20 + ipHdr->iol; if (ipHdr->src == IP_ADDR_THIS) ipHdr->src = route->iface->addr; mtu = route->iface->iface->mtu; if ((WORD)(ipHdr->ihl + ChainLength(chain)) < mtu) { success = SendFragmented(chain, ipHdr, route); } else { if ((ipHdr->flags & IP_FLAG_DONT_FRAGMENT) != IP_FLAG_DONT_FRAGMENT) { blocks = (mtu - ipHdr->ihl) / 8; flags = ipHdr->flags; offset = ipHdr->offset; ipHdr->flags |= IP_FLAG_MORE_FRAGMENTS; success = TRUE; memcpy(&head, chain, sizeof(head)); while (ChainSplit(&head, &tail, blocks * 8)) { if (!SendFragmented(&head, ipHdr, route)) { success = FALSE; break; } memcpy(&head, &tail, sizeof(head)); ipHdr->offset += blocks; } if (success) { ipHdr->flags = flags; success = SendFragmented(&head, ipHdr, route); } ipHdr->flags = flags; ipHdr->offset = offset; } } return success;}static BOOLEAN SendFragmented(CHAIN *chain, IP_HDR *ipHdr, IP_ROUTE_ROUTE *route){ DWORD addr; ARP_ENTRY *arp; BOOLEAN success; WORD n; MAC_HDR macHdr; MAC_IFACE *iface; CHAIN *new, *copy; ipHdr->ttl = (BYTE)route->metric; new = IpHdrEncode(chain, ipHdr); if (new != 0) { iface = route->iface->iface; macHdr.src = route->iface->iface->addr; macHdr.type = MAC_PROT_IP; if (route->broadcast || iface->arp==MAC_ARP_NONE) { macHdr.dst = iface->addrBroadcast; macHdr.broadcast = TRUE; success = MacSend(iface, new, &macHdr); } else { addr = IpH2NDWord(route->addr); arp = ArpFind(iface, MAC_PROT_IP, (BYTE *)&addr); if (arp != 0) { macHdr.dst = arp->addrHard; macHdr.broadcast = FALSE; success = MacSend(iface, new, &macHdr); } else { n = ChainLength(new); copy = ChainAlloc(0, 0, n, n, 0, 0); ChainCopy(new, copy->buffer, n); success = ArpRequest(iface, MAC_PROT_IP, (BYTE *)&addr, SendQueued, copy); } } if (new != chain) ChainFree(new); } return success;}static void SendQueued(MAC_IFACE *iface, ARP_ENTRY *entry, void *specific){ MAC_HDR macHdr; CHAIN *chain; chain = (CHAIN *)specific; if (entry!=0) { macHdr.src = iface->addr; macHdr.dst = entry->addrHard; macHdr.type = MAC_PROT_IP; macHdr.broadcast = FALSE; MacSend(iface, chain, &macHdr); } ChainFree(chain);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -