/* * Copyright (c) 2001 Fenris, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * File: parser.c * * Purpose: This source file defines the interface for parser(). This * function is a nested switch case statement that takes a packet through * the layers of the known protocols (TCP/IP stack as of rev 1.) A packet * header object (as declared in headers.h) is populated by this function. * */ #include /* ntoh[ls]() BSD */ #include /* ntoh[ls]() Linux */ #include "headers.h" /* packet_headers */ #include "parser.h" int parse(const unsigned char *buf, Packet_Headers *p) { p->ll.eth = (Eth_Header *)buf; p->ll.eth->eth_typ = ntohs(p->ll.eth->eth_typ); buf += 14; switch (p->ll.eth->eth_typ) { case ETH_TYP_ARP: case ETH_TYP_RARP: p->type = arp_t; p->nl.arp = (Arp_Header *)buf; p->nl.arp->arp_hrd_typ = ntohs(p->nl.arp->arp_hrd_typ); p->nl.arp->arp_prt_typ = ntohs(p->nl.arp->arp_prt_typ); p->nl.arp->arp_typ = ntohs(p->nl.arp->arp_typ); buf += 28; break; case ETH_TYP_IP: p->nl.ip = (Ip_Header *)buf; p->nl.ip->ip_pkt_len = ntohs(p->nl.ip->ip_pkt_len); p->nl.ip->ip_id = ntohs(p->nl.ip->ip_id); p->nl.ip->ip_frg_off = ntohs(p->nl.ip->ip_frg_off); p->nl.ip->ip_chksum = ntohs(p->nl.ip->ip_chksum); p->nl.ip->ip_src = ntohl(p->nl.ip->ip_src); p->nl.ip->ip_dst = ntohl(p->nl.ip->ip_dst); buf += (p->nl.ip->ip_hdr_len * 4); switch (p->nl.ip->ip_protocol) { case IP_PRT_TCP: p->type = tcp_t; p->tl.tcp = (Tcp_Header *)buf; p->tl.tcp->tcp_src_port = ntohs(p->tl.tcp->tcp_src_port); p->tl.tcp->tcp_dst_port = ntohs(p->tl.tcp->tcp_dst_port); p->tl.tcp->tcp_seq_num = ntohl(p->tl.tcp->tcp_seq_num); p->tl.tcp->tcp_ack_num = ntohl(p->tl.tcp->tcp_ack_num); p->tl.tcp->tcp_win_siz = ntohs(p->tl.tcp->tcp_win_siz); p->tl.tcp->tcp_chksum = ntohs(p->tl.tcp->tcp_chksum); p->tl.tcp->tcp_urg_ptr = ntohs(p->tl.tcp->tcp_urg_ptr); buf += (p->tl.tcp->tcp_hdr_len * 4); break; case IP_PRT_UDP: p->type = udp_t; p->tl.udp = (Udp_Header *)buf; p->tl.udp->udp_src_port = ntohs(p->tl.udp->udp_src_port); p->tl.udp->udp_dst_port = ntohs(p->tl.udp->udp_dst_port); p->tl.udp->udp_len = ntohs(p->tl.udp->udp_len); p->tl.udp->udp_chksum = ntohs(p->tl.udp->udp_chksum); buf += 8; break; case IP_PRT_ICMP: p->type = icmp_t; p->tl.icmp = (Icmp_Header *)buf; p->tl.icmp->icmp_chksum = ntohs(p->tl.icmp->icmp_chksum); buf += 4; break; case IP_PRT_IGMP: p->type = igmp_t; p->tl.igmp = (Igmp_Header *)buf; p->tl.igmp->igmp_chksum = ntohs(p->tl.igmp->igmp_chksum); buf += 8; break; default: return -1; break; } break; default: return -1; break; } p->data = buf; return 0; }