Hi!

Well, i've been writing some code, and now maybe is a good idea you check it 
out 
and continue development from there. I only have the comments for reference, 
i'll
take them off one of these days...

Give some feedback  :)


Marcelo Coelho



DISCLAIMER: This message may contain confidential information or privileged 
material and is intended only for the individual(s) named. If you are not a 
named addressee and mistakenly received this message you should not copy or 
otherwise disseminate it: please delete this e-mail from your system and notify 
the sender immediately. E-mail transmissions are not guaranteed to be secure or 
error-free as information could be intercepted, corrupted, lost, destroyed, 
arrive late or incomplete or contain viruses. Therefore, the sender does not 
accept liability for any errors or omissions in the contents of this message 
that arise as a result of e-mail transmissions. Please request a hard copy 
version if verification is required. Critical Software.


/***
 *
 *  ipv4/raw.c
 *
 *  rtnet - real-time networking subsystem
 *  Copyright (C) 2006 Marcelo J Coelho <[EMAIL PROTECTED]>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  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.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */


#ifdef RAW_TEST_C

#include <linux/types.h>
#include <linux/socket.h>
#include <linux/in.h>
#include <linux/ip.h>
                #include <linux/icmp.h>
#include <net/checksum.h>

                #include <rtskb.h>
#include <rtnet_socket.h>
                #include <ipv4_chrdev.h>
                #include <ipv4/icmp.h>
#include <ipv4/ip_fragment.h>
#include <ipv4/ip_output.h>
#include <ipv4/protocol.h>
#include <ipv4/route.h>

//      NECESSÁRIO????
struct rt_raw_control {
    void (*handler) (struct rtskb *skb);
    short error;
}


/** IMPLEMENTADO
*/
struct raw_bxm {
    unsigned int    csum;
    size_t          head_len;
    size_t          data_len;
    off_t           offset;
    
    struct {
        struct icmphdr  icmph;
        nanosecs_t      timestamp;
    } head;
    
    union {
        struct rtskb    *skb;
        void            *buf;
    } data;
};

//RTDM locking system
static rtdm_lock_t      raw_socket_base_lock = RTDM_LOCK_UNLOCKED;

static struct raw_socket {
    u16             sport;      /* local port */
    u32             saddr;      /* local ip-addr */
    struct rtsocket *sock;
}

//static struct rt_socket raw_socket;     //Usado no icmp como reply socket, passível de ser usado por várias tarefas

/***
 *  rt_raw_init
 */
void __init rt_raw_init( void )
{
    rt_inet_add_protocol( &raw_protocol );
}

/***
 *  RAW-Initialisation
 */
static struct rtinet_protocol raw_protocol = {
    protocol:       IPPROTO_RAW,
    dest_socket:    &rt_raw_dest_socket,
    rcv_handler:    &rt_raw_rcv,
    err_handler:    &rt_raw_rcv_err,
    init_socket:    &rt_raw_socket
};

/***
 *  rt_raw_rcv_err
 */
void rt_raw_rcv_err (struct rtskb *skb)
{
    rtdm_printk("RTnet: rt_raw_rcv err\n");
}

int rt_raw_socket (struct rtdm_dev_context *sockctx, rtdm_user_info_t *user_info)
{
    struct rtsocket *sock = (struct rtsocket *)&sockctx->dev_private;
    int             ret;
    int             i;
    int             index;
    rtdm_lockctx_t  context;


    if ((ret = rt_socket_init(sockctx)) != 0)
        return ret;
    
    sock->protocol        = IPPROTO_RAW;
    sock->prot.inet.saddr = INADDR_ANY;
    sock->prot.inet.state = TCP_CLOSE;
#ifdef CONFIG_RTNET_RTDM_SELECT
    sock->wakeup_select   = NULL;
#endif /* CONFIG_RTNET_RTDM_SELECT */
    
//     rtdm_lock_get_irqsave(&raw_socket_base_lock, context);
    
    /* enforce maximum number of UDP sockets */
//     if (free_ports == 0) {
//         rtdm_lock_put_irqrestore(&raw_socket_base_lock, context);
//         rt_socket_cleanup(sockctx);
//         return -EAGAIN;
//     }
//     free_ports--;
//     
//     /* find free auto-port in bitmap */
//     for (i = 0; i < sizeof(port_bitmap)/4; i++)
//         if (port_bitmap[i] != 0xFFFFFFFF)
//             break;
//     
//     
//     index = ffz(port_bitmap[i]);
//     set_bit(index, &port_bitmap[i]);
//     index += i*32;
/*    sock->prot.inet.reg_index = index;
    sock->prot.inet.sport     = index + auto_port_start;*/
    
    /* register UDP socket */
//     port_registry[index].sport = sock->prot.inet.sport;
//     port_registry[index].saddr = INADDR_ANY;
//     port_registry[index].sock  = sock;
    
//     rtdm_lock_put_irqrestore(&raw_socket_base_lock, context);
    
    return 0;
}
/** FIM DO IMPLEMENTADO
*/






