Adaptation for the new protocols and interface structs.

implementation of receive in the protocols.
Also all unwanted packets are discarded.
This commit is contained in:
Manoel R. Abranches 2010-06-21 19:15:45 -03:00
parent c3639ae731
commit 60cdb895da
9 changed files with 505 additions and 226 deletions

View file

@ -23,14 +23,14 @@
#include <grub/command.h>
struct grub_net_route *grub_net_routes = NULL;
struct grub_net_network_level_interface *grub_net_network_level_interfaces = NULL;
struct grub_net_network_layer_interface *grub_net_network_layer_interfaces = NULL;
struct grub_net_card *grub_net_cards = NULL;
struct grub_net_network_level_protocol *grub_net_network_level_protocols = NULL;
struct grub_net_network_layer_protocol *grub_net_network_layer_protocols = NULL;
grub_err_t
grub_net_resolve_address (struct grub_net_network_level_protocol **prot,
grub_net_resolve_address (struct grub_net_network_layer_protocol **prot,
char *name,
grub_net_network_level_address_t *addr)
grub_net_network_layer_address_t *addr)
{
FOR_NET_NETWORK_LEVEL_PROTOCOLS (*prot)
{
@ -50,15 +50,15 @@ grub_net_resolve_address (struct grub_net_network_level_protocol **prot,
}
grub_err_t
grub_net_route_address (grub_net_network_level_address_t addr,
grub_net_network_level_address_t *gateway,
struct grub_net_network_level_interface **interf)
grub_net_route_address (grub_net_network_layer_address_t addr,
grub_net_network_layer_address_t *gateway,
struct grub_net_network_layer_interface **interf)
{
struct grub_net_route *route;
int depth = 0;
int routecnt = 0;
struct grub_net_network_level_protocol *prot = NULL;
grub_net_network_level_address_t curtarget = addr;
struct grub_net_network_layer_protocol *prot = NULL;
grub_net_network_layer_address_t curtarget = addr;
*gateway = addr;
@ -96,7 +96,7 @@ static grub_err_t
grub_cmd_deladdr (struct grub_command *cmd __attribute__ ((unused)),
int argc, char **args)
{
struct grub_net_network_level_interface *inter;
struct grub_net_network_layer_interface *inter;
if (argc != 4)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected"));
@ -107,8 +107,8 @@ grub_cmd_deladdr (struct grub_command *cmd __attribute__ ((unused)),
if (inter == NULL)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("address not found"));
inter->protocol->fini (inter);
grub_net_network_level_interface_unregister (inter);
// inter->protocol->fini (inter);
grub_net_network_layer_interface_unregister (inter);
grub_free (inter->name);
grub_free (inter);
@ -120,10 +120,10 @@ grub_cmd_addaddr (struct grub_command *cmd __attribute__ ((unused)),
int argc, char **args)
{
struct grub_net_card *card;
struct grub_net_network_level_protocol *prot;
struct grub_net_network_layer_protocol *prot;
grub_err_t err;
grub_net_network_level_address_t addr;
struct grub_net_network_level_interface *inter;
grub_net_network_layer_address_t addr;
struct grub_net_network_layer_interface *inter;
if (argc != 4)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("four arguments expected"));
@ -154,14 +154,14 @@ grub_cmd_addaddr (struct grub_command *cmd __attribute__ ((unused)),
grub_memcpy (&(inter->address), &addr, sizeof (inter->address));
inter->card = card;
err = prot->init (inter);
// err = prot->init (inter);
if (err)
{
grub_free (inter->name);
grub_free (inter);
return err;
}
grub_net_network_level_interface_register (inter);
grub_net_network_layer_interface_register (inter);
return GRUB_ERR_NONE;
}
@ -192,7 +192,7 @@ static grub_err_t
grub_cmd_addroute (struct grub_command *cmd __attribute__ ((unused)),
int argc, char **args)
{
struct grub_net_network_level_protocol *prot;
struct grub_net_network_layer_protocol *prot;
struct grub_net_route *route;
if (argc < 3)
@ -247,7 +247,7 @@ grub_cmd_addroute (struct grub_command *cmd __attribute__ ((unused)),
}
else
{
struct grub_net_network_level_interface *inter;
struct grub_net_network_layer_interface *inter;
route->is_gateway = 0;
FOR_NET_NETWORK_LEVEL_INTERFACES (inter)

View file

@ -23,20 +23,11 @@
#include <grub/err.h>
#include <grub/list.h>
#include <grub/net/netbuff.h>
#include <grub/net/type_net.h>
#include <grub/net/protocol.h>
struct grub_net_card;
typedef enum
{
GRUB_NET_TFTP_ID,
GRUB_NET_UDP_ID,
GRUB_NET_IPV4_ID,
GRUB_NET_IPV6_ID,
GRUB_NET_ETHERNET_ID,
GRUB_NET_ARP_ID,
GRUB_NET_DHCP_ID
}protocol_type_t;
struct grub_net_card_driver
{
@ -66,76 +57,36 @@ struct grub_net_card
void *data;
};
struct grub_net_network_level_interface;
//struct grub_net_network_layer_interface;
typedef union grub_net_network_level_address
struct grub_net_network_layer_interface
{
grub_uint32_t ipv4;
} grub_net_network_level_netaddress_t;
typedef union grub_net_network_level_netaddress
{
struct {
grub_uint32_t base;
int masksize;
} ipv4;
} grub_net_network_level_address_t;
typedef enum grub_network_level_protocol_id
{
GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4
} grub_network_level_protocol_id_t;
struct grub_net_network_level_interface;
struct grub_net_network_level_protocol
{
struct grub_net_network_level_protocol *next;
char *name;
grub_network_level_protocol_id_t id;
grub_err_t (*ntoa) (char *name, grub_net_network_level_address_t *addr);
char * (*aton) (union grub_net_network_level_address addr);
grub_err_t (*net_ntoa) (char *name,
grub_net_network_level_netaddress_t *addr);
char * (*net_aton) (grub_net_network_level_netaddress_t addr);
int (* match_net) (grub_net_network_level_netaddress_t net,
grub_net_network_level_address_t addr);
grub_err_t (*init) (struct grub_net_network_level_interface *dev);
grub_err_t (*fini) (struct grub_net_network_level_interface *dev);
grub_err_t (*send) (struct grub_net_network_level_interface *dev, void *buf,
grub_size_t buflen);
grub_size_t (*recv) (struct grub_net_network_level_interface *dev, void *buf,
grub_size_t buflen);
};
struct grub_net_network_level_interface
{
struct grub_net_network_level_interface *next;
struct grub_net_network_layer_interface *next;
char *name;
/* Underlying protocol. */
struct grub_net_network_level_protocol *protocol;
struct grub_net_network_layer_protocol *protocol;
struct grub_net_card *card;
union grub_net_network_level_address address;
union grub_net_network_layer_address address;
void *data;
};
struct grub_net_route
{
struct grub_net_route *next;
grub_net_network_level_netaddress_t target;
grub_net_network_layer_netaddress_t target;
char *name;
struct grub_net_network_level_protocol *prot;
struct grub_net_network_layer_protocol *prot;
int is_gateway;
union
{
struct grub_net_network_level_interface *interface;
grub_net_network_level_address_t gw;
struct grub_net_network_layer_interface *interface;
grub_net_network_layer_address_t gw;
};
};
struct grub_net_session;
struct grub_net_session_level_protocol
struct grub_net_session_layer_protocol
{
void (*close) (struct grub_net_session *session);
grub_ssize_t (*recv) (struct grub_net_session *session, void *buf,
@ -146,7 +97,7 @@ struct grub_net_session_level_protocol
struct grub_net_session
{
struct grub_net_session_level_protocol *protocol;
struct grub_net_session_layer_protocol *protocol;
void *data;
};
@ -170,23 +121,23 @@ grub_net_session_recv (struct grub_net_session *session, void *buf,
return session->protocol->recv (session, buf, size);
}
extern struct grub_net_network_level_interface *grub_net_network_level_interfaces;
struct grub_net_network_layer_interface *grub_net_network_layer_interfaces;
static inline void
grub_net_network_level_interface_register (struct grub_net_network_level_interface *inter)
grub_net_network_layer_interface_register (struct grub_net_network_layer_interface *inter)
{
grub_list_push (GRUB_AS_LIST_P (&grub_net_network_level_interfaces),
grub_list_push (GRUB_AS_LIST_P (&grub_net_network_layer_interfaces),
GRUB_AS_LIST (inter));
}
static inline void
grub_net_network_level_interface_unregister (struct grub_net_network_level_interface *inter)
grub_net_network_layer_interface_unregister (struct grub_net_network_layer_interface *inter)
{
grub_list_remove (GRUB_AS_LIST_P (&grub_net_network_level_interfaces),
grub_list_remove (GRUB_AS_LIST_P (&grub_net_network_layer_interfaces),
GRUB_AS_LIST (inter));
}
#define FOR_NET_NETWORK_LEVEL_INTERFACES(var) for (var = grub_net_network_level_interfaces; var; var = var->next)
#define FOR_NET_NETWORK_LEVEL_INTERFACES(var) for (var = grub_net_network_layer_interfaces; var; var = var->next)
extern struct grub_net_route *grub_net_routes;
@ -224,28 +175,13 @@ grub_net_card_unregister (struct grub_net_card *card)
#define FOR_NET_CARDS(var) for (var = grub_net_cards; var; var = var->next)
extern struct grub_net_network_level_protocol *grub_net_network_level_protocols;
static inline void
grub_net_network_level_protocol_register (struct grub_net_network_level_protocol *prot)
{
grub_list_push (GRUB_AS_LIST_P (&grub_net_network_level_protocols),
GRUB_AS_LIST (prot));
}
static inline void
grub_net_network_level_protocol_unregister (struct grub_net_network_level_protocol *prot)
{
grub_list_remove (GRUB_AS_LIST_P (&grub_net_network_level_protocols),
GRUB_AS_LIST (prot));
}
#define FOR_NET_NETWORK_LEVEL_PROTOCOLS(var) for ((var) = grub_net_network_level_protocols; (var); (var) = (var)->next)
#define FOR_NET_NETWORK_LEVEL_PROTOCOLS(var) for ((var) = grub_net_network_layer_protocols; (var); (var) = (var)->next)
static inline grub_err_t
grub_net_resolve_address_in_protocol (struct grub_net_network_level_protocol *prot,
grub_net_resolve_address_in_protocol (struct grub_net_network_layer_protocol *prot,
char *name,
grub_net_network_level_address_t *addr)
grub_net_network_layer_address_t *addr)
{
return prot->ntoa (name, addr);
}
@ -254,14 +190,14 @@ struct grub_net_session *
grub_net_open_tcp (char *address, grub_uint16_t port);
grub_err_t
grub_net_resolve_address (struct grub_net_network_level_protocol **prot,
grub_net_resolve_address (struct grub_net_network_layer_protocol **prot,
char *name,
grub_net_network_level_address_t *addr);
grub_net_network_layer_address_t *addr);
grub_err_t
grub_net_route_address (grub_net_network_level_address_t addr,
grub_net_network_level_address_t *gateway,
struct grub_net_network_level_interface **interf);
grub_net_route_address (grub_net_network_layer_address_t addr,
grub_net_network_layer_address_t *gateway,
struct grub_net_network_layer_interface **interf);
#endif /* ! GRUB_NET_HEADER */

View file

@ -5,51 +5,85 @@
#include <grub/net/arp.h>
#include <grub/net/ieee1275/interface.h>
#include <grub/net/netbuff.h>
#include <grub/net/protocol.h>
#include <grub/net/interface.h>
#include <grub/net.h>
static grub_err_t
send_ethernet_packet (struct grub_net_interface *inf,struct grub_net_protstack *protstack __attribute__ ((unused))
,struct grub_net_buff *nb)
send_ethernet_packet (struct grub_net_network_layer_interface *inf __attribute__ ((unused)),
struct grub_net_network_link_interface *net_link_inf __attribute__ ((unused)) ,struct grub_net_buff *nb)
{
struct etherhdr *eth;
grub_err_t err;
if((err = grub_netbuff_push (nb,sizeof(*eth)) ) != GRUB_ERR_NONE)
return err;
struct etherhdr *eth;
grub_netbuff_push (nb,sizeof(*eth));
eth = (struct etherhdr *) nb->data;
grub_memcpy (eth->src,inf->card->lla->addr,6 * sizeof (grub_uint8_t ));
grub_memcpy (eth->dst,inf->lla->addr,6 * sizeof (grub_uint8_t ));
eth->dst[0] =0x00;
eth->dst[1] =0x11;
eth->dst[2] =0x25;
eth->dst[3] =0xca;
eth->dst[4] =0x1f;
eth->dst[5] =0x01;
eth->src[0] =0x0a;
eth->src[1] =0x11;
eth->src[2] =0xbd;
eth->src[3] =0xe3;
eth->src[4] =0xe3;
eth->src[5] =0x04;
eth->type = 0x0800;
return inf->card->driver->send(inf->card,nb);
return send_card_buffer(nb);
// return inf->card->driver->send(inf->card,nb);
}
static struct grub_net_protocol grub_ethernet_protocol =
static grub_err_t
recv_ethernet_packet (struct grub_net_network_layer_interface *inf __attribute__ ((unused)),
struct grub_net_network_link_interface *net_link_inf __attribute__ ((unused)) ,struct grub_net_buff *nb)
{
.name = "udp",
.send = send_ethernet_packet
struct etherhdr *eth;
while (1)
{
get_card_packet (nb);
eth = (struct etherhdr *) nb->data;
/*change for grub_memcmp*/
if( eth->src[0] == 0x00 && eth->src[1] == 0x11 && eth->src[2] == 0x25 &&
eth->src[3] == 0xca && eth->src[4] == 0x1f && eth->src[5] == 0x01 && eth->type == 0x800)
{
//grub_printf("ethernet eth->dst %x:%x:%x:%x:%x:%x\n",eth->dst[0],
// eth->dst[1],eth->dst[2],eth->dst[3],eth->dst[4],eth->dst[5]);
// grub_printf("ethernet eth->src %x:%x:%x:%x:%x:%x\n",eth->src[0],eth->src[1],
// eth->src[2],eth->src[3],eth->src[4],eth->src[5]);
//grub_printf("ethernet eth->type 0x%x\n",eth->type);
//grub_printf("out from ethernet\n");
grub_netbuff_pull(nb,sizeof(*eth));
return 0;
}
}
/* - get ethernet header
- verify if the next layer is the desired one.
- if not. get another packet.
- remove ethernet header from buffer*/
return 0;
}
static struct grub_net_link_layer_protocol grub_ethernet_protocol =
{
.name = "ethernet",
.id = GRUB_NET_ETHERNET_ID,
.send = send_ethernet_packet,
.recv = recv_ethernet_packet
};
void ethernet_ini(void)
{
grub_protocol_register (&grub_ethernet_protocol);
grub_net_link_layer_protocol_register (&grub_ethernet_protocol);
}
void ethernet_fini(void)
{
grub_protocol_unregister (&grub_ethernet_protocol);
grub_net_link_layer_protocol_unregister (&grub_ethernet_protocol);
}
/*
int read_ethernet_packet(buffer,bufflen, int type)
{
struct etherhdr eth;
eth.type = 0;
get_card_buffer (&eth,sizeof (eth));
}*/

View file

@ -0,0 +1,38 @@
/*#include <grub/net/interface.h>
#define INTERFACE_REGISTER_FUNCTIONS(layerprevious,layernext) \
struct grub_net_##layername_layer_protocol *grub_net_##layername_layer_protocols;\
\
void grub_net_##layerprevious_##layernext_interface_register (struct grub_net_##layername_layer_protocol *prot)\
{\
grub_list_push (GRUB_AS_LIST_P (&grub_net_##layername_layer_protocols),\
GRUB_AS_LIST (prot));\
}\
\
void grub_net_##layerprevious_##layernext_interface_unregister (struct grub_net_##layername_layer_protocol *prot);\
{\
grub_list_remove (GRUB_AS_LIST_P (&grub_net_##layername_layer_protocols),\
GRUB_AS_LIST (prot));\
}\
INTERFACE_REGISTER_FUNCTIONS("application","transport");
INTERFACE_REGISTER_FUNCTIONS("transport","network");
INTERFACE_REGISTER_FUNCTIONS("network","link");
INTERFACE_REGISTER_FUNCTIONS("link");*/
#include <grub/mm.h>
#include <grub/net/interface.h>
struct grub_net_protocol_stack *grub_net_protocol_stacks;
struct grub_net_protocol_stack
*grub_net_protocol_stack_get (char *name)
{
struct grub_net_protocol_stack *p;
for (p = grub_net_protocol_stacks; p; p = p->next)
{
if (!grub_strcmp(p->name,name))
return p;
}
return NULL;
}

View file

@ -1,11 +1,11 @@
#include <grub/net/ip.h>
#include <grub/net/type_net.h>
#include <grub/net/ieee1275/interface.h>
#include <grub/misc.h>
#include <grub/net/ethernet.h>
#include <grub/net/netbuff.h>
#include <grub/net/protocol.h>
#include <grub/net/interface.h>
#include <grub/net/type_net.h>
#include <grub/net.h>
#include <grub/net/netbuff.h>
#include <grub/mm.h>
struct grub_net_protocol *grub_ipv4_prot;
@ -29,14 +29,14 @@ ipchksum(void *ipv, int len)
static grub_err_t
send_ip_packet (struct grub_net_interface *inf, struct grub_net_protstack *protstack, struct grub_net_buff *nb )
send_ip_packet (struct grub_net_network_layer_interface *inf,
struct grub_net_transport_network_interface *trans_net_inf, struct grub_net_buff *nb )
{
struct iphdr *iph;
grub_err_t err;
static int id = 0x2400;
if((err = grub_netbuff_push(nb,sizeof(*iph)) ) != GRUB_ERR_NONE)
return err;
grub_netbuff_push(nb,sizeof(*iph));
iph = (struct iphdr *) nb->data;
/*FIXME dont work in litte endian machines*/
@ -44,38 +44,64 @@ send_ip_packet (struct grub_net_interface *inf, struct grub_net_protstack *prots
//grub_uint8_t hdrlen = sizeof (struct iphdr)/4;
iph->verhdrlen = (4<<4 | 5);
iph->service = 0;
iph->len = sizeof(*iph);
iph->ident = 0x2b5f;
iph->len = nb->tail - nb-> data;//sizeof(*iph);
iph->ident = ++id;
iph->frags = 0;
iph->ttl = 0xff;
iph->protocol = 0x11;
//grub_memcpy(&(iph->src) ,inf->card->ila->addr,inf->card->ila->len);
iph->src = *((grub_uint32_t *)inf->card->ila->addr);
//grub_memcpy(&(iph->dest) ,inf->ila->addr,inf->ila->len);
iph->dest = *((grub_uint32_t *)inf->ila->addr);
iph->src = (grub_uint32_t) bootp_pckt -> yiaddr; //inf->address.ipv4; // *((grub_uint32_t *)inf->card->ila->addr);
iph->dest = (grub_uint32_t) bootp_pckt -> siaddr;//inf->address.ipv4;// *((grub_uint32_t *)inf->ila->addr);
iph->chksum = 0 ;
iph->chksum = ipchksum((void *)nb->head, sizeof(*iph));
iph->chksum = ipchksum((void *)nb->data, sizeof(*iph));
return protstack->next->prot->send(inf,protstack->next,nb);
return trans_net_inf->inner_layer->link_prot->send(inf,trans_net_inf->inner_layer,nb);
//return protstack->next->prot->send(inf,protstack->next,nb);
}
static struct grub_net_protocol grub_ipv4_protocol =
static grub_err_t
recv_ip_packet (struct grub_net_network_layer_interface *inf,
struct grub_net_transport_network_interface *trans_net_inf, struct grub_net_buff *nb )
{
struct iphdr *iph;
while (1)
{
trans_net_inf->inner_layer->link_prot->recv(inf,trans_net_inf->inner_layer,nb);
iph = (struct iphdr *) nb->data;
if (iph->dest == 0x0908eaaa && iph->src == 0x0908ea92 && iph->protocol == 0x11)
{
grub_netbuff_pull(nb,sizeof(*iph));
return 0;
}
}
/* grub_printf("ip.src 0x%x\n",iph->src);
grub_printf("ip.dst 0x%x\n",iph->dest);
grub_printf("ip.len 0x%x\n",iph->len);
grub_printf("ip.protocol 0x%x\n",iph->protocol);
*/
/* - get ip header
- verify if is the next layer is correct
-*/
return 0;
}
static struct grub_net_network_layer_protocol grub_ipv4_protocol =
{
.name = "ipv4",
.id = GRUB_NET_IPV4_ID,
.send = send_ip_packet,
.recv = NULL
.recv = recv_ip_packet
};
void ipv4_ini(void)
{
grub_protocol_register (&grub_ipv4_protocol);
grub_net_network_layer_protocol_register (&grub_ipv4_protocol);
}
void ipv4_fini(void)
{
grub_protocol_unregister (&grub_ipv4_protocol);
grub_net_network_layer_protocol_unregister (&grub_ipv4_protocol);
}
/*

View file

@ -26,7 +26,7 @@ grub_err_t grub_netbuff_put (struct grub_net_buff *net_buff ,grub_size_t len)
{
net_buff->tail += len;
if (net_buff->tail > net_buff->end)
return grub_error (GRUB_ERR_OUT_OF_RANGE, "out of the packet range.");
return grub_error (GRUB_ERR_OUT_OF_RANGE, "put out of the packet range.");
return GRUB_ERR_NONE;
}
@ -34,15 +34,20 @@ grub_err_t grub_netbuff_unput (struct grub_net_buff *net_buff ,grub_size_t len)
{
net_buff->tail -= len;
if (net_buff->tail < net_buff->head)
return grub_error (GRUB_ERR_OUT_OF_RANGE, "out of the packet range.");
return grub_error (GRUB_ERR_OUT_OF_RANGE, "unput out of the packet range.");
return GRUB_ERR_NONE;
}
grub_err_t grub_netbuff_push (struct grub_net_buff *net_buff ,grub_size_t len)
{
net_buff->data -= len;
/* grub_printf("push len =%d\n",len);
grub_printf("pack->head =%x\n",(unsigned int)net_buff->head);
grub_printf("pack->data =%x\n",(unsigned int)net_buff->data);
grub_printf("pack->tail =%x\n",(unsigned int)net_buff->tail);
grub_printf("pack->end =%x\n",(unsigned int)net_buff->end);*/
if (net_buff->data < net_buff->head)
return grub_error (GRUB_ERR_OUT_OF_RANGE, "out of the packet range.");
return grub_error (GRUB_ERR_OUT_OF_RANGE, "push out of the packet range.");
return GRUB_ERR_NONE;
}
@ -50,7 +55,7 @@ grub_err_t grub_netbuff_pull (struct grub_net_buff *net_buff ,grub_size_t len)
{
net_buff->data += len;
if (net_buff->data > net_buff->end)
return grub_error (GRUB_ERR_OUT_OF_RANGE, "out of the packet range.");
return grub_error (GRUB_ERR_OUT_OF_RANGE, "pull out of the packet range.");
return GRUB_ERR_NONE;
}
@ -59,14 +64,36 @@ grub_err_t grub_netbuff_reserve (struct grub_net_buff *net_buff ,grub_size_t len
net_buff->data += len;
net_buff->tail += len;
if ((net_buff->tail > net_buff->end) || (net_buff->data > net_buff->end))
return grub_error (GRUB_ERR_OUT_OF_RANGE, "out of the packet range.");
return grub_error (GRUB_ERR_OUT_OF_RANGE, "reserve out of the packet range.");
return GRUB_ERR_NONE;
}
struct grub_net_buff * grub_netbuff_alloc ( grub_size_t len )
struct grub_net_buff *grub_netbuff_alloc ( grub_size_t len )
{
struct grub_net_buff *nb;
void *data;
if (len < NETBUFFMINLEN)
len = NETBUFFMINLEN;
len = ALIGN_UP (len,NETBUFF_ALIGN);
return (struct grub_net_buff *) grub_memalign (len,NETBUFF_ALIGN);
data = grub_memalign (len + sizeof (*nb),NETBUFF_ALIGN);
nb = (struct grub_net_buff *) ((int)data + len);
nb->head = nb->data = nb->tail = data;
nb->end = (char *) nb;
return nb;
}
grub_err_t grub_netbuff_free (struct grub_net_buff *net_buff)
{
grub_free (net_buff);
return 0;
}
grub_err_t grub_netbuff_clear (struct grub_net_buff *net_buff)
{
net_buff->data = net_buff->tail = net_buff->head;
return 0;
}

View file

@ -1,21 +1,37 @@
#include <grub/net/protocol.h>
#include <grub/misc.h>
#include <grub/mm.h>
static grub_net_protocol_t grub_net_protocols;
void grub_protocol_register (grub_net_protocol_t prot)
{
prot->next = grub_net_protocols;
grub_net_protocols = prot;
#define PROTOCOL_REGISTER_FUNCTIONS(layername) \
struct grub_net_##layername##_layer_protocol *grub_net_##layername##_layer_protocols;\
\
void grub_net_##layername##_layer_protocol_register (struct grub_net_##layername##_layer_protocol *prot)\
{\
grub_list_push (GRUB_AS_LIST_P (&grub_net_##layername##_layer_protocols),\
GRUB_AS_LIST (prot));\
}\
\
void grub_net_##layername##_layer_protocol_unregister (struct grub_net_##layername##_layer_protocol *prot)\
{\
grub_list_remove (GRUB_AS_LIST_P (&grub_net_##layername##_layer_protocols),\
GRUB_AS_LIST (prot));\
}\
\
struct grub_net_##layername##_layer_protocol \
*grub_net_##layername##_layer_protocol_get (grub_net_protocol_id_t id)\
{\
struct grub_net_##layername##_layer_protocol *p;\
\
for (p = grub_net_##layername##_layer_protocols; p; p = p->next)\
{\
if (p->id == id)\
return p;\
}\
\
return NULL; \
}
void grub_protocol_unregister (grub_net_protocol_t prot)
{
grub_net_protocol_t *p, q;
for (p = &grub_net_protocols, q = *p; q; p = &(q->next), q = q->next)
if (q == prot)
{
*p = q->next;
break;
}
}
PROTOCOL_REGISTER_FUNCTIONS(application);
PROTOCOL_REGISTER_FUNCTIONS(transport);
PROTOCOL_REGISTER_FUNCTIONS(network);
PROTOCOL_REGISTER_FUNCTIONS(link);

View file

@ -4,42 +4,94 @@
#include <grub/net/ip.h>
#include <grub/net/ethernet.h>
#include <grub/net/netbuff.h>
#include <grub/net/protocol.h>
#include <grub/net/ieee1275/interface.h>
#include <grub/ieee1275/ieee1275.h>
#include <grub/time.h>
#include <grub/net/interface.h>
#include <grub/net/type_net.h>
#include <grub/net.h>
#include <grub/mm.h>
int block,rrq_count=0;
struct {
int block_size;
int size;
} tftp_file;
char *get_tok_val(char **tok, char **val, char **str_opt,char *end);
void process_option(char *tok, char *val);
char *get_tok_val(char **tok, char **val,char **str_opt,char *end)
{
char *p = *str_opt;
*tok = p;
p += grub_strlen(p) + 1;
if(p > end)
return NULL;
*val = p;
p += grub_strlen(p) + 1;
*str_opt = p;
return *tok;
}
void process_option(char *tok, char *val)
{
if (!grub_strcmp(tok,"blksize"))
{
tftp_file.block_size = grub_strtoul (val,NULL,0);
return;
}
if (!grub_strcmp(tok,"tsize"))
{
tftp_file.size = grub_strtoul (val,NULL,0);
return;
}
}
//void tftp_open (char *options);
/*send read request*/
static grub_err_t
send_tftp_rr (struct grub_net_interface *inf, struct grub_net_protstack *protstack,struct grub_net_buff *nb)
tftp_open (struct grub_net_network_layer_interface *inf __attribute((unused)),
struct grub_net_protocol_stack *protstack,struct grub_net_buff *nb, char *filename)
{
/*Start TFTP header*/
struct tftphdr *tftph;
char *rrq;
int rrqlen;
int hdrlen;
grub_err_t err;
struct udp_interf *udp_interf;
struct grub_net_application_transport_interface *app_interface = (struct grub_net_application_transport_interface *) protstack->interface;
if((err = grub_netbuff_push (nb,sizeof(*tftph))) != GRUB_ERR_NONE)
return err;
app_interface = (struct grub_net_application_transport_interface *) protstack->interface;
grub_netbuff_push (nb,sizeof (*tftph));
udp_interf = (struct udp_interf *) app_interface->data;
udp_interf->src = TFTP_CLIENT_PORT + rrq_count++;
grub_printf("open tfpt udp_port = %d\n",udp_interf->src);
udp_interf->dst = TFTP_SERVER_PORT;
tftph = (struct tftphdr *) nb->data;
rrq = (char *) tftph->u.rrq;
rrqlen = 0;
tftph->opcode = TFTP_RRQ;
grub_strcpy (rrq,inf->path);
rrqlen += grub_strlen (inf->path) + 1;
rrq += grub_strlen (inf->path) + 1;
grub_strcpy (rrq,filename);
rrqlen += grub_strlen (filename) + 1;
rrq += grub_strlen (filename) + 1;
/*passar opcoes como parametro ou usar default?*/
grub_strcpy (rrq,"octet");
rrqlen += grub_strlen ("octet") + 1;
rrq += grub_strlen ("octet") + 1;
//grub_strcpy (rrq,"netascii");
//rrqlen += grub_strlen ("netascii") + 1;
//rrq += grub_strlen ("netascii") + 1;
grub_strcpy (rrq,"blksize");
rrqlen += grub_strlen("blksize") + 1;
rrq += grub_strlen ("blksize") + 1;
@ -59,39 +111,146 @@ send_tftp_rr (struct grub_net_interface *inf, struct grub_net_protstack *protsta
grub_netbuff_unput (nb,nb->tail - (nb->data+hdrlen));
return protstack->next->prot->send(inf,protstack->next,nb);
app_interface->trans_prot->send (inf,protstack->interface,nb);
/*Receive OACK*/
return app_interface->app_prot->recv(inf,protstack,nb);
}
/*
int send_tftp_ack(int block, int port){
tftp_t pckt;
int pcktlen;
pckt.opcode = TFTP_ACK;
pckt.u.ack.block = block;
pcktlen = sizeof (pckt.opcode) + sizeof (pckt.u.ack.block);
port = 4;
return 0;// send_udp_packet (&pckt,pcktlen,TFTP_CLIENT_PORT,port);
}
*/
static struct grub_net_protocol grub_tftp_protocol =
static grub_err_t
tftp_receive (struct grub_net_network_layer_interface *inf __attribute((unused)),
struct grub_net_protocol_stack *protstack,struct grub_net_buff *nb)
{
.name = "tftp",
.open = send_tftp_rr
struct tftphdr *tftph;
char *token,*value,*temp;
struct grub_net_application_transport_interface *app_interface =
(struct grub_net_application_transport_interface *) protstack->interface;
app_interface->trans_prot->recv (inf,protstack->interface,nb);
tftph = (struct tftphdr *) nb->data;
switch (tftph->opcode)
{
case TFTP_OACK:
/*process oack packet*/
temp = (char *) tftph->u.oack.data;
while(get_tok_val(&token,&value,&temp,nb->tail))
{
grub_printf("tok = <%s> val = <%s>\n",token,value);
process_option(token,value);
}
//buff_clean
nb->data = nb->tail;
grub_printf("OACK---------------------------------------------------------\n");
grub_printf("block_size=%d\n",tftp_file.block_size);
grub_printf("file_size=%d\n",tftp_file.size);
grub_printf("OACK---------------------------------------------------------\n");
block = 0;
break;
case TFTP_DATA:
grub_netbuff_pull (nb,sizeof (tftph->opcode) + sizeof (tftph->u.data.block));
if (tftph->u.data.block == block + 1)
block = tftph->u.data.block;
else
grub_netbuff_clear(nb);
break;
case TFTP_ERROR:
nb->data = nb->tail;
break;
}
return 0;// tftp_send_ack (inf,protstack,nb,tftph->u.data.block);
/*remove tftp header and return.
nb should now contain only the payload*/
}
static grub_err_t
tftp_send_ack (struct grub_net_network_layer_interface *inf __attribute((unused)),
struct grub_net_protocol_stack *protstack,struct grub_net_buff *nb)
{
struct tftphdr *tftph;
struct grub_net_application_transport_interface *app_interface = (struct grub_net_application_transport_interface *) protstack->interface;
nb->data = nb->tail = nb->end;
grub_netbuff_push (nb,sizeof (tftph->opcode) + sizeof (tftph->u.ack.block));
tftph = (struct tftphdr *) nb->data;
tftph->opcode = TFTP_ACK;
tftph->u.ack.block = block;
return app_interface->trans_prot->send (inf,protstack->interface,nb);
}
static int tftp_file_size (struct grub_net_network_layer_interface* inf ,
struct grub_net_protocol_stack *protocol_stack , struct grub_net_buff *nb ,char *filename )
{
tftp_open (inf, protocol_stack,nb, filename);
return tftp_file.size;
}
static grub_err_t
tftp_close (struct grub_net_network_layer_interface *inf __attribute((unused)),
struct grub_net_protocol_stack *protstack __attribute((unused)),struct grub_net_buff *nb __attribute((unused)))
{
return 0;
}
static struct grub_net_application_transport_interface grub_net_tftp_app_trans_interf;
static struct grub_net_transport_network_interface grub_net_tftp_trans_net_interf;
static struct grub_net_network_link_interface grub_net_tftp_net_link_interf;
static struct grub_net_protocol_stack grub_net_tftp_stack =
{
.name = "tftp",
.id = GRUB_NET_TFTP_ID,
.interface = (void *) &grub_net_tftp_app_trans_interf
};
static struct grub_net_application_layer_protocol grub_tftp_protocol =
{
.name = "tftp",
.id = GRUB_NET_TFTP_ID,
.open = tftp_open,
.recv = tftp_receive,
.send_ack = tftp_send_ack,
.get_file_size = tftp_file_size,
.close = tftp_close
};
static struct udp_interf tftp_udp_interf;
void tftp_ini(void)
{
grub_protocol_register (&grub_tftp_protocol);
ethernet_ini ();
ipv4_ini ();
udp_ini ();
grub_net_application_layer_protocol_register (&grub_tftp_protocol);
grub_net_stack_register (&grub_net_tftp_stack);
grub_net_tftp_app_trans_interf.app_prot = &grub_tftp_protocol;
grub_net_tftp_app_trans_interf.trans_prot = grub_net_transport_layer_protocol_get (GRUB_NET_UDP_ID);
grub_net_tftp_app_trans_interf.inner_layer = &grub_net_tftp_trans_net_interf;
grub_net_tftp_app_trans_interf.data = &tftp_udp_interf;
grub_net_tftp_trans_net_interf.trans_prot = grub_net_tftp_app_trans_interf.trans_prot;
grub_net_tftp_trans_net_interf.net_prot = grub_net_network_layer_protocol_get (GRUB_NET_IPV4_ID);
grub_net_tftp_trans_net_interf.inner_layer = &grub_net_tftp_net_link_interf;
grub_net_tftp_net_link_interf.net_prot = grub_net_tftp_trans_net_interf.net_prot;
grub_net_tftp_net_link_interf.link_prot = grub_net_link_layer_protocol_get (GRUB_NET_ETHERNET_ID) ;
}
void tftp_fini(void)
{
grub_protocol_unregister (&grub_tftp_protocol);
grub_net_application_layer_protocol_unregister (&grub_tftp_protocol);
}
/*
int read_tftp_pckt (grub_uint16_t port, void *buffer, int &buff_len){

View file

@ -4,41 +4,84 @@
#include <grub/net/netbuff.h>
#include <grub/net/protocol.h>
#include <grub/net/interface.h>
/*Assumes that there is allocated memory to the header before the buffer address. */
static grub_err_t
send_udp_packet (struct grub_net_interface *inf, struct grub_net_protstack *protstack, struct grub_net_buff *nb)
send_udp_packet (struct grub_net_network_layer_interface *inf,
struct grub_net_application_transport_interface *app_trans_inf, struct grub_net_buff *nb)
{
struct udphdr *udph;
grub_err_t err;
struct udp_interf *udp_interf;
if((err = grub_netbuff_push (nb,sizeof(*udph)) ) != GRUB_ERR_NONE)
return err;
grub_netbuff_push (nb,sizeof(*udph));
udph = (struct udphdr *) nb->data;
udph->src = *((grub_uint16_t *) inf->card->tla->addr);
udph->dst = *((grub_uint16_t *) inf->tla->addr);
udp_interf = (struct udp_interf *) app_trans_inf->data;
udph->src = udp_interf->src;
udph->dst = udp_interf->dst;
/*no chksum*/
udph->chksum = 0;
udph->len = sizeof (sizeof (*udph)) + nb->end - nb->head;
udph->len = nb->tail - nb->data;
return protstack->next->prot->send(inf,protstack->next,nb);
return app_trans_inf->inner_layer->net_prot->send(inf,app_trans_inf->inner_layer,nb);
}
static struct grub_net_protocol grub_udp_protocol =
static grub_err_t
receive_udp_packet (struct grub_net_network_layer_interface *inf,
struct grub_net_application_transport_interface *app_trans_inf, struct grub_net_buff *nb)
{
struct udphdr *udph;
struct udp_interf *udp_interf;
udp_interf = (struct udp_interf *) app_trans_inf->data;
while(1)
{
app_trans_inf->inner_layer->net_prot->recv(inf,app_trans_inf->inner_layer,nb);
udph = (struct udphdr *) nb->data;
// grub_printf("udph->dst %d\n",udph->dst);
// grub_printf("udp_interf->src %d\n",udp_interf->src);
if (udph->dst == udp_interf->src)
{
grub_netbuff_pull (nb,sizeof(*udph));
// udp_interf->src = udph->dst;
udp_interf->dst = udph->src;
// grub_printf("udph->dst %d\n",udph->dst);
// grub_printf("udph->src %d\n",udph->src);
// grub_printf("udph->len %d\n",udph->len);
// grub_printf("udph->chksum %x\n",udph->chksum);
/* - get udp header..
- verify if is in the desired port
- if not. get another packet
- remove udp header*/
return 0;
}
}
}
static struct grub_net_transport_layer_protocol grub_udp_protocol =
{
.name = "udp",
.send = send_udp_packet
.id = GRUB_NET_UDP_ID,
.send = send_udp_packet,
.recv = receive_udp_packet
};
void udp_ini(void)
{
grub_protocol_register (&grub_udp_protocol);
grub_net_transport_layer_protocol_register (&grub_udp_protocol);
}
void udp_fini(void)
{
grub_protocol_unregister (&grub_udp_protocol);
grub_net_transport_layer_protocol_unregister (&grub_udp_protocol);
}
/*