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