Example #1
0
static void
ipt_log_packet(unsigned int pf,
	       unsigned int hooknum,
	       const struct sk_buff *skb,
	       const struct net_device *in,
	       const struct net_device *out,
	       const struct nf_loginfo *loginfo,
	       const char *prefix)
{
	if (!loginfo)
		loginfo = &default_loginfo;

	spin_lock_bh(&log_lock);
	printk("<%d>%sIN=%s OUT=%s ", loginfo->u.log.level,
	       prefix,
	       in ? in->name : "",
	       out ? out->name : "");
#ifdef CONFIG_BRIDGE_NETFILTER
	if (skb->nf_bridge) {
		struct net_device *physindev = skb->nf_bridge->physindev;
		struct net_device *physoutdev = skb->nf_bridge->physoutdev;

		if (physindev && in != physindev)
			printk("PHYSIN=%s ", physindev->name);
		if (physoutdev && out != physoutdev)
			printk("PHYSOUT=%s ", physoutdev->name);
	}
#endif

	if (in && !out) {
		/* MAC logging for input chain only. */
		printk("MAC=");
		if (skb->dev && skb->dev->hard_header_len
		    && skb->mac.raw != (void*)skb->nh.iph) {
			int i;
			unsigned char *p = skb->mac.raw;
			for (i = 0; i < skb->dev->hard_header_len; i++,p++)
				printk("%02x%c", *p,
				       i==skb->dev->hard_header_len - 1
				       ? ' ':':');
		} else
			printk(" ");
	}

	dump_packet(loginfo, skb, 0);
	printk("\n");
	spin_unlock_bh(&log_lock);
}
Example #2
0
int
main(int argc, char *argv[])
{
	int			 ch, i, r;
	uint16_t		 type = T_A;
	char			 buf[1024], *host;

	while((ch = getopt(argc, argv, "et:")) !=  -1) {
		switch(ch) {
		case 'e':
			long_err += 1;
			break;
		case 't':
			if ((type = strtotype(optarg)) == 0)
				usage();
			break;
		default:
			usage();
			/* NOTREACHED */
		}
	}
	argc -= optind;
	argv += optind;

	for (i = 0; i < argc; i++) {

		if (i)
			printf("\n");

		printf("===> \"%s\"\n", argv[i]);
		host = gethostarg(argv[i]);

		errno = 0;
		h_errno = 0;
		gai_errno = 0;
		rrset_errno = 0;

		r = res_mkquery(QUERY, host, C_IN, type, NULL, 0, NULL, buf, sizeof(buf));
		if (r != -1) {
			dump_packet(buf, r);
			printf(";; MSG SIZE %i\n", r);
		}
		print_errors();
	}

	return (0);
}
Example #3
0
void dump_to_file(struct dump_file *dump_file, 
                  void *pip, 
                  void *plast)
{
    //open a new dump file
    if (dump_file->win_start.tv_sec == -1 &&
        dump_file->win_start.tv_usec == -1) {
        dump_file->fp = new_dump_file(dump_file);
        dump_file->win_start.tv_sec = current_time.tv_sec;
        dump_file->win_start.tv_usec = current_time.tv_usec;
    }
    else if (slice_win > 0) {
        //check if current dump window is ended
        double diff = elapsed(dump_file->win_start, current_time) / 1000000;
        if (diff >= slice_win) {
#ifdef HAVE_ZLIB
	    if (zlib_dump)
             { 
               gzclose(dump_file->fp);
	     }
	    else
#endif
             { 
	       fflush(dump_file->fp);
               fclose(dump_file->fp);
	     }
            dump_file->seq_num++;

            // compute the current timestamp of dumping window
            // considering that there can be windows without traffic
            // associated
            dump_file->win_start.tv_sec += 
                ((long)diff / slice_win) * slice_win;
            dump_file->fp = new_dump_file(dump_file);
        }
    }

    //dump current packet
    dump_packet(dump_file->fp, pip, plast);

    //if (timestamp.tv_sec == -1) {
    //    fprintf(fp_log, "dump start: %s\n", Timestamp());
    //}
    last_dump_tm = current_time;
    if (first_dump_tm.tv_sec == -1) 
        first_dump_tm = current_time;
}
Example #4
0
int flush_read(struct astribank_device *astribank)
{
	char		tmpbuf[BUFSIZ];
	int		ret;

	DBG("starting...\n");
	memset(tmpbuf, 0, BUFSIZ);
	ret = recv_usb(astribank, tmpbuf, BUFSIZ, 1);
	if(ret < 0 && ret != -ETIMEDOUT) {
		ERR("ret=%d\n", ret);
		return ret;
	} else if(ret > 0) {
		DBG("Got %d bytes:\n", ret);
		dump_packet(LOG_DEBUG, DBG_MASK, __FUNCTION__, tmpbuf, ret);
	}
	return 0;
}
Example #5
0
int xusb_flushread(struct xusb *xusb)
{
	char		tmpbuf[BUFSIZ];
	int		ret;

	DBG("starting...\n");
	memset(tmpbuf, 0, BUFSIZ);
	ret = xusb_recv(xusb, tmpbuf, BUFSIZ, 1);
	if(ret < 0 && ret != -ETIMEDOUT) {
		ERR("ret=%d\n", ret);
		return ret;
	} else if(ret > 0) {
		DBG("Got %d bytes:\n", ret);
		dump_packet(LOG_DEBUG, DBG_MASK, __FUNCTION__, tmpbuf, ret);
	}
	return 0;
}
Example #6
0
int recv_usb(const char *msg, struct my_usb_device *mydev, char *buf, size_t len, int timeout)
{
	int	ret;

	if(mydev->my_ep_in & USB_ENDPOINT_OUT) {
		ERR("recv_usb called with an output endpoint 0x%x\n", mydev->my_ep_in);
		return -EINVAL;
	}
	ret = usb_bulk_read(mydev->handle, mydev->my_ep_in, buf, len, timeout);
	if(ret < 0) {
		ERR("bulk_read from endpoint 0x%x failed: %s\n", mydev->my_ep_in, usb_strerror());
		return ret;
	}
	if(verbose >= LOG_DEBUG)
		dump_packet(msg, buf, ret);
	return ret;
}
Example #7
0
int xusb_recv(struct xusb *xusb, char *buf, size_t len, int timeout)
{
	int	ret;

	if(EP_IN(xusb) & USB_ENDPOINT_OUT) {
		ERR("%s called with an output endpoint 0x%x\n", __FUNCTION__, EP_IN(xusb));
		return -EINVAL;
	}
	ret = usb_bulk_read(xusb->handle, EP_IN(xusb), buf, len, timeout);
	if(ret < 0) {
		DBG("bulk_read from endpoint 0x%x failed: (%d) %s\n",
			EP_IN(xusb), ret, usb_strerror());
		memset(buf, 0, len);
		return ret;
	}
	dump_packet(LOG_DEBUG, DBG_MASK, __FUNCTION__, buf, ret);
	return ret;
}
Example #8
0
File: test.c Project: FreeSrk/omx
int test_rtsp(char *url)
{
    int err;
    AVFormatContext *ic = NULL;
    AVInputFormat *fmt = &ff_rtsp_demuxer;
    AVFormatParameters params, *ap = &params;
    AVPacket cur_pkt, *pkt = &cur_pkt;

    memset(ap, 0, sizeof(*ap));

    ic = avformat_alloc_context();
    if(ic == NULL)
        return 0;

    ic->iformat = fmt;
    strcpy(ic->filename, url);

    if (fmt->priv_data_size > 0) {
        ic->priv_data = av_mallocz(fmt->priv_data_size);
        if (!ic->priv_data) {
            return 0;
        }
    } else {
        ic->priv_data = NULL;
    }

    err = ic->iformat->read_header(ic, ap);
    if (err < 0)
        return 0;

    while(1) {
        av_init_packet(pkt);
        //err = ic->iformat->read_packet(ic, pkt);
        err = av_read_packet(ic, pkt);
        if (err < 0)
            return 0;
        printf("stream: %d, len: %d, pts: %lld\n", pkt->stream_index, pkt->size, pkt->pts);
        dump_packet(pkt);
        if (pkt->destruct) pkt->destruct(pkt);
        pkt->data = NULL; pkt->size = 0;
    }

    return 1;
}
Example #9
0
status_t
IPCP::Send(struct mbuf *packet, uint16 protocolNumber)
{
	TRACE("IPCP: Send(0x%X)\n", protocolNumber);
	
	if((protocolNumber == IP_PROTOCOL && State() == PPP_OPENED_STATE)
			|| protocolNumber == IPCP_PROTOCOL) {
#if DEBUG
		dump_packet(packet, "outgoing");
#endif
		Interface().UpdateIdleSince();
		return SendToNext(packet, protocolNumber);
	}
	
	ERROR("IPCP: Send() failed because of wrong state or protocol number!\n");
	
	m_freem(packet);
	return B_ERROR;
}
Example #10
0
status_t
IPCP::ReceiveIPPacket(struct mbuf *packet, uint16 protocolNumber)
{
	if(protocolNumber != IP_PROTOCOL || State() != PPP_OPENED_STATE)
		return PPP_UNHANDLED;
	
	// TODO: add VJC support (the packet would be decoded here)
	
	if (gProto[IPPROTO_IP] && gProto[IPPROTO_IP]->pr_input) {
#if DEBUG
		dump_packet(packet, "incoming");
#endif
		Interface().UpdateIdleSince();
		gProto[IPPROTO_IP]->pr_input(packet, 0);
		return B_OK;
	} else {
		ERROR("IPCP: Error: Could not find input function for IP!\n");
		m_freem(packet);
		return B_ERROR;
	}
}
Example #11
0
static void hvsi_recv_response(struct hvsi_struct *hp, uint8_t *packet)
{
	struct hvsi_query_response *resp = (struct hvsi_query_response *)packet;

	switch (hp->state) {
		case HVSI_WAIT_FOR_VER_RESPONSE:
			__set_state(hp, HVSI_WAIT_FOR_VER_QUERY);
			break;
		case HVSI_WAIT_FOR_MCTRL_RESPONSE:
			hp->mctrl = 0;
			if (resp->u.mctrl_word & HVSI_TSDTR)
				hp->mctrl |= TIOCM_DTR;
			if (resp->u.mctrl_word & HVSI_TSCD)
				hp->mctrl |= TIOCM_CD;
			__set_state(hp, HVSI_OPEN);
			break;
		default:
			printk(KERN_ERR "hvsi%i: unexpected query response: ", hp->index);
			dump_packet(packet);
			break;
	}
}
static void
ipt_log_packet(u_int8_t pf,
	       unsigned int hooknum,
	       const struct sk_buff *skb,
	       const struct net_device *in,
	       const struct net_device *out,
	       const struct nf_loginfo *loginfo,
	       const char *prefix)
{
	struct sbuff *m = sb_open();

	if (!loginfo)
		loginfo = &default_loginfo;

	sb_add(m, "<%d>%sIN=%s OUT=%s ", loginfo->u.log.level,
	       prefix,
	       in ? in->name : "",
	       out ? out->name : "");
#ifdef CONFIG_BRIDGE_NETFILTER
	if (skb->nf_bridge) {
		const struct net_device *physindev;
		const struct net_device *physoutdev;

		physindev = skb->nf_bridge->physindev;
		if (physindev && in != physindev)
			sb_add(m, "PHYSIN=%s ", physindev->name);
		physoutdev = skb->nf_bridge->physoutdev;
		if (physoutdev && out != physoutdev)
			sb_add(m, "PHYSOUT=%s ", physoutdev->name);
	}
#endif

	if (in != NULL)
		dump_mac_header(m, loginfo, skb);

	dump_packet(m, loginfo, skb, 0);

	sb_close(m);
}
Example #13
0
int l2cap_send_connectionless(uint16_t handle, uint16_t cid, uint8_t * buffer, uint16_t len) {
    // printf("l2cap_send_connectionless\n");

    int pb = hci_non_flushable_packet_boundary_flag_supported() ? 0x00 : 0x02;

    // 0 - Connection handle : PB=pb : BC=00
    bt_store_16(packet_buffer, 0, handle | (pb << 12) | (0 << 14));
    // 2 - ACL length
    bt_store_16(packet_buffer, 2,  len + 4);
    // 4 - L2CAP packet length
    bt_store_16(packet_buffer, 4,  len + 0);
    // 6 - L2CAP channel DEST
    bt_store_16(packet_buffer, 6, cid);

    memcpy(&packet_buffer[8], buffer, len);
    hci_dump_packet(HCI_ACL_DATA_PACKET, 0, &packet_buffer[0], len + 8);

    dump_packet(HCI_ACL_DATA_PACKET, packet_buffer, len + 8);
    packet_buffer_len = len + 8;

    return 0;
}
Example #14
0
static void ether_do_interrupt(void)
{
	// Call protocol handler for received packets
	EthernetPacket ether_packet;
	uint32 packet = ether_packet.addr();
	ssize_t length;
	for (;;) {

		// Read packet from Ethernet device
		length = dequeue_packet(Mac2HostAddr(packet));
		if (length < 14)
			break;

#if MONITOR
		bug("Receiving Ethernet packet (%d bytes):\n",(int)length);
		dump_packet( Mac2HostAddr(packet), length );
#endif

		// Dispatch packet
		ether_dispatch_packet(packet, length);
	}
}
Example #15
0
int nl2_send(int sock, struct sockaddr_in *addr, znl2msg *msg)
{
    int i;
    int len;
    uint32_t* store;
    znl2msg *flipped;

    if (verbose >= 1)
      fprintf(stdout, "%s: sending %d bytes (message #%d %s) to %s:%d\n",
              progname,
              msg->n.znl2msg_len,
              msg->n.znl2msg_seq, type2s(msg->n.znl2msg_type),
              inet_ntoa(addr->sin_addr), ntohs(addr->sin_port));

    /* 
     * Make a copy of msg before byte flipping it. We're preserving the
     * original so that we can compare the request & reply headers.
     */
    len = msg->n.znl2msg_len;
    flipped = malloc(len);
    memcpy(flipped, msg, len);

    /* Endianess/byte ordering */
    store = (uint32_t*) flipped;
    if (flipped->n.znl2msg_type == ZNL2_SYN || flipped->n.znl2msg_type == ZNL2_FIN) {
        for (i = 0; i < (sizeof(znl2msghdr)/4+2); i++)
            store[i] = psdb_pton(store[i]);
    } else {
        for (i = 0; i < (len/4); i++)
            store[i] = psdb_pton(store[i]);
    }

    if (verbose >= 3)
        dump_packet(flipped, len);

    return sendto(sock, flipped, len, 0, (struct sockaddr *)addr,
                  sizeof(struct sockaddr_in));
}
Example #16
0
void do_uncook_loop(struct anonflow *flow, struct function *flist)
{
	flist_node_t   *fn;
	struct function *next_func;
	struct headers_data *frag_data;

	flow->uncook_ready = 0;

	for (fn = flist_head(flow->client_headers); fn != NULL; fn = flist_next(fn)) {
		anon_pkthdr_t   frag_pkt_head;
		flow->decoded_packet = NULL;

		frag_data = (struct headers_data *)(fn->data);
		//fprintf(stderr,"(%d) frag_data->caplen: %d %d %x\n",ff++,frag_data->caplen,flist_size(flow->headers),frag_data);

		frag_pkt_head.caplen = frag_data->caplen;
		frag_pkt_head.wlen = frag_data->wlen;
		frag_pkt_head.ts.tv_sec = frag_data->ts.tv_sec;
		frag_pkt_head.ts.tv_usec = frag_data->ts.tv_usec;

		next_func = flist->next;

		while (next_func) {
			if (next_func->function_info->
			    process(flow, next_func->internal_data, frag_data->header,
				    &frag_pkt_head) == 0) {
				break;
			}
			next_func = next_func->next;
		}

		if (next_func == NULL && flow->output_type != NONE) {	//Flow reached its end
			dump_packet(flow, frag_data->header, &frag_pkt_head);
		}
	}

	return;
}
Example #17
0
void log_data( FILE *file )
{
    Huint   size;
    Huint   data[ ETH_MTU_WORD ];
    
    while( 1 )
    {
        memset( data, 0, sizeof(Huint)*size );

        show_operation( oper_win, "Waiting for Header..." );
        box( oper_win, 0, 0 );
        wrefresh( oper_win );
        eth_recv( (Hubyte*)&size, sizeof(Huint) );
        size = ntohl( size );

        show_operation( oper_win, "Waiting for Data..." );
        box( oper_win, 0, 0 );
        wrefresh( oper_win );
        eth_recv( (Hubyte*)data, size*sizeof(Huint) );

        dump_packet( size, data, file );
    }
}
static int
write_packet(int  fd, const char* name, apacket** ppacket)
{
    char buff[8];
    if (!name) {
        snprintf(buff, sizeof buff, "fd=%d", fd);
        name = buff;
    }
    VLOG(TRANSPORT) << dump_packet(name, "to remote", *ppacket);
    char* p = reinterpret_cast<char*>(ppacket);  /* we really write the packet address */
    int len = sizeof(apacket*);
    while(len > 0) {
        int r = adb_write(fd, p, len);
        if(r > 0) {
            len -= r;
            p += r;
        } else {
            D("%s: write_packet (fd=%d) error ret=%d: %s", name, fd, r, strerror(errno));
            return -1;
        }
    }
    return 0;
}
Example #19
0
/* One level of recursion won't kill us */
static void dump_packet(const struct nf_loginfo *info,
			const struct sk_buff *skb,
			unsigned int iphoff)
{
	struct iphdr _iph;
	const struct iphdr *ih;
	unsigned int logflags;

	if (info->type == NF_LOG_TYPE_LOG)
		logflags = info->u.log.logflags;
	else
		logflags = NF_LOG_MASK;

	ih = skb_header_pointer(skb, iphoff, sizeof(_iph), &_iph);
	if (ih == NULL) {
		printk("TRUNCATED");
		return;
	}

	/* Important fields:
	 * TOS, len, DF/MF, fragment offset, TTL, src, dst, options. */
	/* Max length: 40 "SRC=255.255.255.255 DST=255.255.255.255 " */
	printk("SRC=%pI4 DST=%pI4 ",
	       &ih->saddr, &ih->daddr);

	/* Max length: 46 "LEN=65535 TOS=0xFF PREC=0xFF TTL=255 ID=65535 " */
	printk("LEN=%u TOS=0x%02X PREC=0x%02X TTL=%u ID=%u ",
	       ntohs(ih->tot_len), ih->tos & IPTOS_TOS_MASK,
	       ih->tos & IPTOS_PREC_MASK, ih->ttl, ntohs(ih->id));

	/* Max length: 6 "CE DF MF " */
	if (ntohs(ih->frag_off) & IP_CE)
		printk("CE ");
	if (ntohs(ih->frag_off) & IP_DF)
		printk("DF ");
	if (ntohs(ih->frag_off) & IP_MF)
		printk("MF ");

	/* Max length: 11 "FRAG:65535 " */
	if (ntohs(ih->frag_off) & IP_OFFSET)
		printk("FRAG:%u ", ntohs(ih->frag_off) & IP_OFFSET);

	if ((logflags & IPT_LOG_IPOPT) &&
	    ih->ihl * 4 > sizeof(struct iphdr)) {
		const unsigned char *op;
		unsigned char _opt[4 * 15 - sizeof(struct iphdr)];
		unsigned int i, optsize;

		optsize = ih->ihl * 4 - sizeof(struct iphdr);
		op = skb_header_pointer(skb, iphoff+sizeof(_iph),
					optsize, _opt);
		if (op == NULL) {
			printk("TRUNCATED");
			return;
		}

		/* Max length: 127 "OPT (" 15*4*2chars ") " */
		printk("OPT (");
		for (i = 0; i < optsize; i++)
			printk("%02X", op[i]);
		printk(") ");
	}

	switch (ih->protocol) {
	case IPPROTO_TCP: {
		struct tcphdr _tcph;
		const struct tcphdr *th;

		/* Max length: 10 "PROTO=TCP " */
		printk("PROTO=TCP ");

		if (ntohs(ih->frag_off) & IP_OFFSET)
			break;

		/* Max length: 25 "INCOMPLETE [65535 bytes] " */
		th = skb_header_pointer(skb, iphoff + ih->ihl * 4,
					sizeof(_tcph), &_tcph);
		if (th == NULL) {
			printk("INCOMPLETE [%u bytes] ",
			       skb->len - iphoff - ih->ihl*4);
			break;
		}

		/* Max length: 20 "SPT=65535 DPT=65535 " */
		printk("SPT=%u DPT=%u ",
		       ntohs(th->source), ntohs(th->dest));
		/* Max length: 30 "SEQ=4294967295 ACK=4294967295 " */
		if (logflags & IPT_LOG_TCPSEQ)
			printk("SEQ=%u ACK=%u ",
			       ntohl(th->seq), ntohl(th->ack_seq));
		/* Max length: 13 "WINDOW=65535 " */
		printk("WINDOW=%u ", ntohs(th->window));
		/* Max length: 9 "RES=0x3F " */
		printk("RES=0x%02x ", (u8)(ntohl(tcp_flag_word(th) & TCP_RESERVED_BITS) >> 22));
		/* Max length: 32 "CWR ECE URG ACK PSH RST SYN FIN " */
		if (th->cwr)
			printk("CWR ");
		if (th->ece)
			printk("ECE ");
		if (th->urg)
			printk("URG ");
		if (th->ack)
			printk("ACK ");
		if (th->psh)
			printk("PSH ");
		if (th->rst)
			printk("RST ");
		if (th->syn)
			printk("SYN ");
		if (th->fin)
			printk("FIN ");
		/* Max length: 11 "URGP=65535 " */
		printk("URGP=%u ", ntohs(th->urg_ptr));

		if ((logflags & IPT_LOG_TCPOPT) &&
		    th->doff * 4 > sizeof(struct tcphdr)) {
			unsigned char _opt[4 * 15 - sizeof(struct tcphdr)];
			const unsigned char *op;
			unsigned int i, optsize;

			optsize = th->doff * 4 - sizeof(struct tcphdr);
			op = skb_header_pointer(skb,
						iphoff+ih->ihl*4+sizeof(_tcph),
						optsize, _opt);
			if (op == NULL) {
				printk("TRUNCATED");
				return;
			}

			/* Max length: 127 "OPT (" 15*4*2chars ") " */
			printk("OPT (");
			for (i = 0; i < optsize; i++)
				printk("%02X", op[i]);
			printk(") ");
		}
		break;
	}
	case IPPROTO_UDP:
	case IPPROTO_UDPLITE: {
		struct udphdr _udph;
		const struct udphdr *uh;

		if (ih->protocol == IPPROTO_UDP)
			/* Max length: 10 "PROTO=UDP "     */
			printk("PROTO=UDP " );
		else	/* Max length: 14 "PROTO=UDPLITE " */
			printk("PROTO=UDPLITE ");

		if (ntohs(ih->frag_off) & IP_OFFSET)
			break;

		/* Max length: 25 "INCOMPLETE [65535 bytes] " */
		uh = skb_header_pointer(skb, iphoff+ih->ihl*4,
					sizeof(_udph), &_udph);
		if (uh == NULL) {
			printk("INCOMPLETE [%u bytes] ",
			       skb->len - iphoff - ih->ihl*4);
			break;
		}

		/* Max length: 20 "SPT=65535 DPT=65535 " */
		printk("SPT=%u DPT=%u LEN=%u ",
		       ntohs(uh->source), ntohs(uh->dest),
		       ntohs(uh->len));
		break;
	}
	case IPPROTO_ICMP: {
		struct icmphdr _icmph;
		const struct icmphdr *ich;
		static const size_t required_len[NR_ICMP_TYPES+1]
			= { [ICMP_ECHOREPLY] = 4,
			    [ICMP_DEST_UNREACH]
			    = 8 + sizeof(struct iphdr),
			    [ICMP_SOURCE_QUENCH]
			    = 8 + sizeof(struct iphdr),
			    [ICMP_REDIRECT]
			    = 8 + sizeof(struct iphdr),
			    [ICMP_ECHO] = 4,
			    [ICMP_TIME_EXCEEDED]
			    = 8 + sizeof(struct iphdr),
			    [ICMP_PARAMETERPROB]
			    = 8 + sizeof(struct iphdr),
			    [ICMP_TIMESTAMP] = 20,
			    [ICMP_TIMESTAMPREPLY] = 20,
			    [ICMP_ADDRESS] = 12,
			    [ICMP_ADDRESSREPLY] = 12 };

		/* Max length: 11 "PROTO=ICMP " */
		printk("PROTO=ICMP ");

		if (ntohs(ih->frag_off) & IP_OFFSET)
			break;

		/* Max length: 25 "INCOMPLETE [65535 bytes] " */
		ich = skb_header_pointer(skb, iphoff + ih->ihl * 4,
					 sizeof(_icmph), &_icmph);
		if (ich == NULL) {
			printk("INCOMPLETE [%u bytes] ",
			       skb->len - iphoff - ih->ihl*4);
			break;
		}

		/* Max length: 18 "TYPE=255 CODE=255 " */
		printk("TYPE=%u CODE=%u ", ich->type, ich->code);

		/* Max length: 25 "INCOMPLETE [65535 bytes] " */
		if (ich->type <= NR_ICMP_TYPES &&
		    required_len[ich->type] &&
		    skb->len-iphoff-ih->ihl*4 < required_len[ich->type]) {
			printk("INCOMPLETE [%u bytes] ",
			       skb->len - iphoff - ih->ihl*4);
			break;
		}

		switch (ich->type) {
		case ICMP_ECHOREPLY:
		case ICMP_ECHO:
			/* Max length: 19 "ID=65535 SEQ=65535 " */
			printk("ID=%u SEQ=%u ",
			       ntohs(ich->un.echo.id),
			       ntohs(ich->un.echo.sequence));
			break;

		case ICMP_PARAMETERPROB:
			/* Max length: 14 "PARAMETER=255 " */
			printk("PARAMETER=%u ",
			       ntohl(ich->un.gateway) >> 24);
			break;
		case ICMP_REDIRECT:
			/* Max length: 24 "GATEWAY=255.255.255.255 " */
			printk("GATEWAY=%pI4 ", &ich->un.gateway);
			/* Fall through */
		case ICMP_DEST_UNREACH:
		case ICMP_SOURCE_QUENCH:
		case ICMP_TIME_EXCEEDED:
			/* Max length: 3+maxlen */
			if (!iphoff) { /* Only recurse once. */
				printk("[");
				dump_packet(info, skb,
					    iphoff + ih->ihl*4+sizeof(_icmph));
				printk("] ");
			}

			/* Max length: 10 "MTU=65535 " */
			if (ich->type == ICMP_DEST_UNREACH &&
			    ich->code == ICMP_FRAG_NEEDED)
				printk("MTU=%u ", ntohs(ich->un.frag.mtu));
		}
		break;
	}
	/* Max Length */
	case IPPROTO_AH: {
		struct ip_auth_hdr _ahdr;
		const struct ip_auth_hdr *ah;

		if (ntohs(ih->frag_off) & IP_OFFSET)
			break;

		/* Max length: 9 "PROTO=AH " */
		printk("PROTO=AH ");

		/* Max length: 25 "INCOMPLETE [65535 bytes] " */
		ah = skb_header_pointer(skb, iphoff+ih->ihl*4,
					sizeof(_ahdr), &_ahdr);
		if (ah == NULL) {
			printk("INCOMPLETE [%u bytes] ",
			       skb->len - iphoff - ih->ihl*4);
			break;
		}

		/* Length: 15 "SPI=0xF1234567 " */
		printk("SPI=0x%x ", ntohl(ah->spi));
		break;
	}
	case IPPROTO_ESP: {
		struct ip_esp_hdr _esph;
		const struct ip_esp_hdr *eh;

		/* Max length: 10 "PROTO=ESP " */
		printk("PROTO=ESP ");

		if (ntohs(ih->frag_off) & IP_OFFSET)
			break;

		/* Max length: 25 "INCOMPLETE [65535 bytes] " */
		eh = skb_header_pointer(skb, iphoff+ih->ihl*4,
					sizeof(_esph), &_esph);
		if (eh == NULL) {
			printk("INCOMPLETE [%u bytes] ",
			       skb->len - iphoff - ih->ihl*4);
			break;
		}

		/* Length: 15 "SPI=0xF1234567 " */
		printk("SPI=0x%x ", ntohl(eh->spi));
		break;
	}
	/* Max length: 10 "PROTO 255 " */
	default:
		printk("PROTO=%u ", ih->protocol);
	}

	/* Max length: 15 "UID=4294967295 " */
	if ((logflags & IPT_LOG_UID) && !iphoff && skb->sk) {
		read_lock_bh(&skb->sk->sk_callback_lock);
		if (skb->sk->sk_socket && skb->sk->sk_socket->file)
			printk("UID=%u GID=%u ",
				skb->sk->sk_socket->file->f_cred->fsuid,
				skb->sk->sk_socket->file->f_cred->fsgid);
		read_unlock_bh(&skb->sk->sk_callback_lock);
	}

	/* Max length: 16 "MARK=0xFFFFFFFF " */
	if (!iphoff && skb->mark)
		printk("MARK=0x%x ", skb->mark);

	/* Proto    Max log string length */
	/* IP:      40+46+6+11+127 = 230 */
	/* TCP:     10+max(25,20+30+13+9+32+11+127) = 252 */
	/* UDP:     10+max(25,20) = 35 */
	/* UDPLITE: 14+max(25,20) = 39 */
	/* ICMP:    11+max(25, 18+25+max(19,14,24+3+n+10,3+n+10)) = 91+n */
	/* ESP:     10+max(25)+15 = 50 */
	/* AH:      9+max(25)+15 = 49 */
	/* unknown: 10 */

	/* (ICMP allows recursion one level deep) */
	/* maxlen =  IP + ICMP +  IP + max(TCP,UDP,ICMP,unknown) */
	/* maxlen = 230+   91  + 230 + 252 = 803 */
}
Example #20
0
int main(int argc, char *argv[]) {
    /**
     * I've included some basic code for opening a socket in C, sending
     * a UDP packet, and then receiving a response (or timeout).  You'll
     * need to fill in many of the details, but this should be enough to
     * get you started.
     */
    // process the arguments
    if (argc != 3 && argc != 4) {
        printf("Usage: ./3600dns [-ns|-mx] @<server:port> <name>\n");
        exit(-1);
    }
    char serverType = RECORDS;
    if (argc == 4) {
        if (!strcmp(argv[1],"-mx")) {
            serverType = MX;
        } else if (!strcmp(argv[1],"-ns")) {
            serverType = NS;
        } else {
            return -1;
        }
        argc = 1;
    } else {
        argc = 0;
    }
    // set the default port to 53
    int port = 53;
    char* name = calloc(150,sizeof(char));
    char* server = argv[argc+1] + 1;
    memcpy( name,argv[argc+2],strlen(argv[2]) );
    char* offset = strchr(argv[argc+1], ':');
    if (offset) {
        *offset = 0;
        port = atoi(offset + 1);
    }

    // construct the DNS request

    //Structure mallocs
    unsigned char* packetDNS =  (unsigned char*)calloc(MAX_IP_PACKET_SIZE, sizeof(char));
    if (!packetDNS) {
        return -1;
    }
    dnsheader* header =  (dnsheader*)calloc(1, sizeof(dnsheader));
    if (!header) {
        return -1;
    }
    dnsquestion* question =  (dnsquestion*)calloc(1, sizeof(dnsquestion));
    if (!question) {
        return -1;
    }
    dnsanswer* answer =  (dnsanswer*)calloc(1, sizeof(dnsanswer));
    if (!answer) {
        return -1;
    }

    //setup the header
    header->ID = htons(QUERY_ID);
    header->RD = ~(0);
    header->QDCOUNT = htons(0x0001);
    //setup the question, QNAME is added later
    switch (serverType) {
    case RECORDS:
        question->QTYPE = htons(0x0001);
        break;
    case MX:
        question->QTYPE = htons(MX);
        break;
    case NS:
        question->QTYPE = htons(NS);
        break;
    }
    question->QCLASS = htons(0x0001);

    int packetSize = 0;
    //copy header into packet
    memcpy( packetDNS, header,  sizeof(dnsheader) );
    packetSize += sizeof(dnsheader);

    //copy qname into packet
    int length = strlen(name);
    char* period = NULL;
    *( name + length ) = '.';
    *( name + length + 1 ) = 0;
    while ( (period = strchr(name, '.')) != 0 ) {
        *period = 0;
        length = strlen(name);
        memcpy( packetDNS + packetSize, &length, 1 );
        packetSize++;
        memcpy( packetDNS + packetSize, name, length);
        packetSize += length;
        name = period + 1;
    }

    //copy zero byte at end of qname
    char zeroByte = 0;
    memcpy( packetDNS + packetSize, &zeroByte, 1 );
    packetSize++;

    //copy question into packet
    memcpy( packetDNS + packetSize, question, sizeof(dnsquestion) );
    packetSize += sizeof(dnsquestion);


    // send the DNS request (and call dump_packet with your request)
    dump_packet( packetDNS, packetSize );

    // first, open a UDP socket
    int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);

    // next, construct the destination address
    struct sockaddr_in out;
    out.sin_family = AF_INET;
    out.sin_port = htons( (short) port );
    out.sin_addr.s_addr = inet_addr(server);

    if (sendto(sock, packetDNS, packetSize, 0, (struct sockaddr*)&out, sizeof(out)) < 0) {
        printf("Error occured in sendto\n");
        return -1;
    }

    //Clear question buffer to use for answer buffer in the future
    memset( packetDNS, 0, MAX_IP_PACKET_SIZE );
    memset( question, 0, sizeof(dnsquestion) );
    memset( header, 0, sizeof(dnsheader) );
    packetSize = 0;

    // wait for the DNS reply (timeout: 5 seconds)
    struct sockaddr_in in;
    socklen_t in_len;

    // construct the socket set
    fd_set socks;
    FD_ZERO(&socks);
    FD_SET(sock, &socks);

    // construct the timeout
    struct timeval t;
    t.tv_sec = 5;
    t.tv_usec = 0;

    // wait to receive, or for a timeout

    if (select(sock + 1, &socks, NULL, NULL, &t)) {
        in_len = sizeof(in);
        int status;
        status = recvfrom(sock, packetDNS, MAX_IP_PACKET_SIZE, 0, (struct sockaddr*) &in, &in_len);
        if ( status < 0) {
            printf("%s in recvfrom\n",strerror(errno));
            return -1;
        }
        if (!header) {
            return -1;
        }
        /*==========================
            Parse response HEADER
           ==========================*/
        //Check header for consistency
        memcpy( header,packetDNS,sizeof(dnsheader) );
        if ( ntohs(header->ID) != QUERY_ID ||
                header->QR != 1 ||
                header->RD != 1 ||
                header->RA != 1 ) {
            printf("ERROR: Header mismatch\n");
            return 1;
        }
        packetSize = sizeof(dnsheader);
        int numAnswers = ntohs(header->ANCOUNT);
        /*==========================
            Parse response QUESTION QNAME
           ==========================*/
        unsigned char* qname = calloc(150, sizeof(char));
        int len = parse_qname( packetDNS, qname, sizeof(dnsheader) );
        if (!strcmp((char*)argv[2],(char*)qname+1)) {
            printf("ERROR: qname mismatch '%s'\n",qname);
            return -1;
        }

        packetSize += len;
        /*==========================
            Parse response QUESTION
           ==========================*/
        memcpy( question, packetDNS+packetSize, sizeof(dnsquestion) );
        if ( (ntohs(question->QTYPE) != RECORDS &&
                ntohs(question->QTYPE) != MX &&
                ntohs(question->QTYPE) != NS) ||
                ntohs(question->QCLASS) != (1) ) {
            printf("ERROR: question mismatch\n");
            return -1;
        }
        packetSize += sizeof(dnsquestion);
        /*==========================
            Parse response ANSWER QNAME
           ==========================*/
        do {
            memset(qname,0,150);
            len = parse_qname(packetDNS,qname,packetSize);
            if (!strcmp((char*)argv[2],(char*)qname+1)) {
                printf("ERROR: answer qname mismatch '%s'\n",qname);
                return -1;
            }
            packetSize += len;
            /*==========================
                Parse response ANSWER
               ==========================*/
            memcpy(answer,packetDNS+packetSize,sizeof(dnsanswer));
            if ((ntohs(answer->TYPE) != RECORDS &&
                    ntohs(answer->TYPE) != CNAME &&
                    ntohs(answer->TYPE) != MX &&
                    ntohs(answer->TYPE) != NS) ||
                    ntohs(answer->CLASS) != 1 ) {
                printf("NOTFOUND\n");
                return 1;
            }
            //Two bytes need to be subtracted from dnsanswer becasue padding was added
            packetSize += sizeof(dnsanswer) - 2;
            /*=====================
                Parse response RDATA
               =====================*/
            unsigned char* rdata = calloc(150,sizeof(char));
            short preference = 0;
            if ( ntohs(answer->TYPE) == RECORDS ) {
                parse_ip(packetDNS,rdata,packetSize);
                printf("IP\t%s",rdata);
                packetSize += ntohs(answer->RDLENGTH);
            }
            else if ( ntohs(answer->TYPE) == CNAME ) {
                len = parse_qname(packetDNS,rdata,packetSize);
                printf("CNAME\t%s",rdata);
                packetSize += len;
            }
            else if ( ntohs(answer->TYPE) == NS ) {
                len = parse_qname(packetDNS,rdata,packetSize);
                printf("NS\t%s",rdata);
                packetSize += len;
            }
            else if ( ntohs(answer->TYPE) == MX ) {
                memcpy(&preference,packetDNS+packetSize,sizeof(short));
                packetSize+=sizeof(preference);
                preference = ntohs(preference);
                len = parse_qname(packetDNS,rdata,packetSize);
                printf("MX\t%s\t%d",rdata,preference);
                packetSize += len;
            }

            if ( header->AA) {
                printf("\tauth\n");
            } else {
                printf("\tnonauth\n");
            }
            numAnswers--;
        } while (numAnswers);
    } else {
        // a timeout occurred
        printf("NORESPONSE");
    }
    // print out the result
    //dump_packet( packetDNS, packetSize);
    free(header);
    free(question);
    free(packetDNS);
    free(answer);
    return 0;
}
Example #21
0
void
parse_packet(u_char *mode, const struct pcap_pkthdr *header, const u_char *packet)
{
    // IP header data
    struct ip *ip4;
#ifdef WITH_IPV6
    // IPv6 header data
    struct ip6_hdr *ip6;
#endif
    // IP version
    uint32_t ip_ver;
    // IP protocol
    uint8_t ip_proto;
    // IP header size
    uint32_t ip_hl = 0;
    // Fragment offset
    uint32_t ip_off = 0;
    // Fragmentation flag
    uint8_t ip_frag = 0;
    // Fragmentation offset
    uint16_t ip_frag_off = 0;
    //! Source Address
    char ip_src[ADDRESSLEN];
    //! Destination Address
    char ip_dst[ADDRESSLEN];
    // Source and Destination Ports
    u_short sport, dport;
    // UDP header data
    struct udphdr *udp;
    // UDP header size
    uint16_t udp_off;
    // TCP header data
    struct tcphdr *tcp;
    // TCP header size
    uint16_t tcp_off;
    // Packet payload data
    u_char *payload = NULL;
    // Packet payload size
    uint32_t size_payload = header->caplen;
    // SIP message transport
    int transport;
    // Media structure for RTP packets
    rtp_stream_t *stream;
    // Captured packet info
    capture_packet_t *pkt;

    // Ignore packets while capture is paused
    if (capture_is_paused())
        return;

    // Check if we have reached capture limit
    if (capinfo.limit && sip_calls_count() >= capinfo.limit)
        return;

    // Get IP header
    ip4 = (struct ip *) (packet + capinfo.link_hl);

#ifdef WITH_IPV6
    // Get IPv6 header
    ip6 = (struct ip6_hdr *) (packet + capinfo.link_hl);
#endif

    // Get IP version
    ip_ver = ip4->ip_v;

    switch (ip_ver) {
        case 4:
            ip_hl = ip4->ip_hl * 4;
            ip_proto = ip4->ip_p;
            ip_off = ntohs(ip4->ip_off);

            ip_frag = ip_off & (IP_MF | IP_OFFMASK);
            ip_frag_off = (ip_frag) ? (ip_off & IP_OFFMASK) * 8 : 0;
            // TODO Get fragment information

            inet_ntop(AF_INET, &ip4->ip_src, ip_src, sizeof(ip_src));
            inet_ntop(AF_INET, &ip4->ip_dst, ip_dst, sizeof(ip_dst));
            break;
#ifdef WITH_IPV6
        case 6:
            ip_hl = sizeof(struct ip6_hdr);
            ip_proto = ip6->ip6_nxt;

            if (ip_proto == IPPROTO_FRAGMENT) {
                struct ip6_frag *ip6f = (struct ip6_frag *) (ip6 + ip_hl);
                ip_frag_off = ntohs(ip6f->ip6f_offlg & IP6F_OFF_MASK);
                // TODO Get fragment information
            }

            inet_ntop(AF_INET6, &ip6->ip6_src, ip_src, sizeof(ip_src));
            inet_ntop(AF_INET6, &ip6->ip6_dst, ip_dst, sizeof(ip_dst));
            break;
#endif
        default:
            return;
    }

    // Only interested in UDP packets
    if (ip_proto == IPPROTO_UDP) {
        // Get UDP header
        udp = (struct udphdr *)((u_char *)(ip4) + ip_hl);
        udp_off = (ip_frag_off) ? 0 : sizeof(struct udphdr);

        // Set packet ports
        sport = htons(udp->uh_sport);
        dport = htons(udp->uh_dport);

        // Get actual payload size
        size_payload -= capinfo.link_hl + ip_hl + udp_off;

#ifdef WITH_IPV6
        if (ip_ver == 6)
            size_payload -= ntohs(ip6->ip6_ctlun.ip6_un1.ip6_un1_plen);
#endif
        // Get payload start
        payload = (u_char *) (udp) + udp_off;

        // Set transport UDP
        transport = CAPTURE_PACKET_SIP_UDP;

    } else if (ip_proto == IPPROTO_TCP) {
        // Get TCP header
        tcp = (struct tcphdr *)((u_char *)(ip4 )+ ip_hl);
        tcp_off = (ip_frag_off) ? 0 : (tcp->th_off * 4);

        // Set packet ports
        sport = htons(tcp->th_sport);
        dport = htons(tcp->th_dport);

        // Get actual payload size
        size_payload -= capinfo.link_hl + ip_hl + tcp_off;

#ifdef WITH_IPV6
        if (ip_ver == 6)
            size_payload -= ntohs(ip6->ip6_ctlun.ip6_un1.ip6_un1_plen);
#endif
        // Get payload start
        payload = (u_char *)(tcp) + tcp_off;

        // Set transport TCP
        transport = CAPTURE_PACKET_SIP_TCP;
    } else {
        // Not handled protocol
        return;
    }

    if ((int32_t)size_payload < 0)
        size_payload = 0;

    // Create a structure for this captured packet
    pkt = capture_packet_create(header, packet, header->caplen);
    capture_packet_set_type(pkt, transport);
    // For TCP and UDP, use payload directly from the packet
    capture_packet_set_payload(pkt, NULL, size_payload);

#ifdef WITH_OPENSSL
    // Check if packet is TLS
    if (capinfo.keyfile && transport == CAPTURE_PACKET_SIP_TCP)
        tls_process_segment(ip4, pkt);
#endif

    // Check if packet is WS or WSS
    if (transport == CAPTURE_PACKET_SIP_TCP)
        capture_ws_check_packet(pkt);

    // We're only interested in packets with payload
    if (capture_packet_get_payload_len(pkt)) {
        // Parse this header and payload
        if (sip_load_message(pkt, ip_src, sport, ip_dst, dport)) {
            // Store this packets in output file
            dump_packet(capinfo.pd, header, packet);
            return;
        }

        // Check if this packet belongs to a RTP stream
        // TODO Store this packet in the stream
        if ((stream = rtp_check_stream(pkt, ip_src, sport, ip_dst, dport))) {
            // We have an RTP packet!
            capture_packet_set_type(pkt, CAPTURE_PACKET_RTP);
            // Store this pacekt if capture rtp is enabled
            if (capinfo.rtp_capture) {
                call_add_rtp_packet(stream_get_call(stream), pkt);
            } else {
                capture_packet_destroy(pkt);
            }
            // Store this packets in output file
            dump_packet(capinfo.pd, header, packet);
            return;
        }
    }

    // Not an interesting packet ...
    capture_packet_destroy(pkt);
}
Example #22
0
/* One level of recursion won't kill us */
static void dump_packet(const struct nf_loginfo *info,
			const struct sk_buff *skb, unsigned int ip6hoff,
			int recurse)
{
	u_int8_t currenthdr;
	int fragment;
	struct ipv6hdr _ip6h;
	const struct ipv6hdr *ih;
	unsigned int ptr;
	unsigned int hdrlen = 0;
	unsigned int logflags;

	if (info->type == NF_LOG_TYPE_LOG)
		logflags = info->u.log.logflags;
	else
		logflags = NF_LOG_MASK;

	ih = skb_header_pointer(skb, ip6hoff, sizeof(_ip6h), &_ip6h);
	if (ih == NULL) {
		printk("TRUNCATED");
		return;
	}

	/* Max length: 88 "SRC=0000.0000.0000.0000.0000.0000.0000.0000 DST=0000.0000.0000.0000.0000.0000.0000.0000 " */
	printk("SRC=%pI6 DST=%pI6 ", &ih->saddr, &ih->daddr);

	/* Max length: 44 "LEN=65535 TC=255 HOPLIMIT=255 FLOWLBL=FFFFF " */
	printk("LEN=%Zu TC=%u HOPLIMIT=%u FLOWLBL=%u ",
	       ntohs(ih->payload_len) + sizeof(struct ipv6hdr),
	       (ntohl(*(__be32 *)ih) & 0x0ff00000) >> 20,
	       ih->hop_limit,
	       (ntohl(*(__be32 *)ih) & 0x000fffff));

	fragment = 0;
	ptr = ip6hoff + sizeof(struct ipv6hdr);
	currenthdr = ih->nexthdr;
	while (currenthdr != NEXTHDR_NONE && ip6t_ext_hdr(currenthdr)) {
		struct ipv6_opt_hdr _hdr;
		const struct ipv6_opt_hdr *hp;

		hp = skb_header_pointer(skb, ptr, sizeof(_hdr), &_hdr);
		if (hp == NULL) {
			printk("TRUNCATED");
			return;
		}

		/* Max length: 48 "OPT (...) " */
		if (logflags & IP6T_LOG_IPOPT)
			printk("OPT ( ");

		switch (currenthdr) {
		case IPPROTO_FRAGMENT: {
			struct frag_hdr _fhdr;
			const struct frag_hdr *fh;

			printk("FRAG:");
			fh = skb_header_pointer(skb, ptr, sizeof(_fhdr),
						&_fhdr);
			if (fh == NULL) {
				printk("TRUNCATED ");
				return;
			}

			/* Max length: 6 "65535 " */
			printk("%u ", ntohs(fh->frag_off) & 0xFFF8);

			/* Max length: 11 "INCOMPLETE " */
			if (fh->frag_off & htons(0x0001))
				printk("INCOMPLETE ");

			printk("ID:%08x ", ntohl(fh->identification));

			if (ntohs(fh->frag_off) & 0xFFF8)
				fragment = 1;

			hdrlen = 8;

			break;
		}
		case IPPROTO_DSTOPTS:
		case IPPROTO_ROUTING:
		case IPPROTO_HOPOPTS:
			if (fragment) {
				if (logflags & IP6T_LOG_IPOPT)
					printk(")");
				return;
			}
			hdrlen = ipv6_optlen(hp);
			break;
		/* Max Length */
		case IPPROTO_AH:
			if (logflags & IP6T_LOG_IPOPT) {
				struct ip_auth_hdr _ahdr;
				const struct ip_auth_hdr *ah;

				/* Max length: 3 "AH " */
				printk("AH ");

				if (fragment) {
					printk(")");
					return;
				}

				ah = skb_header_pointer(skb, ptr, sizeof(_ahdr),
							&_ahdr);
				if (ah == NULL) {
					/*
					 * Max length: 26 "INCOMPLETE [65535
					 *  bytes] )"
					 */
					printk("INCOMPLETE [%u bytes] )",
					       skb->len - ptr);
					return;
				}

				/* Length: 15 "SPI=0xF1234567 */
				printk("SPI=0x%x ", ntohl(ah->spi));

			}

			hdrlen = (hp->hdrlen+2)<<2;
			break;
		case IPPROTO_ESP:
			if (logflags & IP6T_LOG_IPOPT) {
				struct ip_esp_hdr _esph;
				const struct ip_esp_hdr *eh;

				/* Max length: 4 "ESP " */
				printk("ESP ");

				if (fragment) {
					printk(")");
					return;
				}

				/*
				 * Max length: 26 "INCOMPLETE [65535 bytes] )"
				 */
				eh = skb_header_pointer(skb, ptr, sizeof(_esph),
							&_esph);
				if (eh == NULL) {
					printk("INCOMPLETE [%u bytes] )",
					       skb->len - ptr);
					return;
				}

				/* Length: 16 "SPI=0xF1234567 )" */
				printk("SPI=0x%x )", ntohl(eh->spi) );

			}
			return;
		default:
			/* Max length: 20 "Unknown Ext Hdr 255" */
			printk("Unknown Ext Hdr %u", currenthdr);
			return;
		}
		if (logflags & IP6T_LOG_IPOPT)
			printk(") ");

		currenthdr = hp->nexthdr;
		ptr += hdrlen;
	}

	switch (currenthdr) {
	case IPPROTO_TCP: {
		struct tcphdr _tcph;
		const struct tcphdr *th;

		/* Max length: 10 "PROTO=TCP " */
		printk("PROTO=TCP ");

		if (fragment)
			break;

		/* Max length: 25 "INCOMPLETE [65535 bytes] " */
		th = skb_header_pointer(skb, ptr, sizeof(_tcph), &_tcph);
		if (th == NULL) {
			printk("INCOMPLETE [%u bytes] ", skb->len - ptr);
			return;
		}

		/* Max length: 20 "SPT=65535 DPT=65535 " */
		printk("SPT=%u DPT=%u ",
		       ntohs(th->source), ntohs(th->dest));
		/* Max length: 30 "SEQ=4294967295 ACK=4294967295 " */
		if (logflags & IP6T_LOG_TCPSEQ)
			printk("SEQ=%u ACK=%u ",
			       ntohl(th->seq), ntohl(th->ack_seq));
		/* Max length: 13 "WINDOW=65535 " */
		printk("WINDOW=%u ", ntohs(th->window));
		/* Max length: 9 "RES=0x3C " */
		printk("RES=0x%02x ", (u_int8_t)(ntohl(tcp_flag_word(th) & TCP_RESERVED_BITS) >> 22));
		/* Max length: 32 "CWR ECE URG ACK PSH RST SYN FIN " */
		if (th->cwr)
			printk("CWR ");
		if (th->ece)
			printk("ECE ");
		if (th->urg)
			printk("URG ");
		if (th->ack)
			printk("ACK ");
		if (th->psh)
			printk("PSH ");
		if (th->rst)
			printk("RST ");
		if (th->syn)
			printk("SYN ");
		if (th->fin)
			printk("FIN ");
		/* Max length: 11 "URGP=65535 " */
		printk("URGP=%u ", ntohs(th->urg_ptr));

		if ((logflags & IP6T_LOG_TCPOPT) &&
		    th->doff * 4 > sizeof(struct tcphdr)) {
			u_int8_t _opt[60 - sizeof(struct tcphdr)];
			const u_int8_t *op;
			unsigned int i;
			unsigned int optsize = th->doff * 4
					       - sizeof(struct tcphdr);

			op = skb_header_pointer(skb,
						ptr + sizeof(struct tcphdr),
						optsize, _opt);
			if (op == NULL) {
				printk("OPT (TRUNCATED)");
				return;
			}

			/* Max length: 127 "OPT (" 15*4*2chars ") " */
			printk("OPT (");
			for (i =0; i < optsize; i++)
				printk("%02X", op[i]);
			printk(") ");
		}
		break;
	}
	case IPPROTO_UDP:
	case IPPROTO_UDPLITE: {
		struct udphdr _udph;
		const struct udphdr *uh;

		if (currenthdr == IPPROTO_UDP)
			/* Max length: 10 "PROTO=UDP "     */
			printk("PROTO=UDP " );
		else	/* Max length: 14 "PROTO=UDPLITE " */
			printk("PROTO=UDPLITE ");

		if (fragment)
			break;

		/* Max length: 25 "INCOMPLETE [65535 bytes] " */
		uh = skb_header_pointer(skb, ptr, sizeof(_udph), &_udph);
		if (uh == NULL) {
			printk("INCOMPLETE [%u bytes] ", skb->len - ptr);
			return;
		}

		/* Max length: 20 "SPT=65535 DPT=65535 " */
		printk("SPT=%u DPT=%u LEN=%u ",
		       ntohs(uh->source), ntohs(uh->dest),
		       ntohs(uh->len));
		break;
	}
	case IPPROTO_ICMPV6: {
		struct icmp6hdr _icmp6h;
		const struct icmp6hdr *ic;

		/* Max length: 13 "PROTO=ICMPv6 " */
		printk("PROTO=ICMPv6 ");

		if (fragment)
			break;

		/* Max length: 25 "INCOMPLETE [65535 bytes] " */
		ic = skb_header_pointer(skb, ptr, sizeof(_icmp6h), &_icmp6h);
		if (ic == NULL) {
			printk("INCOMPLETE [%u bytes] ", skb->len - ptr);
			return;
		}

		/* Max length: 18 "TYPE=255 CODE=255 " */
		printk("TYPE=%u CODE=%u ", ic->icmp6_type, ic->icmp6_code);

		switch (ic->icmp6_type) {
		case ICMPV6_ECHO_REQUEST:
		case ICMPV6_ECHO_REPLY:
			/* Max length: 19 "ID=65535 SEQ=65535 " */
			printk("ID=%u SEQ=%u ",
				ntohs(ic->icmp6_identifier),
				ntohs(ic->icmp6_sequence));
			break;
		case ICMPV6_MGM_QUERY:
		case ICMPV6_MGM_REPORT:
		case ICMPV6_MGM_REDUCTION:
			break;

		case ICMPV6_PARAMPROB:
			/* Max length: 17 "POINTER=ffffffff " */
			printk("POINTER=%08x ", ntohl(ic->icmp6_pointer));
			/* Fall through */
		case ICMPV6_DEST_UNREACH:
		case ICMPV6_PKT_TOOBIG:
		case ICMPV6_TIME_EXCEED:
			/* Max length: 3+maxlen */
			if (recurse) {
				printk("[");
				dump_packet(info, skb, ptr + sizeof(_icmp6h),
					    0);
				printk("] ");
			}

			/* Max length: 10 "MTU=65535 " */
			if (ic->icmp6_type == ICMPV6_PKT_TOOBIG)
				printk("MTU=%u ", ntohl(ic->icmp6_mtu));
		}
		break;
	}
	/* Max length: 10 "PROTO=255 " */
	default:
		printk("PROTO=%u ", currenthdr);
	}

	/* Max length: 15 "UID=4294967295 " */
	if ((logflags & IP6T_LOG_UID) && recurse && skb->sk) {
		read_lock_bh(&skb->sk->sk_callback_lock);
		if (skb->sk->sk_socket && skb->sk->sk_socket->file)
			printk("UID=%u GID=%u ",
				skb->sk->sk_socket->file->f_cred->fsuid,
				skb->sk->sk_socket->file->f_cred->fsgid);
		read_unlock_bh(&skb->sk->sk_callback_lock);
	}

	/* Max length: 16 "MARK=0xFFFFFFFF " */
	if (!recurse && skb->mark)
		printk("MARK=0x%x ", skb->mark);
}
Example #23
0
static int connection_handle_read(server *srv, connection *con) {
	int len;
	buffer *b;
	int toread;

	if (con->conf.is_ssl) {
		return connection_handle_read_ssl(srv, con);
	}

#if defined(__WIN32)
	b = chunkqueue_get_append_buffer(con->read_queue);
	buffer_prepare_copy(b, 4 * 1024);
	len = recv(con->fd, b->ptr, b->size - 1, 0);
#else
	if (ioctl(con->fd, FIONREAD, &toread)) {
		log_error_write(srv, __FILE__, __LINE__, "sd",
				"unexpected end-of-file:",
				con->fd);
		return -1;
	}
	b = chunkqueue_get_append_buffer(con->read_queue);
	buffer_prepare_copy(b, toread + 1);

	len = read(con->fd, b->ptr, b->size - 1);
#endif

	if (len < 0) {
		con->is_readable = 0;

		if (errno == EAGAIN) return 0;
		if (errno == EINTR) {
			/* we have been interrupted before we could read */
			con->is_readable = 1;
			return 0;
		}

		if (errno != ECONNRESET) {
			/* expected for keep-alive */
			log_error_write(srv, __FILE__, __LINE__, "ssd", "connection closed - read failed: ", strerror(errno), errno);
		}

		connection_set_state(srv, con, CON_STATE_ERROR);

		return -1;
	} else if (len == 0) {
		con->is_readable = 0;
		/* the other end close the connection -> KEEP-ALIVE */

		/* pipelining */

		return -2;
	} else if ((size_t)len < b->size - 1) {
		/* we got less then expected, wait for the next fd-event */

		con->is_readable = 0;
	}

	b->used = len;
	b->ptr[b->used++] = '\0';

	con->bytes_read += len;
#if 0
	dump_packet(b->ptr, len);
#endif

	return 0;
}
Example #24
0
/* 0: everything ok, -1: error, -2: con closed */
static int connection_handle_read(server *srv, connection *con) {
	int len;
	char *mem = NULL;
	size_t mem_len = 0;
	int toread;

	if (con->srv_socket->is_ssl) {
		return connection_handle_read_ssl(srv, con);
	}

	/* default size for chunks is 4kb; only use bigger chunks if FIONREAD tells
	 *  us more than 4kb is available
	 * if FIONREAD doesn't signal a big chunk we fill the previous buffer
	 *  if it has >= 1kb free
	 */
#if defined(__WIN32)
	chunkqueue_get_memory(con->read_queue, &mem, &mem_len, 0, 4096);

	len = recv(con->fd, mem, mem_len, 0);
#else
	if (ioctl(con->fd, FIONREAD, &toread) || toread == 0 || toread <= 4*1024) {
		if (toread > MAX_READ_LIMIT) toread = MAX_READ_LIMIT;
	} else {
		toread = 4096;
	}
	chunkqueue_get_memory(con->read_queue, &mem, &mem_len, 0, toread);

	len = read(con->fd, mem, mem_len);
#endif

	chunkqueue_use_memory(con->read_queue, len > 0 ? len : 0);

	if (len < 0) {
		con->is_readable = 0;

		if (errno == EAGAIN) return 0;
		if (errno == EINTR) {
			/* we have been interrupted before we could read */
			con->is_readable = 1;
			return 0;
		}

		if (errno != ECONNRESET) {
			/* expected for keep-alive */
			log_error_write(srv, __FILE__, __LINE__, "ssd", "connection closed - read failed: ", strerror(errno), errno);
		}

		connection_set_state(srv, con, CON_STATE_ERROR);

		return -1;
	} else if (len == 0) {
		con->is_readable = 0;
		/* the other end close the connection -> KEEP-ALIVE */

		/* pipelining */

		return -2;
	} else if (len != (ssize_t) mem_len) {
		/* we got less then expected, wait for the next fd-event */

		con->is_readable = 0;
	}

	con->bytes_read += len;
#if 0
	dump_packet(b->ptr, len);
#endif

	return 0;
}
Example #25
0
void
parse_packet(u_char *info, const struct pcap_pkthdr *header, const u_char *packet)
{
    // Capture info
    capture_info_t *capinfo = (capture_info_t *) info;
    // UDP header data
    struct udphdr *udp;
    // UDP header size
    uint16_t udp_off;
    // TCP header data
    struct tcphdr *tcp;
    // TCP header size
    uint16_t tcp_off;
    // Packet data
    u_char data[MAX_CAPTURE_LEN];
    // Packet payload data
    u_char *payload = NULL;
    // Whole packet size
    uint32_t size_capture = header->caplen;
    // Packet payload size
    uint32_t size_payload =  size_capture - capinfo->link_hl;
    // Captured packet info
    packet_t *pkt;

    // Ignore packets while capture is paused
    if (capture_paused())
        return;

    // Check if we have reached capture limit
    if (capture_cfg.limit && sip_calls_count() >= capture_cfg.limit)
        return;

    // Check maximum capture length
    if (header->caplen > MAX_CAPTURE_LEN)
        return;

    // Copy packet payload
    memcpy(data, packet, header->caplen);

    // Check if we have a complete IP packet
    if (!(pkt = capture_packet_reasm_ip(capinfo, header, data, &size_payload, &size_capture)))
        return;

    // Only interested in UDP packets
    if (pkt->proto == IPPROTO_UDP) {
        // Get UDP header
        udp = (struct udphdr *)((u_char *)(data) + (size_capture - size_payload));
        udp_off = sizeof(struct udphdr);

        // Set packet ports
        pkt->src.port = htons(udp->uh_sport);
        pkt->dst.port = htons(udp->uh_dport);

        // Remove UDP Header from payload
        size_payload -= udp_off;

        if ((int32_t)size_payload < 0)
            size_payload = 0;

        // Remove TCP Header from payload
        payload = (u_char *) (udp) + udp_off;

        // Complete packet with Transport information
        packet_set_type(pkt, PACKET_SIP_UDP);
        packet_set_payload(pkt, payload, size_payload);

    } else if (pkt->proto == IPPROTO_TCP) {
        // Get TCP header
        tcp = (struct tcphdr *)((u_char *)(data) + (size_capture - size_payload));
        tcp_off = (tcp->th_off * 4);

        // Set packet ports
        pkt->src.port = htons(tcp->th_sport);
        pkt->dst.port = htons(tcp->th_dport);

        // Get actual payload size
        size_payload -= tcp_off;

        if ((int32_t)size_payload < 0)
            size_payload = 0;

        // Get payload start
        payload = (u_char *)(tcp) + tcp_off;

        // Complete packet with Transport information
        packet_set_type(pkt, PACKET_SIP_TCP);
        packet_set_payload(pkt, payload, size_payload);

        // Create a structure for this captured packet
        if (!(pkt = capture_packet_reasm_tcp(pkt, tcp, payload, size_payload)))
            return;

#if defined(WITH_GNUTLS) || defined(WITH_OPENSSL)
        // Check if packet is TLS
        if (capture_cfg.keyfile) {
            tls_process_segment(pkt, tcp);
        }
#endif

        // Check if packet is WS or WSS
        capture_ws_check_packet(pkt);
    } else {
        // Not handled protocol
        packet_destroy(pkt);
        return;
    }

    // Avoid parsing from multiples sources.
    // Avoid parsing while screen in being redrawn
    capture_lock();
    // Check if we can handle this packet
    if (capture_packet_parse(pkt) == 0) {
#ifdef USE_EEP
        // Send this packet through eep
        capture_eep_send(pkt);
#endif
        // Store this packets in output file
        dump_packet(capture_cfg.pd, pkt);
        // If storage is disabled, delete frames payload
        if (capture_cfg.storage == 0) {
            packet_free_frames(pkt);
        }
        // Allow Interface refresh and user input actions
        capture_unlock();
        return;
    }

    // Not an interesting packet ...
    packet_destroy(pkt);
    // Allow Interface refresh and user input actions
    capture_unlock();
}
Example #26
0
/* One level of recursion won't kill us */
static void dump_packet(const struct ipt_log_info *info,
                        const struct sk_buff *skb,
                        unsigned int iphoff)
{
    struct iphdr iph;

    if (skb_copy_bits(skb, iphoff, &iph, sizeof(iph)) < 0) {
        printk("TRUNCATED");
        return;
    }

    /* Important fields:
     * TOS, len, DF/MF, fragment offset, TTL, src, dst, options. */
    /* Max length: 40 "SRC=255.255.255.255 DST=255.255.255.255 " */
    printk("SRC=%u.%u.%u.%u DST=%u.%u.%u.%u ",
           NIPQUAD(iph.saddr), NIPQUAD(iph.daddr));

    /* Max length: 46 "LEN=65535 TOS=0xFF PREC=0xFF TTL=255 ID=65535 " */
    printk("LEN=%u TOS=0x%02X PREC=0x%02X TTL=%u ID=%u ",
           ntohs(iph.tot_len), iph.tos & IPTOS_TOS_MASK,
           iph.tos & IPTOS_PREC_MASK, iph.ttl, ntohs(iph.id));

    /* Max length: 6 "CE DF MF " */
    if (ntohs(iph.frag_off) & IP_CE)
        printk("CE ");
    if (ntohs(iph.frag_off) & IP_DF)
        printk("DF ");
    if (ntohs(iph.frag_off) & IP_MF)
        printk("MF ");

    /* Max length: 11 "FRAG:65535 " */
    if (ntohs(iph.frag_off) & IP_OFFSET)
        printk("FRAG:%u ", ntohs(iph.frag_off) & IP_OFFSET);

    if ((info->logflags & IPT_LOG_IPOPT)
            && iph.ihl * 4 != sizeof(struct iphdr)) {
        unsigned char opt[4 * 15 - sizeof(struct iphdr)];
        unsigned int i, optsize;

        optsize = iph.ihl * 4 - sizeof(struct iphdr);
        if (skb_copy_bits(skb, iphoff+sizeof(iph), opt, optsize) < 0) {
            printk("TRUNCATED");
            return;
        }

        /* Max length: 127 "OPT (" 15*4*2chars ") " */
        printk("OPT (");
        for (i = 0; i < optsize; i++)
            printk("%02X", opt[i]);
        printk(") ");
    }

    switch (iph.protocol) {
    case IPPROTO_TCP: {
        struct tcphdr tcph;

        /* Max length: 10 "PROTO=TCP " */
        printk("PROTO=TCP ");

        if (ntohs(iph.frag_off) & IP_OFFSET)
            break;

        /* Max length: 25 "INCOMPLETE [65535 bytes] " */
        if (skb_copy_bits(skb, iphoff+iph.ihl*4, &tcph, sizeof(tcph))
                < 0) {
            printk("INCOMPLETE [%u bytes] ",
                   skb->len - iphoff - iph.ihl*4);
            break;
        }

        /* Max length: 20 "SPT=65535 DPT=65535 " */
        printk("SPT=%u DPT=%u ",
               ntohs(tcph.source), ntohs(tcph.dest));
        /* Max length: 30 "SEQ=4294967295 ACK=4294967295 " */
        if (info->logflags & IPT_LOG_TCPSEQ)
            printk("SEQ=%u ACK=%u ",
                   ntohl(tcph.seq), ntohl(tcph.ack_seq));
        /* Max length: 13 "WINDOW=65535 " */
        printk("WINDOW=%u ", ntohs(tcph.window));
        /* Max length: 9 "RES=0x3F " */
        printk("RES=0x%02x ", (u8)(ntohl(tcp_flag_word(&tcph) & TCP_RESERVED_BITS) >> 22));
        /* Max length: 32 "CWR ECE URG ACK PSH RST SYN FIN " */
        if (tcph.cwr)
            printk("CWR ");
        if (tcph.ece)
            printk("ECE ");
        if (tcph.urg)
            printk("URG ");
        if (tcph.ack)
            printk("ACK ");
        if (tcph.psh)
            printk("PSH ");
        if (tcph.rst)
            printk("RST ");
        if (tcph.syn)
            printk("SYN ");
        if (tcph.fin)
            printk("FIN ");
        /* Max length: 11 "URGP=65535 " */
        printk("URGP=%u ", ntohs(tcph.urg_ptr));

        if ((info->logflags & IPT_LOG_TCPOPT)
                && tcph.doff * 4 != sizeof(struct tcphdr)) {
            unsigned char opt[4 * 15 - sizeof(struct tcphdr)];
            unsigned int i, optsize;

            optsize = tcph.doff * 4 - sizeof(struct tcphdr);
            if (skb_copy_bits(skb, iphoff+iph.ihl*4 + sizeof(tcph),
                              opt, optsize) < 0) {
                printk("TRUNCATED");
                return;
            }

            /* Max length: 127 "OPT (" 15*4*2chars ") " */
            printk("OPT (");
            for (i = 0; i < optsize; i++)
                printk("%02X", opt[i]);
            printk(") ");
        }
        break;
    }
    case IPPROTO_UDP: {
        struct udphdr udph;

        /* Max length: 10 "PROTO=UDP " */
        printk("PROTO=UDP ");

        if (ntohs(iph.frag_off) & IP_OFFSET)
            break;

        /* Max length: 25 "INCOMPLETE [65535 bytes] " */
        if (skb_copy_bits(skb, iphoff+iph.ihl*4, &udph, sizeof(udph))
                < 0) {
            printk("INCOMPLETE [%u bytes] ",
                   skb->len - iphoff - iph.ihl*4);
            break;
        }

        /* Max length: 20 "SPT=65535 DPT=65535 " */
        printk("SPT=%u DPT=%u LEN=%u ",
               ntohs(udph.source), ntohs(udph.dest),
               ntohs(udph.len));
        break;
    }
    case IPPROTO_ICMP: {
        struct icmphdr icmph;
        static size_t required_len[NR_ICMP_TYPES+1]
            = { [ICMP_ECHOREPLY] = 4,
                [ICMP_DEST_UNREACH]
                = 8 + sizeof(struct iphdr) + 8,
                [ICMP_SOURCE_QUENCH]
                = 8 + sizeof(struct iphdr) + 8,
                [ICMP_REDIRECT]
                = 8 + sizeof(struct iphdr) + 8,
                [ICMP_ECHO] = 4,
                [ICMP_TIME_EXCEEDED]
                = 8 + sizeof(struct iphdr) + 8,
                [ICMP_PARAMETERPROB]
                = 8 + sizeof(struct iphdr) + 8,
                [ICMP_TIMESTAMP] = 20,
                [ICMP_TIMESTAMPREPLY] = 20,
                [ICMP_ADDRESS] = 12,
                [ICMP_ADDRESSREPLY] = 12
              };

        /* Max length: 11 "PROTO=ICMP " */
        printk("PROTO=ICMP ");

        if (ntohs(iph.frag_off) & IP_OFFSET)
            break;

        /* Max length: 25 "INCOMPLETE [65535 bytes] " */
        if (skb_copy_bits(skb, iphoff+iph.ihl*4, &icmph, sizeof(icmph))
                < 0) {
            printk("INCOMPLETE [%u bytes] ",
                   skb->len - iphoff - iph.ihl*4);
            break;
        }

        /* Max length: 18 "TYPE=255 CODE=255 " */
        printk("TYPE=%u CODE=%u ", icmph.type, icmph.code);

        /* Max length: 25 "INCOMPLETE [65535 bytes] " */
        if (icmph.type <= NR_ICMP_TYPES
                && required_len[icmph.type]
                && skb->len-iphoff-iph.ihl*4 < required_len[icmph.type]) {
            printk("INCOMPLETE [%u bytes] ",
                   skb->len - iphoff - iph.ihl*4);
            break;
        }

        switch (icmph.type) {
        case ICMP_ECHOREPLY:
        case ICMP_ECHO:
            /* Max length: 19 "ID=65535 SEQ=65535 " */
            printk("ID=%u SEQ=%u ",
                   ntohs(icmph.un.echo.id),
                   ntohs(icmph.un.echo.sequence));
            break;

        case ICMP_PARAMETERPROB:
            /* Max length: 14 "PARAMETER=255 " */
            printk("PARAMETER=%u ",
                   ntohl(icmph.un.gateway) >> 24);
            break;
        case ICMP_REDIRECT:
            /* Max length: 24 "GATEWAY=255.255.255.255 " */
            printk("GATEWAY=%u.%u.%u.%u ",
                   NIPQUAD(icmph.un.gateway));
        /* Fall through */
        case ICMP_DEST_UNREACH:
        case ICMP_SOURCE_QUENCH:
        case ICMP_TIME_EXCEEDED:
            /* Max length: 3+maxlen */
            if (!iphoff) { /* Only recurse once. */
                printk("[");
                dump_packet(info, skb,
                            iphoff + iph.ihl*4+sizeof(icmph));
                printk("] ");
            }

            /* Max length: 10 "MTU=65535 " */
            if (icmph.type == ICMP_DEST_UNREACH
                    && icmph.code == ICMP_FRAG_NEEDED)
                printk("MTU=%u ", ntohs(icmph.un.frag.mtu));
        }
        break;
    }
    /* Max Length */
    case IPPROTO_AH: {
        struct ip_auth_hdr ah;

        if (ntohs(iph.frag_off) & IP_OFFSET)
            break;

        /* Max length: 9 "PROTO=AH " */
        printk("PROTO=AH ");

        /* Max length: 25 "INCOMPLETE [65535 bytes] " */
        if (skb_copy_bits(skb, iphoff+iph.ihl*4, &ah, sizeof(ah)) < 0) {
            printk("INCOMPLETE [%u bytes] ",
                   skb->len - iphoff - iph.ihl*4);
            break;
        }

        /* Length: 15 "SPI=0xF1234567 " */
        printk("SPI=0x%x ", ntohl(ah.spi));
        break;
    }
    case IPPROTO_ESP: {
        struct ip_esp_hdr esph;

        /* Max length: 10 "PROTO=ESP " */
        printk("PROTO=ESP ");

        if (ntohs(iph.frag_off) & IP_OFFSET)
            break;

        /* Max length: 25 "INCOMPLETE [65535 bytes] " */
        if (skb_copy_bits(skb, iphoff+iph.ihl*4, &esph, sizeof(esph))
                < 0) {
            printk("INCOMPLETE [%u bytes] ",
                   skb->len - iphoff - iph.ihl*4);
            break;
        }

        /* Length: 15 "SPI=0xF1234567 " */
        printk("SPI=0x%x ", ntohl(esph.spi));
        break;
    }
    /* Max length: 10 "PROTO 255 " */
    default:
        printk("PROTO=%u ", iph.protocol);
    }

    /* Proto    Max log string length */
    /* IP:      40+46+6+11+127 = 230 */
    /* TCP:     10+max(25,20+30+13+9+32+11+127) = 252 */
    /* UDP:     10+max(25,20) = 35 */
    /* ICMP:    11+max(25, 18+25+max(19,14,24+3+n+10,3+n+10)) = 91+n */
    /* ESP:     10+max(25)+15 = 50 */
    /* AH:      9+max(25)+15 = 49 */
    /* unknown: 10 */

    /* (ICMP allows recursion one level deep) */
    /* maxlen =  IP + ICMP +  IP + max(TCP,UDP,ICMP,unknown) */
    /* maxlen = 230+   91  + 230 + 252 = 803 */
}
Example #27
0
static void run_listener(const char* fifo, const guint16 port, const char* proto_name)
{
	struct sockaddr_in clientaddr;
	int clientlen = sizeof(clientaddr);
	socket_handle_t sock;
	char* buf;
	ssize_t buflen;
	FILE* fp = NULL;

	if (signal(SIGINT, exit_from_loop) == SIG_ERR) {
		g_warning("Can't set signal handler");
		return;
	}

	if (setup_dumpfile(fifo, &fp) == EXIT_FAILURE) {
		if (fp)
			fclose(fp);
		return;
	}

	if (setup_listener(port, &sock) == EXIT_FAILURE)
		return;

	g_debug("Listener running on port %u", port);

	buf = (char*)g_malloc(PKT_BUF_SIZE);
	while(run_loop == TRUE) {
		memset(buf, 0x0, PKT_BUF_SIZE);

		buflen = recvfrom(sock, buf, PKT_BUF_SIZE, 0, (struct sockaddr *)&clientaddr, &clientlen);
		if (buflen < 0) {
			switch(errno) {
				case EAGAIN:
				case EINTR:
					break;
				default:
#ifdef _WIN32
					{
						wchar_t *errmsg = NULL;
						int err = WSAGetLastError();
						FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
							NULL, err,
							MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
							(LPWSTR)&errmsg, 0, NULL);
						g_warning("Error in recvfrom: %S (err=%d)", errmsg, err);
						LocalFree(errmsg);
					}
#else
					g_warning("Error in recvfrom: %s (errno=%d)", strerror(errno), errno);
#endif
					run_loop = FALSE;
					break;
			}
		} else {
			if (dump_packet(proto_name, port, buf, buflen, clientaddr, fp) == EXIT_FAILURE)
				run_loop = FALSE;
		}
	}

	fclose(fp);
	closesocket(sock);
	g_free(buf);
}
static void
ipt_log_packet(unsigned int pf,
	       unsigned int hooknum,
	       const struct sk_buff *skb,
	       const struct net_device *in,
	       const struct net_device *out,
	       const struct nf_loginfo *loginfo,
	       const char *prefix)
{
	if (!loginfo)
		loginfo = &default_loginfo;

	spin_lock_bh(&log_lock);

/*purpose     : 0017197 author : Yami date : 2013-04-29    */
/*description : firewall logs has wrong content   */
	if(out)
	{
		printk("<%d>%sIN=%s OUT=%s ", loginfo->u.log.level,
			prefix,
			in ? in->name : "",
			out->name);
	}
	else
	{
		printk("<%d>%sIN=%s ", loginfo->u.log.level,
			prefix,
			in ? in->name : "");
	}

#ifdef CONFIG_BRIDGE_NETFILTER
	if (skb->nf_bridge) {
		struct net_device *physindev = skb->nf_bridge->physindev;
		struct net_device *physoutdev = skb->nf_bridge->physoutdev;

		if (physindev && in != physindev)
			printk("PHYSIN=%s ", physindev->name);
		if (physoutdev && out != physoutdev)
			printk("PHYSOUT=%s ", physoutdev->name);
	}
#endif

/*purpose     : 0017197 author : Yami date : 2013-04-29    */
/*description : firewall logs has wrong content   */
/*
	if (in && !out) {
		// MAC logging for input chain only.
		printk("MAC=");
		if (skb->dev && skb->dev->hard_header_len
		    && skb->mac.raw != (void*)skb->nh.iph) {
			int i;
			unsigned char *p = skb->mac.raw;
			for (i = 0; i < skb->dev->hard_header_len; i++,p++)
				printk("%02x%c", *p,
				       i==skb->dev->hard_header_len - 1
				       ? ' ':':');
		} else
			printk(" ");
	}
*/
	dump_packet(loginfo, skb, 0);
	printk("\n");
	spin_unlock_bh(&log_lock);
}
Example #29
0
/*
 * Returns true/false indicating data successfully read from hypervisor.
 * Used both to get packets for tty connections and to advance the state
 * machine during console handshaking (in which case tty = NULL and we ignore
 * incoming data).
 */
