97 lines
2.3 KiB
C
97 lines
2.3 KiB
C
/*
|
|
* udp_packet.c
|
|
*
|
|
* $Id: udp_packet.c,v 1.1.1.1 1999/10/27 09:54:38 fukusima Exp $
|
|
*
|
|
* Copyright (C) 1999 Masaki Fukushima
|
|
*/
|
|
|
|
#include "ruby_pcap.h"
|
|
#include <limits.h>
|
|
|
|
#define UDP_HDR(pkt) ((struct udphdr *)LAYER4_HDR(pkt))
|
|
#define UDP_DATA(pkt) ((u_char *)LAYER5_HDR(pkt))
|
|
#define UDP_LENGTH(pkt) (ntohs(UDP_HDR(pkt)->uh_ulen))
|
|
|
|
VALUE cUDPPacket;
|
|
|
|
#define CheckTruncateUdp(pkt, need) \
|
|
CheckTruncate(pkt, pkt->hdr.layer4_off, need, "truncated UDP")
|
|
|
|
VALUE
|
|
setup_udp_packet(pkt, tl_len)
|
|
struct packet_object *pkt;
|
|
int tl_len;
|
|
{
|
|
VALUE class;
|
|
|
|
DEBUG_PRINT("setup_udp_packet");
|
|
|
|
class = cUDPPacket;
|
|
if (tl_len > 8) {
|
|
int hl = 8;
|
|
int layer5_len;
|
|
|
|
tl_len = MIN(tl_len, UDP_LENGTH(pkt));
|
|
layer5_len = tl_len - hl;
|
|
if (layer5_len > 0) {
|
|
pkt->hdr.layer5_off = pkt->hdr.layer4_off + hl;
|
|
/* upper layer */
|
|
}
|
|
}
|
|
return class;
|
|
}
|
|
|
|
#define UDPP_METHOD(func, need, val) \
|
|
static VALUE\
|
|
(func)(self)\
|
|
VALUE self;\
|
|
{\
|
|
struct packet_object *pkt;\
|
|
struct udphdr *udp;\
|
|
DEBUG_PRINT(#func);\
|
|
GetPacket(self, pkt);\
|
|
CheckTruncateUdp(pkt, (need));\
|
|
udp = UDP_HDR(pkt);\
|
|
return (val);\
|
|
}
|
|
|
|
UDPP_METHOD(udpp_sport, 2, INT2FIX(ntohs(udp->uh_sport)))
|
|
UDPP_METHOD(udpp_dport, 4, INT2FIX(ntohs(udp->uh_dport)))
|
|
UDPP_METHOD(udpp_len, 6, INT2FIX(ntohs(udp->uh_ulen)))
|
|
UDPP_METHOD(udpp_sum, 8, INT2FIX(ntohs(udp->uh_sum)))
|
|
|
|
static VALUE
|
|
udpp_data(self)
|
|
VALUE self;
|
|
{
|
|
struct packet_object *pkt;
|
|
int len;
|
|
|
|
DEBUG_PRINT("udpp_data");
|
|
GetPacket(self, pkt);
|
|
CheckTruncateUdp(pkt, 8);
|
|
|
|
if (pkt->hdr.layer5_off == OFF_NONEXIST) return Qnil;
|
|
|
|
len = MIN(Caplen(pkt, pkt->hdr.layer5_off), UDP_LENGTH(pkt)-8);
|
|
return rb_str_new(UDP_DATA(pkt), len);
|
|
}
|
|
|
|
void
|
|
Init_udp_packet(void)
|
|
{
|
|
DEBUG_PRINT("Init_udp_packet");
|
|
|
|
/* define class UdpPacket */
|
|
cUDPPacket = rb_define_class_under(mPcap, "UDPPacket", cIPPacket);
|
|
|
|
rb_define_method(cUDPPacket, "udp_sport", udpp_sport, 0);
|
|
rb_define_method(cUDPPacket, "sport", udpp_sport, 0);
|
|
rb_define_method(cUDPPacket, "udp_dport", udpp_dport, 0);
|
|
rb_define_method(cUDPPacket, "dport", udpp_dport, 0);
|
|
rb_define_method(cUDPPacket, "udp_len", udpp_len, 0);
|
|
rb_define_method(cUDPPacket, "udp_sum", udpp_sum, 0);
|
|
rb_define_method(cUDPPacket, "udp_data", udpp_data, 0);
|
|
}
|