/***
 *  rt_raw_connect
 */
int rt_raw_connect(struct rtsocket *sock,
                   const struct sockaddr *serv_addr,
                   socklen_t addrlen)
{
    struct sockaddr_in  *usin = (struct sockaddr_in *) serv_addr;
    rtdm_lockctx_t      context;
    int                 index;
    
    
    if (usin->sin_family == AF_UNSPEC) {
        //if ((index = sock->prot.inet.reg_index) < 0)
        //    /* socket is being closed */
        //    return -EBADF;
        
        rtdm_lock_get_irqsave(&raw_socket_base_lock, context);
        
        sock->prot.inet.saddr = INADDR_ANY;
        /* Note: The following line differs from standard stacks, and we also
                 don't remove the socket from the port list. Might get fixed in
                 the future... */
//         sock->prot.inet.sport = index + auto_port_start;
        sock->prot.inet.daddr = INADDR_ANY;
        sock->prot.inet.dport = 0;
        sock->prot.inet.state = TCP_CLOSE;
        
        rtdm_lock_put_irqrestore(&udp_socket_base_lock, context);
    } else {
        if ((addrlen < (int)sizeof(struct sockaddr_in)) ||
            (usin->sin_family != AF_INET))          /*Use PF_INET instead of AF_INET??  */
            return -EINVAL;
        
        rtdm_lock_get_irqsave(&udp_socket_base_lock, context);
        
        if (sock->prot.inet.state != TCP_CLOSE) {
            rtdm_lock_put_irqrestore(&udp_socket_base_lock, context);
            return -EINVAL;
        }
        
        sock->prot.inet.state = TCP_ESTABLISHED;
        sock->prot.inet.daddr = usin->sin_addr.s_addr;
        sock->prot.inet.dport = usin->sin_port;
        
        rtdm_lock_put_irqrestore(&udp_socket_base_lock, context);
    }
    
    return 0;
}



int rt_raw_rcv (struct rtskb *skb)
{
    struct rtsocket *sock = skb->sk;
    void            (*callback_func)(struct rtdm_dev_context *, void *);
    void            *callback_arg;
    rtdm_lockctx_t  context;
    
    
    rtskb_queue_tail(&sock->incoming, skb);
    rtdm_sem_up(&sock->pending_sem);
    
    rtdm_lock_get_irqsave(&sock->param_lock, context);
#ifdef CONFIG_RTNET_RTDM_SELECT
    if (sock->wakeup_select != NULL) {
        wq_wakeup(sock->wakeup_select);
    }
#endif /* CONFIG_RTNET_RTDM_SELECT */
    callback_func = sock->callback_func;
    callback_arg  = sock->callback_arg;
    rtdm_lock_put_irqrestore(&sock->param_lock, context);
    
    if (callback_func)
        callback_func(rt_socket_context(sock), callback_arg);
    
    return 0;
}



/***
 *  rt_raw_release
 */
void rt_raw_release(void)
{
    rt_inet_del_protocol(&raw_protocol);
    
    /** Executar alguma função de clean-up...
        Se for usada uma pool, fazer...
    */
    rtskb_pool_release( &raw_socket.skb_pool );
}





#endif

Reply via email to