LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices



Reply
 
Search this Thread
Old 01-28-2008, 10:22 PM   #1
nasim751
Member
 
Registered: Jan 2008
Posts: 40

Rep: Reputation: 15
Post segmentation error (core dumped) Linux in c


hello,
Thanks for propose idea for gbd. I got the problem exactly where is in my program.
Program received signal SIGSEGV, Segmentation fault.
0x08048a6b in descry_init (gp=0x8049e39, device=0x0, capture_file=0x0,
flags=0 '\0') at descry.c:161
161 *gp = malloc(sizeof(struct descry_pack));

here i attach my program...........
#include <syslog.h>
#include <libnet.h>
#include <pcap.h>
#include <time.h>
/* misc defines */
#define MAX_STRING 0x100 /* default string length */
#define CON_REMOVED 0xFFFFFFFF /* tag a node for removal */
#define CLEANUP_INTERVAL 1000 /* how often the cleaner runs */
#define EXPIRE_TIME 11800 /* seconds that a connection should
* should linger in SYN-ACK state
* before it gets expired
*/
#define MAX_PACKET 1500 /* max packet size */

/* filter to catch SYN-ACK, FIN-ACK, and RST segments */
#define FILTER "((tcp[13] & 0x12) == 0x12) || \
((tcp[13] & 0x11) == 0x11) || \
((tcp[13] & 0x14) == 0x14) || \
((tcp[13] & 0x04) == 0x04)"


/* patricia key symbolic constants */
#define KEY_BYTES 12
#define MIN_KEY_BIT 0
#define MAX_KEY_BIT (KEY_BYTES * 8 - 1)