static int hvsi_load_chunk(struct hvsi_struct *hp, struct tty_struct **flip,
		struct tty_struct **hangup, struct hvsi_struct **handshake)
{
	uint8_t *packet = hp->inbuf;
	int chunklen;

	*flip = NULL;
	*hangup = NULL;
	*handshake = NULL;

	chunklen = hvsi_read(hp, hp->inbuf_end, HVSI_MAX_READ);
	if (chunklen == 0) {
		pr_debug("%s: 0-length read\n", __FUNCTION__);
		return 0;
	}

	pr_debug("%s: got %i bytes\n", __FUNCTION__, chunklen);
	dbg_dump_hex(hp->inbuf_end, chunklen);

	hp->inbuf_end += chunklen;

	/* handle all completed packets */
	while ((packet < hp->inbuf_end) && got_packet(hp, packet)) {
		struct hvsi_header *header = (struct hvsi_header *)packet;

		if (!is_header(packet)) {
			printk(KERN_ERR "hvsi%i: got malformed packet\n", hp->index);
			/* skip bytes until we find a header or run out of data */
			while ((packet < hp->inbuf_end) && (!is_header(packet)))
				packet++;
			continue;
		}

		pr_debug("%s: handling %i-byte packet\n", __FUNCTION__,
				len_packet(packet));
		dbg_dump_packet(packet);

		switch (header->type) {
			case VS_DATA_PACKET_HEADER:
				if (!is_open(hp))
					break;
				if (hp->tty == NULL)
					break; /* no tty buffer to put data in */
				*flip = hvsi_recv_data(hp, packet);
				break;
			case VS_CONTROL_PACKET_HEADER:
				hvsi_recv_control(hp, packet, hangup, handshake);
				break;
			case VS_QUERY_RESPONSE_PACKET_HEADER:
				hvsi_recv_response(hp, packet);
				break;
			case VS_QUERY_PACKET_HEADER:
				hvsi_recv_query(hp, packet);
				break;
			default:
				printk(KERN_ERR "hvsi%i: unknown HVSI packet type 0x%x\n",
						hp->index, header->type);
				dump_packet(packet);
				break;
		}

		packet += len_packet(packet);

		if (*hangup || *handshake) {
			pr_debug("%s: hangup or handshake\n", __FUNCTION__);
			/*
			 * we need to send the hangup now before receiving any more data.
			 * If we get "data, hangup, data", we can't deliver the second
			 * data before the hangup.
			 */
			break;
		}
	}

