xref: /mOS-networking-stack/core/src/ip_in.c (revision 05e3289c)
1 #define __MOS_CORE_
2 
3 #include <string.h>
4 #include <netinet/ip.h>
5 #include <stdbool.h>
6 
7 #include "ip_in.h"
8 #include "ip_out.h"
9 #include "tcp.h"
10 #include "mtcp_api.h"
11 #include "debug.h"
12 #include "mos_api.h"
13 #include "icmp.h"
14 #include "config.h"
15 
16 #define ETH_P_IP_FRAG   0xF800
17 #define ETH_P_IPV6_FRAG 0xF6DD
18 
19 
20 /*----------------------------------------------------------------------------*/
21 inline void
FillInPacketIPContext(struct pkt_ctx * pctx,struct iphdr * iph,int ip_len)22 FillInPacketIPContext (struct pkt_ctx *pctx, struct iphdr *iph, int ip_len)
23 {
24 	pctx->p.iph = iph;
25 	pctx->p.ip_len = ip_len;
26 
27 	return;
28 }
29 /*----------------------------------------------------------------------------*/
30 inline int
ProcessInIPv4Packet(mtcp_manager_t mtcp,struct pkt_ctx * pctx)31 ProcessInIPv4Packet(mtcp_manager_t mtcp, struct pkt_ctx *pctx)
32 {
33 	bool release = false;
34 	int ret;
35 	struct mon_listener *walk;
36 	/* check and process IPv4 packets */
37 	struct iphdr* iph =
38 		(struct iphdr *)((char *)pctx->p.ethh + sizeof(struct ethhdr));
39 	int ip_len = ntohs(iph->tot_len);
40 
41 	/* drop the packet shorter than ip header */
42 	if (ip_len < sizeof(struct iphdr)) {
43 		ret = ERROR;
44 		goto __return;
45 	}
46 
47 	if (iph->version != IPVERSION ) {
48 		release = true;
49 		ret = FALSE;
50 		goto __return;
51 	}
52 
53 	FillInPacketIPContext(pctx, iph, ip_len);
54 
55 	/* callback for monitor raw socket */
56 	TAILQ_FOREACH(walk, &mtcp->monitors, link)
57 		if (walk->socket->socktype == MOS_SOCK_MONITOR_RAW) {
58 			if (ISSET_BPFFILTER(walk->raw_pkt_fcode) &&
59 				EVAL_BPFFILTER(walk->raw_pkt_fcode, (uint8_t *)pctx->p.ethh,
60 							   pctx->p.eth_len))
61 				HandleCallback(mtcp, MOS_NULL, walk->socket, MOS_SIDE_BOTH,
62 							   pctx, MOS_ON_PKT_IN);
63 		}
64 
65 	/* if there is no MOS_SOCK_STREAM or MOS_SOCK_MONITOR_STREAM socket,
66 	   forward IP packet before reaching upper (transport) layer */
67 	if (mtcp->num_msp == 0 && mtcp->num_esp == 0) {
68 		if (pctx->forward) {
69 			ForwardIPPacket(mtcp, pctx);
70 		}
71 		return TRUE;
72 	}
73 
74 	if (ip_fast_csum(iph, iph->ihl)) {
75 		ret = ERROR;
76 		goto __return;
77 	}
78 
79 	switch (iph->protocol) {
80 		case IPPROTO_TCP:
81 			return ProcessInTCPPacket(mtcp, pctx);
82 		case IPPROTO_ICMP:
83 			if (ProcessICMPPacket(mtcp, pctx))
84 				return TRUE;
85 		default:
86 			/* forward other protocols without any processing */
87 			if (!mtcp->num_msp || !pctx->forward)
88 				release = true;
89 			else
90 				ForwardIPPacket(mtcp, pctx);
91 
92 			ret = FALSE;
93 			goto __return;
94 	}
95 
96 __return:
97 	if (release && mtcp->iom->release_pkt)
98 		mtcp->iom->release_pkt(mtcp->ctx, pctx->p.in_ifidx,
99 				       (unsigned char *)pctx->p.ethh, pctx->p.eth_len);
100 	return ret;
101 }
102 /*----------------------------------------------------------------------------*/
103