176404edcSAsim Jamshed #define __MOS_CORE_
276404edcSAsim Jamshed
376404edcSAsim Jamshed #include <string.h>
476404edcSAsim Jamshed #include <netinet/ip.h>
576404edcSAsim Jamshed #include <stdbool.h>
676404edcSAsim Jamshed
776404edcSAsim Jamshed #include "ip_in.h"
876404edcSAsim Jamshed #include "ip_out.h"
976404edcSAsim Jamshed #include "tcp.h"
1076404edcSAsim Jamshed #include "mtcp_api.h"
1176404edcSAsim Jamshed #include "debug.h"
1276404edcSAsim Jamshed #include "mos_api.h"
1376404edcSAsim Jamshed #include "icmp.h"
1476404edcSAsim Jamshed #include "config.h"
1576404edcSAsim Jamshed
1676404edcSAsim Jamshed #define ETH_P_IP_FRAG 0xF800
1776404edcSAsim Jamshed #define ETH_P_IPV6_FRAG 0xF6DD
1876404edcSAsim Jamshed
1976404edcSAsim Jamshed
2076404edcSAsim Jamshed /*----------------------------------------------------------------------------*/
2176404edcSAsim Jamshed inline void
FillInPacketIPContext(struct pkt_ctx * pctx,struct iphdr * iph,int ip_len)2276404edcSAsim Jamshed FillInPacketIPContext (struct pkt_ctx *pctx, struct iphdr *iph, int ip_len)
2376404edcSAsim Jamshed {
2476404edcSAsim Jamshed pctx->p.iph = iph;
2576404edcSAsim Jamshed pctx->p.ip_len = ip_len;
2676404edcSAsim Jamshed
2776404edcSAsim Jamshed return;
2876404edcSAsim Jamshed }
2976404edcSAsim Jamshed /*----------------------------------------------------------------------------*/
3076404edcSAsim Jamshed inline int
ProcessInIPv4Packet(mtcp_manager_t mtcp,struct pkt_ctx * pctx)3176404edcSAsim Jamshed ProcessInIPv4Packet(mtcp_manager_t mtcp, struct pkt_ctx *pctx)
3276404edcSAsim Jamshed {
3376404edcSAsim Jamshed bool release = false;
3476404edcSAsim Jamshed int ret;
3576404edcSAsim Jamshed struct mon_listener *walk;
3676404edcSAsim Jamshed /* check and process IPv4 packets */
3776404edcSAsim Jamshed struct iphdr* iph =
3876404edcSAsim Jamshed (struct iphdr *)((char *)pctx->p.ethh + sizeof(struct ethhdr));
3976404edcSAsim Jamshed int ip_len = ntohs(iph->tot_len);
4076404edcSAsim Jamshed
4176404edcSAsim Jamshed /* drop the packet shorter than ip header */
4276404edcSAsim Jamshed if (ip_len < sizeof(struct iphdr)) {
4376404edcSAsim Jamshed ret = ERROR;
4476404edcSAsim Jamshed goto __return;
4576404edcSAsim Jamshed }
4676404edcSAsim Jamshed
4776404edcSAsim Jamshed if (iph->version != IPVERSION ) {
4876404edcSAsim Jamshed release = true;
4976404edcSAsim Jamshed ret = FALSE;
5076404edcSAsim Jamshed goto __return;
5176404edcSAsim Jamshed }
5276404edcSAsim Jamshed
5376404edcSAsim Jamshed FillInPacketIPContext(pctx, iph, ip_len);
5476404edcSAsim Jamshed
55*05e3289cSYoungGyoun /* callback for monitor raw socket */
56*05e3289cSYoungGyoun TAILQ_FOREACH(walk, &mtcp->monitors, link)
57*05e3289cSYoungGyoun if (walk->socket->socktype == MOS_SOCK_MONITOR_RAW) {
58*05e3289cSYoungGyoun if (ISSET_BPFFILTER(walk->raw_pkt_fcode) &&
59*05e3289cSYoungGyoun EVAL_BPFFILTER(walk->raw_pkt_fcode, (uint8_t *)pctx->p.ethh,
60*05e3289cSYoungGyoun pctx->p.eth_len))
61*05e3289cSYoungGyoun HandleCallback(mtcp, MOS_NULL, walk->socket, MOS_SIDE_BOTH,
62*05e3289cSYoungGyoun pctx, MOS_ON_PKT_IN);
63*05e3289cSYoungGyoun }
64*05e3289cSYoungGyoun
65*05e3289cSYoungGyoun /* if there is no MOS_SOCK_STREAM or MOS_SOCK_MONITOR_STREAM socket,
66*05e3289cSYoungGyoun forward IP packet before reaching upper (transport) layer */
67*05e3289cSYoungGyoun if (mtcp->num_msp == 0 && mtcp->num_esp == 0) {
68*05e3289cSYoungGyoun if (pctx->forward) {
69*05e3289cSYoungGyoun ForwardIPPacket(mtcp, pctx);
70*05e3289cSYoungGyoun }
71*05e3289cSYoungGyoun return TRUE;
72*05e3289cSYoungGyoun }
73*05e3289cSYoungGyoun
74*05e3289cSYoungGyoun if (ip_fast_csum(iph, iph->ihl)) {
75*05e3289cSYoungGyoun ret = ERROR;
76*05e3289cSYoungGyoun goto __return;
77*05e3289cSYoungGyoun }
78*05e3289cSYoungGyoun
7976404edcSAsim Jamshed switch (iph->protocol) {
8076404edcSAsim Jamshed case IPPROTO_TCP:
8176404edcSAsim Jamshed return ProcessInTCPPacket(mtcp, pctx);
8276404edcSAsim Jamshed case IPPROTO_ICMP:
8376404edcSAsim Jamshed if (ProcessICMPPacket(mtcp, pctx))
8476404edcSAsim Jamshed return TRUE;
8576404edcSAsim Jamshed default:
8676404edcSAsim Jamshed /* forward other protocols without any processing */
8776404edcSAsim Jamshed if (!mtcp->num_msp || !pctx->forward)
8876404edcSAsim Jamshed release = true;
8976404edcSAsim Jamshed else
9076404edcSAsim Jamshed ForwardIPPacket(mtcp, pctx);
9176404edcSAsim Jamshed
9276404edcSAsim Jamshed ret = FALSE;
9376404edcSAsim Jamshed goto __return;
9476404edcSAsim Jamshed }
9576404edcSAsim Jamshed
9676404edcSAsim Jamshed __return:
9776404edcSAsim Jamshed if (release && mtcp->iom->release_pkt)
98a834ea89SAsim Jamshed mtcp->iom->release_pkt(mtcp->ctx, pctx->p.in_ifidx,
9976404edcSAsim Jamshed (unsigned char *)pctx->p.ethh, pctx->p.eth_len);
10076404edcSAsim Jamshed return ret;
10176404edcSAsim Jamshed }
10276404edcSAsim Jamshed /*----------------------------------------------------------------------------*/
103