📄 netip.c
字号:
* This is where route lookup could occur.
*/
void ipRawOut(NBuf* nb)
{
ipDispatch(nb);
}
/*
* ripInput - Handle raw IP packets.
*/
void ripInput(NBuf* nb)
{
IPDEBUG((LOG_INFO, TL_IP, "rip_input: dropping packet"));
nFreeChain(nb);
STATS(ipStats.ips_odropped.val++;)
}
/*
* ipIOCtl - Get and set IP I/O configuration.
*/
int ipIOCtl(short cmd, void* arg)
{
return 0;
}
/*
* ipOptStrip - Strip off the options from the head of the buffer.
* If the operation fails (likely failure to allocate a new nBuf),
* then the situation is considered unrecoverable and the buffer
* chain is dropped.
* Return the resulting buffer chain.
*/
NBuf* ipOptStrip(NBuf* inBuf, u_int ipHeadLen)
{
int optSize = ipHeadLen - sizeof(IPHdr);
NBuf* n0;
if (optSize < 0 || (n0 = nSplit(inBuf, ipHeadLen)) == NULL) {
nFreeChain(inBuf);
inBuf = NULL;
STATS(ipStats.ips_odropped.val++;)
} else if (nTrim(NULL, &inBuf, -optSize) < optSize) {
nFreeChain(n0);
nFreeChain(inBuf);
inBuf = NULL;
STATS(ipStats.ips_odropped.val++;)
} else
inBuf = nCat(inBuf, n0);
return inBuf;
}
/*
* ipMTU - Return the size in bytes of the Maximum Transmission Unit for the
* given destination or zero if the destination is not reachable.
*/
u_int ipMTU(u_long dstAddr)
{
u_int st;
if (dstAddr == htonl(localHost) || dstAddr == htonl(LOOPADDR))
st = NBUFSZ;
else switch (defIfType) {
#if PPP_SUPPORT > 0
case IFT_PPP:
st = pppMTU(defIfID);
break;
#endif
#if ETHER_SUPPORT > 0
case IFT_ETH:
// st = ethMTU(defIfID);
break;
#endif
default:
st = 0;
break;
}
IPDEBUG((LOG_INFO, TL_IP, "ipMTU: dst %s => %u", ip_ntoa(dstAddr), st));
return st;
}
/*
* ipSetDefault - set the default route.
*/
void ipSetDefault(u_int32_t l, u_int32_t g, IfType ifType, int ifID)
{
localHost = ntohl(l);
defIPAddr = g;
defIfType = ifType;
defIfID = ifID;
IPDEBUG((LOG_INFO, TL_IP, "ipSetDefault: %s %s %d %d",
ip_ntoa(l),
ip_ntoa2(g),
ifType, ifID));
}
/*
* ipClearDefault - clear the default route.
*/
void ipClearDefault(void)
{
defIPAddr = 0;
defIfType = IFT_UNSPEC;
defIfID = 0;
IPDEBUG((LOG_INFO, TL_IP, "ipClearDefault"));
}
/*
* Make a string representation of a network IP address.
* WARNING: NOT RE-ENTRANT!
*/
char *ip_ntoa(u_int32_t ipaddr)
{
static char b[20];
ipaddr = ntohl(ipaddr);
sprintf(b, "%d.%d.%d.%d",
(u_char)(ipaddr >> 24),
(u_char)(ipaddr >> 16),
(u_char)(ipaddr >> 8),
(u_char)(ipaddr));
return b;
}
/* A second buffer if you want 2 addresses in one printf. */
char *ip_ntoa2(u_int32_t ipaddr)
{
static char b[20];
ipaddr = ntohl(ipaddr);
sprintf(b, "%d.%d.%d.%d",
(u_char)(ipaddr >> 24),
(u_char)(ipaddr >> 16),
(u_char)(ipaddr >> 8),
(u_char)(ipaddr));
return b;
}
/*
* Make a string representation of a host IP address.
* WARNING: NOT RE-ENTRANT!
*/
char *ip_htoa(u_int32_t ipaddr)
{
static char b[20];
sprintf(b, "%d.%d.%d.%d",
(u_char)(ipaddr >> 24),
(u_char)(ipaddr >> 16),
(u_char)(ipaddr >> 8),
(u_char)(ipaddr));
return b;
}
/**********************************/
/*** LOCAL FUNCTION DEFINITIONS ***/
/**********************************/
/*
* ipDispatch - Dispatch a "prepared" IP datagram according to it's source
* and destination IP addresses and its protocol.
* By prepared, the buffer's data pointer references the start of the IP
* header and the length, identification, and offset fields are in HOST
* byte order. The IP address fields are in network byte order.
*/
static void ipDispatch(NBuf *outBuf)
{
IPHdr *ip = nBUFTOPTR(outBuf, IPHdr *);
u_char hdrLen = ip->ip_hl * 4;
u_long srcAddr = ip->ip_src.s_addr;
u_long dstAddr = ip->ip_dst.s_addr;
IPDEBUG((LOG_INFO, TL_IP, "ipDispatch: len %u proto %u to %s from %s tos %d",
ip->ip_len, ip->ip_p,
ip_ntoa(dstAddr),
ip_ntoa2(srcAddr),
ip->ip_tos));
/* Validata the IP header. */
if (ip->ip_len < hdrLen) {
IPDEBUG((LOG_ERR, TL_IP, "ipDispatch: Dropped short len %u proto %u to %s from %s",
ip->ip_len,
ip->ip_p,
ip_ntoa(dstAddr),
ip_ntoa2(srcAddr)));
STATS(ipStats.ips_badlen.val++;)
nFreeChain(outBuf);
}
/* If destined for us, dispatch according to the protocol. */
/*
* Note: We catch the loopback address here instead of passing it
* to a loopback interface so that this one dispatch function may
* handle both input and output.
*/
else if (dstAddr == htonl(localHost) || dstAddr == htonl(LOOPADDR)) {
switch (ip->ip_p) {
case IPPROTO_ICMP:
icmpInput(outBuf, hdrLen);
break;
case IPPROTO_TCP:
tcpInput(outBuf, hdrLen);
break;
#if UDP_SUPPORT > 0
case IPPROTO_UDP:
udpInput(outBuf, hdrLen);
break;
#endif
default:
IPDEBUG((LOG_ERR, TL_IP,
"ipDispatch: Dropped bad protocol %d, len %u from %s to %s",
ip->ip_p,
ip->ip_len,
ip_ntoa(dstAddr),
ip_ntoa2(srcAddr)));
nFreeChain(outBuf);
STATS(ipStats.ips_odropped.val++;)
}
}
/*
* Otherwise, if not from us, we're not a router so drop it.
* XXX We could (should?) send an ICMP message.
*/
else if (srcAddr != htonl(localHost)) {
IPDEBUG((LOG_ERR, TL_IP,
"ipDispatch: Dropped can't fwd len %u proto %u to %s from %s",
ip->ip_len, ip->ip_p,
ip_ntoa(dstAddr),
ip_ntoa2(srcAddr)));
STATS(ipStats.ips_cantforward.val++;)
nFreeChain(outBuf);
}
/* If we made it here, send it out. */
else switch (defIfType) {
#if PPP_SUPPORT > 0
case IFT_PPP:
/* Convert fields to network representation. */
HTONS(ip->ip_len);
HTONS(ip->ip_id);
HTONS(ip->ip_off);
/* Checksum the header. */
ip->ip_sum = 0;
ip->ip_sum = inChkSum(outBuf, hdrLen, 0);
pppOutput(defIfID, PPP_IP, outBuf);
STATS(ipStats.ips_delivered.val++;)
break;
#endif
#if ETHER_SUPPORT > 0
case IFT_ETH:
/* Convert fields to network representation. */
HTONS(ip->ip_len);
HTONS(ip->ip_id);
HTONS(ip->ip_off);
/* Checksum the header. */
ip->ip_sum = 0;
ip->ip_sum = inChkSum(outBuf, hdrLen, 0);
etherOutput(outBuf);
// ethOutput(defIfID, PPP_IP, outBuf);
STATS(ipStats.ips_delivered.val++;)
break;
#endif
default:
IPDEBUG((LOG_ERR, TL_IP,
"ipDispatch: Dropped bad if %d len %u proto %u to %s from %s",
defIfType,
ip->ip_len, ip->ip_p,
ip_ntoa(dstAddr),
ip_ntoa2(srcAddr)));
nFreeChain(outBuf);
STATS(ipStats.ips_odropped.val++;)
break;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -