/*
** k_linux.c - Linux 0.99.13q or later kernel access functions
**
** Copyright (c) 1997-1998 Peter Eriksson <pen@lysator.liu.se>
**
** This program is free software; you can redistribute it and/or
** modify it as you wish - as long as you don't claim that you wrote
** it.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/

#include "config.h"

#include <stdio.h>
#include <syslog.h>
#include <errno.h>

#include <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include "pidentd.h"

/*
** Make sure we are running on a supported OS version
*/
int
ka_init(void)
{
    return 0; /* We always succeed */
}


int
ka_open(void **misc)
{
    FILE *fp;

    
    while ((fp = fopen("/proc/net/tcp", "r")) == NULL && errno == EINTR)
	;
    
    if (fp == NULL)
    {
	syslog(LOG_ERR, "fopen(\"/proc/net/tcp\", \"r\"): %m");
	return -1;
    }

    *misc = (void *) fp;
    return 0;
}


int 
ka_lookup(void *vp, struct kernel *kp)
{
    FILE *fp;
    long dummy;
    char buf[512];
    long r_laddr, r_raddr, myladdr, myraddr;
    int r_lport, r_rport, mylport, myrport;
    int euid;
    
    
    r_rport = ntohs(kp->remote.sin_port);
    r_lport = ntohs(kp->local.sin_port);
    r_raddr = kp->remote.sin_addr.s_addr;
    r_laddr = kp->local.sin_addr.s_addr;

    fp = (FILE *) vp;

    kp->ruid = NO_UID;
    rewind(fp);

    /* eat header */
    if (fgets(buf, sizeof(buf)-1,fp) == NULL)
	return -1;

    while (fgets(buf, sizeof(buf)-1, fp) != NULL)
    {
	if (sscanf(buf, "%d: %lX:%x %lX:%x %x %lX:%lX %x:%lX %lx %d %ld %d",
		   &dummy, &myladdr, &mylport, &myraddr, &myrport,
		   &dummy, &dummy, &dummy, &dummy, &dummy, &dummy,
		   &euid, &dummy, &dummy) >= 12)
	{
	    if (myladdr == r_laddr && mylport == r_lport &&
		myraddr == r_raddr && myrport == r_rport)
	    {
		kp->euid = euid;
		return 1;
	    }
	}
    }

    return -1;
}