	compact_inbuf(hp, packet);

	return 1;
}
Example #30
0
int main( int argc, char* argv[] )
{
	int		socket;
	unsigned char	data[1280];
	int		size;

	libnet_t	*libnet_context;
	char		libnet_errmsg_buf[LIBNET_ERRBUF_SIZE];

	//socket = sock_afpacket( argv[1] ); 
	socket = sock_udp( argv[2], strtoul(argv[3], NULL, 10 ) );
	if ( socket == -1 )
	{
		fprintf(stderr, "socket error\n");
		return 1;
	}

	// libnetのコンテキスト作成
	libnet_context = libnet_init(LIBNET_RAW6_ADV, NULL, libnet_errmsg_buf );
	//libnet_context = libnet_init(LIBNET_RAW6_ADV, argv[1], libnet_errmsg_buf );
	if ( NULL == libnet_context )
	{
		fprintf(stderr, "%s\n", libnet_errmsg_buf );
		close(socket);
		return 1;
	}
		
	for(;;)
	{
		libnet_ptag_t			ptag_udp, ptag_ip6;
		uint8_t					*pbuf;
		uint32_t				payload_len;
		
		//afpacketからのデータ受信
		//size = recv_packet( socket, sizeof(data), data );
		//print_ipv6_header( data );

		// UDPデータ受信
		size = recv( socket, data, sizeof(data), MSG_TRUNC );
		
		printf("data recieve. ");
		dump_packet( size, data );
		putc('\n', stdout);

		// UDPヘッダ
		ptag_udp = libnet_build_udp(
			(uint16_t)(random()%(65535-49152)+49152),	// source port(49152 - 65535)
			53,		// destination port
			sizeof(header_udp) + size,	// length of UDP pakcet
			0,			// checksum(autofill)
			data,		// payload
			size,		// payload length
			libnet_context,
			0 );
		
		pbuf = libnet_getpbuf( libnet_context, ptag_udp );
		payload_len = libnet_getpbuf_size( libnet_context, ptag_udp );

		// IPv6ヘッダ
		ptag_ip6 = libnet_build_ipv6(
			0,		// Traffic Class
			0,		// Flow Label
			//sizeof(header_ipv6) + sizeof(header_udp) + size,	// total length of the IP packet
			sizeof(header_udp) + size,	// total length of the IP packet
			IPPROTO_UDP,	// Next header(UDP)
			10,		// Hop Limit
			libnet_name2addr6(
				libnet_context, SRC_IP, LIBNET_DONT_RESOLVE ),		// src ip
			libnet_name2addr6(
				libnet_context, DST_IP, LIBNET_DONT_RESOLVE ),		// dst ip
			pbuf,			// payload
			payload_len,	// Payload Length
			libnet_context,
			0 );
		
		// 送信データ取得
		pbuf = libnet_getpbuf( libnet_context, ptag_ip6 );
		payload_len = libnet_getpbuf_size( libnet_context, ptag_ip6 );

		// チェックサム計算←IPv6は未対応の模様
		//libnet_do_checksum( libnet_context, pbuf, IPPROTO_UDP, payload_len );

		printf("data sending. ");
		dump_packet( payload_len, pbuf );

		// データ送信
		//libnet_write_raw_ipv6( libnet_context, data, size );
		libnet_write_raw_ipv6( libnet_context, pbuf, payload_len );

		// 作成データ解放
		libnet_clear_packet( libnet_context );
	}

	return 0;
}