xref: /mOS-networking-stack/core/src/ip_in.c (revision dcdbbb98)
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
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
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 (ip_fast_csum(iph, iph->ihl)) {
48 		ret = ERROR;
49 		goto __return;
50 	}
51 
52 	if (iph->version != IPVERSION ) {
53 		release = true;
54 		ret = FALSE;
55 		goto __return;
56 	}
57 
58 	FillInPacketIPContext(pctx, iph, ip_len);
59 
60 	switch (iph->protocol) {
61 		case IPPROTO_TCP:
62 			return ProcessInTCPPacket(mtcp, pctx);
63 		case IPPROTO_ICMP:
64 			if (ProcessICMPPacket(mtcp, pctx))
65 				return TRUE;
66 		default:
67 			/* forward other protocols without any processing */
68 			if (!mtcp->num_msp || !pctx->forward)
69 				release = true;
70 			else
71 				ForwardIPPacket(mtcp, pctx);
72 
73 			ret = FALSE;
74 			goto __return;
75 	}
76 
77 __return:
78 	/* callback for monitor raw socket */
79 	TAILQ_FOREACH(walk, &mtcp->monitors, link)
80 		if (walk->socket->socktype == MOS_SOCK_MONITOR_RAW)
81 			HandleCallback(mtcp, MOS_NULL, walk->socket, MOS_SIDE_BOTH,
82 				       pctx, MOS_ON_PKT_IN);
83 	if (release && mtcp->iom->release_pkt)
84 		mtcp->iom->release_pkt(mtcp->ctx, pctx->p.in_ifidx,
85 				       (unsigned char *)pctx->p.ethh, pctx->p.eth_len);
86 	return ret;
87 }
88 /*----------------------------------------------------------------------------*/
89