implementation of receive in the protocols.
Also all unwanted packets are discarded.
#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)
{
}
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;
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"));
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);
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"));
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;
}
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)
}
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)
#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
{
void *data;
};
-struct grub_net_network_level_interface;
-
-typedef union grub_net_network_level_address
-{
- 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;
+//struct grub_net_network_layer_interface;
-typedef enum grub_network_level_protocol_id
+struct grub_net_network_layer_interface
{
- 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,
struct grub_net_session
{
- struct grub_net_session_level_protocol *protocol;
+ struct grub_net_session_layer_protocol *protocol;
void *data;
};
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;
#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);
}
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 */
#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 (ð,sizeof (eth));
-
-}*/
+/*#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;
+}
#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;
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*/
//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 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 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 )
+{
- return protstack->next->prot->send(inf,protstack->next,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_protocol grub_ipv4_protocol =
+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);
}
/*
{
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;
}
{
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;
}
{
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;
}
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;
}
#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);
#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;
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){
+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)
+{
+ 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;
+ }
- tftp_t pckt;
- int pcktlen;
- pckt.opcode = TFTP_ACK;
- pckt.u.ack.block = block;
- pcktlen = sizeof (pckt.opcode) + sizeof (pckt.u.ack.block);
+ 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;
- port = 4;
- return 0;// send_udp_packet (&pckt,pcktlen,TFTP_CLIENT_PORT,port);
+ 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 struct grub_net_protocol grub_tftp_protocol =
+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)))
{
- .name = "tftp",
- .open = send_tftp_rr
-
+
+ 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){
#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 app_trans_inf->inner_layer->net_prot->send(inf,app_trans_inf->inner_layer,nb);
+}
+
+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)
+{
- return protstack->next->prot->send(inf,protstack->next,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_protocol grub_udp_protocol =
+
+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);
}
/*