/*
* Simple way to subtract timeval based timers. Not every OS has this,
* so we'll just define it here.
*/
#define PTIMERSUB(tvp, uvp, vvp) \
do \
{ \
(vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec; \
(vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec; \
if ((vvp)->tv_usec < 0) \
{ \
(vvp)->tv_sec--; \
(vvp)->tv_usec += 1000000; \
} \
} \
while (0) \

/* code cleanup to set connection state */
#define SET_STATE(c, dip, dp, sip, sp, s) \
{ \
c->dst_addr.s_addr = dip; \
c->dst_port = dp; \
c->src_addr.s_addr = sip; \
c->src_port = sp; \
c->seq = s; \
} \

/* TCP connection info */
struct tcp_connection
{
struct in_addr src_addr;
struct in_addr dst_addr;
struct timeval ts;
u_long seq;
u_short src_port;
u_short dst_port;
};

/* decision node within the patricia trie */
struct pt_node
{
int bit;
struct pt_node *l;
struct pt_node *r;
struct tcp_connection *con;
};

/* patricia trie context */
struct pt_context
{
struct pt_node *head;
u_long n;
};

/* main descry control context */
struct descry_pack
{
pcap_t *p;
u_char flags;
#define ALL_HOSTS 0x1
#define DO_SYSLOG 0x02
int offset;
struct pt_context *pt;
};


/********************************************************************/
/*Function Body*/
/********************************************************************/
int
descry_init(struct descry_pack **gp, char *device, char *capture_file,
u_char flags)
{
char *interface = NULL;
char error[PCAP_ERRBUF_SIZE];
struct bpf_program prog;
u_int32_t network, netmask;

*gp = malloc(sizeof(struct descry_pack)); this is the problem line
if (*gp == NULL)
{
perror("descry_init(): malloc(): ");
return (0);
}

/* initialize the patricia trie */
if (pt_init(&((*gp)->pt)) == 0)
{
/* error set in pt_init() */
return (EXIT_FAILURE);
}

/* control flags */
(*gp)->flags = flags;

if (capture_file)
{
/* we have a capture file to analyze */
(*gp)->p = pcap_open_offline(capture_file, error);
if ((*gp)->p == NULL)
{
fprintf(stderr, "pcap_open_offline() %s\n", error);
return (0);
}
}
else
{
/* we're doing a live capture, do we have a device? */
if (device)
{
interface = device;
}
else
{
interface = pcap_lookupdev(error);
if (interface == NULL)
{
fprintf(stderr, "pcap_lookupdev(): %s\n", error);
return (0);
}
}
(*gp)->p = pcap_open_live(interface, MAX_PACKET,
((*gp)->flags & ALL_HOSTS), 0, error);
if ((*gp)->p == NULL)
{
fprintf(stderr, "pcap_open_live() %s\n", error);
return (0);
}
}

/* get the length of the link layer header */
switch (pcap_datalink((*gp)->p))
{
case DLT_SLIP:
/* a little SLIPstreaming! Whoops! There's Charlie! */
(*gp)->offset = 0x10;
break;
case DLT_PPP:
/* PPP y0 */
(*gp)->offset = 0x04;
break;
default:
case DLT_EN10MB:
/* good old ethernet or something like it I hope! */
(*gp)->offset = 0x0e;
break;
}

if (interface)
{
/* compile our filter and apply it to the interface */
if (pcap_lookupnet(interface, &network, &netmask, error) < 0)
{
fprintf(stderr, "pcap_lookupnet() %s\n", error);
return (0);
}
}
if (pcap_compile((*gp)->p, &prog, FILTER, 1, netmask) < 0)
{
fprintf(stderr, "pcap_compile(): \"%s\" failed\n", FILTER);
return (0);
}
if (pcap_setfilter((*gp)->p, &prog) < 0)
{
fprintf(stderr, "pcap_setfilter() failed\n");
return 0;
}
return (1);
}
/********************************************************************/
void
descry_destroy(struct descry_pack *gp)
{
/* do something someday*/
}
/********************************************************************/
/********************************************************************/
void
pt_expire(struct descry_pack *gp, struct timeval* ts)
{
/* walk the tree and expire old connections */
pt_walk_r(gp, gp->pt->head, gp->pt->head, ts);
}
/********************************************************************/
void
descry(u_char *u, struct pcap_pkthdr *phdr, u_char *packet)
{
struct libnet_ipv4_hdr *ip;
struct libnet_tcp_hdr *tcp;
struct descry_pack *gp;
struct tcp_connection *c;
struct tcp_connection *rc;
static u_char cleanup = 0;
struct timeval ts;

rc = NULL;
c = NULL;
gp = (struct descry_pack *)u;

/*
* In order to keep the trie from growing boundlessly, we need to
* periodically expire half open connections.
*/
if (cleanup++ > CLEANUP_INTERVAL)
{
ts.tv_usec = phdr->ts.tv_usec;
ts.tv_sec = phdr->ts.tv_sec;

/* expire old connections */
pt_expire(gp, &ts);
cleanup = 0;
}


if (phdr->len < (gp->offset + LIBNET_IPV4_H + LIBNET_TCP_H))
{
return;
}

/* overlay IP and TCP headers */
ip = (struct libnet_ipv4_hdr *)(packet + gp->offset);
tcp = (struct libnet_tcp_hdr *)(packet + gp->offset +
(ip->ip_hl << 2));

/* shave off the lower order 6 bits containing the control flags */
switch (tcp->th_flags & 0x3F)
{
case (TH_SYN | TH_ACK):
/* this is a new connection to be added to the trie */

/* get memory for the connection state */
c = malloc(sizeof (struct tcp_connection ));
if (c == NULL)
{
return;
}

/* set connection state */
memcpy(&(c->ts), &(phdr->ts), sizeof(struct timeval));

SET_STATE(c, ip->ip_src.s_addr, tcp->th_sport,
ip->ip_dst.s_addr, tcp->th_dport, tcp->th_ack);

/* insert TCP connection into the trie */
if (pt_insert(gp->pt, c) == 0)
{
fprintf(stderr, "pt_insert() failed!\n");
}
break;
case (TH_FIN | TH_ACK):
case (TH_RST):
case (TH_RST | TH_ACK):
/* connection teardown */

/* get memory for the connection state */
c = malloc(sizeof (struct tcp_connection));
if (c == NULL)
{
return;
}
/* set connection state so we can search for the connection */
SET_STATE(c, ip->ip_dst.s_addr, tcp->th_dport,
ip->ip_src.s_addr, tcp->th_sport, tcp->th_seq);


if (pt_find(gp->pt, c, &rc))
{

check_state(gp, c, rc);

/* delete the connection from the trie */
pt_delete(gp->pt, rc);
}
else
{

SET_STATE(c, ip->ip_src.s_addr, tcp->th_sport,
ip->ip_dst.s_addr, tcp->th_dport, tcp->th_ack);
pt_delete(gp->pt, c);
}
free(c);
break;
default:
break;
}
}
/********************************************************************/
char *
get_time()
{
int i;
time_t t;
static char buf[26];

t = time((time_t *)NULL);
strcpy(buf, ctime(&t));

/* cut out the day, year and \n */
for (i = 0; i < 20; i++)
{
buf[i] = buf[i + 4];
}
buf[15] = 0;

return (buf);
}
/********************************************************************/
void
check_state(struct descry_pack *gp, struct tcp_connection *con1,
struct tcp_connection *con2)
{
/* check sequence number delta to see if data was sent */
if (ntohl(con1->seq) >= ntohl(con2->seq) &&
ntohl(con1->seq) <= ntohl(con2->seq) + 2)
{
if (gp->flags & DO_SYSLOG)
{
syslog(LOG_NOTICE,
"Possible TCP port scan from %s:%d to %s:%d",
libnet_addr2name4(con1->src_addr.s_addr,
LIBNET_DONT_RESOLVE),
ntohs(con1->src_port),
libnet_addr2name4(con1->dst_addr.s_addr,
LIBNET_DONT_RESOLVE),
ntohs(con1->dst_port));
}
else
{
fprintf(stderr,
"[%s] TCP probe from %s:%d to %s:%d\n",
get_time(),
libnet_addr2name4(con1->src_addr.s_addr,
LIBNET_DONT_RESOLVE),
ntohs(con1->src_port),
libnet_addr2name4(con1->dst_addr.s_addr,
LIBNET_DONT_RESOLVE),
ntohs(con1->dst_port));
}
}
}
/********************************************************************/
void
pt_make_key(u_char *key, struct tcp_connection *c)
{
if (c == NULL)
{
fprintf(stderr, "pt_make_key(): c is NULL!\n");
return;
}
/* create a key for the trie from connection info */
memcpy(key, &(c->src_addr.s_addr), 4);
memcpy(key + 4, &(c->src_port), 2);
memcpy(key + 6, &(c->dst_addr.s_addr), 4);
memcpy(key + 10, &(c->dst_port), 2);
}

struct pt_node *
pt_new(int bit, struct pt_node *l, struct pt_node *r,
struct tcp_connection *con)
{
struct pt_node *p = NULL;

p = malloc(sizeof(struct pt_node));
if (p)
{
p->bit = bit;
p->l = l;
p->r = r;
p->con = con;
}
return (p);
}
/********************************************************************/
int
pt_init(struct pt_context **p)
{
*p = malloc(sizeof(struct pt_context));
if (*p == NULL)
{
perror("pt_init(): malloc(): ");
return (0);
}

/* point the head node to NULL and set the node counter to 0 */
(*p)->head = NULL;
(*p)->n = 0;

return (1);
}
/********************************************************************/
int
get_bit(u_char *key, struct pt_node *n)
{
u_char conkey[KEY_BYTES];

memset(conkey, NULL, KEY_BYTES);
if (n->bit < MIN_KEY_BIT || n->bit > MAX_KEY_BIT)
{
pt_make_key(conkey, n->con);
if (memcmp(key, conkey, KEY_BYTES) == 0)
{
/* found a match! */
return (2);
}
else
{
/* did not match */
return (3);
}
}

return ((key[n->bit / 8] >> (7 - (n->bit % 8))) & 0x01);
}
/********************************************************************/
int
pt_search_r(struct pt_node *n, u_char *key, struct pt_node **rc)
{
/* extract bit from the key */
switch (get_bit(key, n))
{
case 0:
return (pt_search_r(n->l, key, rc));
case 1:
return (pt_search_r(n->r, key, rc));
case 2:
*rc = n;
return (1);
default:
*rc = n;
return (0);
}
}
/********************************************************************/
int
pt_remove_r(struct pt_context *pt, struct pt_node *n, u_char *key,
struct pt_node *prev)
{
struct pt_node *tmp;

if (n == NULL)
{
return (0);
}

/* extract bit from the key */
switch (get_bit(key, n))
{
case 0:
/* recurse down the left of this node */
return (pt_remove_r(pt, n->l, key, n));
break;
case 1:
/* recurse down the right of this node */
return (pt_remove_r(pt, n->r, key, n));
break;
case 2:

free(n->con);
n->con = (struct tcp_connection *)CON_REMOVED;
/
if (prev == NULL)
{
return (1);
}

if ((int)prev->l->con == CON_REMOVED)
{
tmp = prev->r->r;
free(prev->l);
prev->con = prev->r->con;
prev->bit = prev->r->bit;
prev->l = prev->r->l;
free(prev->r);
prev->r = tmp;
}

else
{
tmp = prev->l->l;
free(prev->r);
prev->con = prev->l->con;
prev->bit = prev->l->bit;
prev->r = prev->l->r;
free(prev->l);
prev->l = tmp;
}
/* decrement node counter in trie context structure */
pt->n -= 2;
return (1);
default:
return (0);
}
}
/********************************************************************/
void
pt_delete(struct pt_context *pt, struct tcp_connection *c)
{
u_char key[KEY_BYTES];

/* if the trie is empty, just return */
if (pt->head == NULL)
{
return;
}
/* generate the trie key for this connection record */
memset(key, NULL, KEY_BYTES);
pt_make_key(key, c);

/* call the recursive search and delete function */
if (pt_remove_r(pt, pt->head, key, NULL))
{
/
if (pt->n == 1 && (int)(pt->head->con) == CON_REMOVED)
{
free(pt->head);
pt->head = NULL;
pt->n = 0;
}
}
}
/********************************************************************/
int
pt_find(struct pt_context *pt, struct tcp_connection *c,
struct tcp_connection **rc)
{
u_char key[KEY_BYTES];
struct pt_node *rn;
int r;

if (pt->head == NULL)
{
/* can't find anything in a NULL trie */
*rc = NULL;
return (0);
}

/* get a key for this connection */
memset(key, NULL, KEY_BYTES);
pt_make_key(key, c);

rn = NULL;
r = pt_search_r(pt->head, key, &rn);

/* point the retrieved connection to the node found */
*rc = rn->con;

return (r);
}
/********************************************************************/
int
diff_bit(u_char *key1, u_char *key2, int *b)
{
int i, j;
unsigned char v;

/* iterate through all key bytes */
for (i = 0; i < KEY_BYTES; i++)
{
/* XOR each byte to find the first differing key byte */
if ((v = key1[i] ^ key2[i]))
{

for (j = 0; j < 8; j++)
{
/* left shift with bitwise AND with a high bit mask */
if (v << j & 0x80)
{
/*
* Isolate the differring bit in key1 and place the
* actual value of the bit in b.
*/
*b = key1[i] >> (7 - j) & 0x01;

*/
return (i * 8 + j);
}
}
}
}
/* no difference */
return (MAX_KEY_BIT);
}
/********************************************************************/
int
pt_insert(struct pt_context *pt, struct tcp_connection *c)
{
struct pt_node *rn = NULL;
u_char key1[KEY_BYTES], key2[KEY_BYTES];
int b;

if (pt->head == NULL)
{
/* make a new head node */
pt->head = pt_new(MIN_KEY_BIT - 1, NULL, NULL, c);
if (pt->head == NULL)
{
perror("pt_insert(): malloc(): ");
return (0);
}
else
{
/* increment node counter and return success */
pt->n++;
return (1);
}
}
else
{
memset(key1, NULL, KEY_BYTES);
pt_make_key(key1, c);

switch (pt_search_r(pt->head, key1, &*rn))
{
case 0:
memset(key2, NULL, KEY_BYTES);
pt_make_key(key2, rn->con);

/* find the first differing bit, and its value */
rn->bit = diff_bit(key1, key2, &b);

if (((b ? rn->r : rn->l) == pt_new(MIN_KEY_BIT - 1, NULL, NULL, c)) == NULL)
{
return (0);
}

if (((b ? rn->l : rn->r) == pt_new(MIN_KEY_BIT - 1, NULL, NULL, rn->con)) == NULL)
{
free(b ? rn->r : rn->l);
return (0);
}
rn->con = NULL;
/* added two new nodes */
pt->n += 2;
return (1);
case 1:
return (2);
}
}
return (0);
}
/********************************************************************/
void
pt_walk_r(struct descry_pack *gp, struct pt_node *cur,
struct pt_node *pre, struct timeval* ts)
{
struct timeval tsdif;

if (cur == NULL || pre == NULL)
{
/* can't walk a NULL trie */
return;
}

/* if this is a decision node, then keep walking */
if (cur->bit >= MIN_KEY_BIT && cur->bit <= MAX_KEY_BIT)
{
pt_walk_r(gp, cur->l, cur, ts);
}

/* looks like a data node, so check the connection values */
else if (NULL != cur->con)
{
PTIMERSUB(ts, &(cur->con->ts), &tsdif);

/*
* If the timestamp on the current connection is too old
* remove it.
*/
if (EXPIRE_TIME < tsdif.tv_sec)
{
pt_delete(gp->pt, cur->con);
}

/* return if we reach the far right or the root node */
if (cur == pre || cur == pre->r)
{
return;
}

/* otherwise, go up one and to the right */
pt_walk_r(gp, pre->r, pre, ts);
}
else
{
/*
* If we hit this code block we have major problems -- a node
* looks like it is a data node, but it has no data. We'll
* warn and bail immediately.
*/
if (gp->flags & DO_SYSLOG)
{
syslog(LOG_WARNING, "Internal data structure corrupted!");
}
else
{
fprintf(stderr, "Internal data structure corrupted!\n");
}
abort();
}
}
/********************************************************************/
/*/void
pt_expire(struct descry_pack *gp, struct timeval* ts)
{
/* walk the tree and expire old connections
pt_walk_r(gp, gp->pt->head, gp->pt->head, ts);*/
//}
/********************************************************************/

/********************************************************************/
void
usage(char* name)
{
fprintf(stderr,
"usage %s [options] (-i and -f are mutually exclusive)\n"
"-a\t\tmonitor all hosts in the same segment\n"
"-i interface\tspecify device <or>\n"
"-f capture file\tspecify tcpdump capture file\n"
"-s\t\tlog to syslog instead of stderr\n", name);
}



/*************************************************************************/
/*Main Program*/
/*************************************************************************/
int
main(int argc, char *argv[])
{
int c;
u_char flags;
char *device;
char *capture_file;
struct descry_pack *gp;
printf("Descry 1.0 [TCP port scan detection tool]\n");

flags = 0;
device = NULL;
capture_file = NULL;
while ((c = getopt(argc, argv, "ahf:i:vs")) != EOF)
{
switch (c)
{
case 'a':
flags |= ALL_HOSTS;
break;
case 'f':
capture_file = optarg;
break;
case 'i':
device = optarg;
break;
case 'v':
break;
case 's':
flags |= DO_SYSLOG;
break;
case 'h':
default:
usage(argv[0]);
return (EXIT_FAILURE);
}
}

/* either read from a capture file OR run on the network */
if (capture_file && device)
{
usage(argv[0]);
return (EXIT_FAILURE);
}

if (descry_init(gp, device, capture_file, flags) == 0)
{
fprintf(stderr, "descry_init(): catastrophic failure\n");
return (EXIT_FAILURE);
}

while (pcap_dispatch(&gp->p, 0, (pcap_handler)descry, (u_char*)gp));

descry_destroy(gp);

return (EXIT_SUCCESS);
}
 
Old 01-29-2008, 03:40 PM   #2
orgcandman
Member
 
Registered: May 2002
Location: dracut MA
Distribution: Ubuntu; PNE-LE; LFS (no book)
Posts: 594

Rep: Reputation: 102Reputation: 102
Code:
if (descry_init(gp, device, capture_file, flags) == 0)
Your error lies here. The compiler should have produced a warning along the lines of:
"converting type struct descry_pack * to struct descry_pack ** results in invalid assignment"

Something like that anyway.

The key is to open your K&R C (2nd edition) to page 94. This discusses pointers and addresses.

If you don't have this book, here's a brief overview:

Code:
int *pi;   /* This is a pointer to an integer */
int   i;   /* This is an actual integer */
int **ppi; /* This points to a pointer to an integer */

i = 12;
pi = &i;
ppi = &pi;

printf("The value [%d] can be found at [%p] and that has a pointer at [%p]\n", i, pi, ppi);
This should contain all the information you need. If not, feel free to post again.

Last edited by orgcandman; 01-29-2008 at 03:43 PM.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Segmentation fault (core dumped) nasim751 Programming 2 01-28-2008 03:56 PM
Segmentation fault (core dumped) nasim751 Programming 1 01-27-2008 10:18 PM
segmentation error (core dumped) Linux in c nasim751 Programming 1 01-27-2008 06:12 PM
segmentation error (core dumped) Linux in c nasim751 Programming 2 01-27-2008 06:06 PM
Segmentation fault (core dumped) plisken Linux - General 8 09-17-2003 04:32 AM


All times are GMT -5. The time now is 01:56 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration