TCP fragmentation

This commit is contained in:
Vladimir 'phcoder' Serbinenko 2011-07-10 11:26:34 +02:00
parent bfca152e5a
commit f4e6e2909b
2 changed files with 45 additions and 4 deletions

View file

@ -41,7 +41,9 @@ enum
TCP_FIN = 0x1, TCP_FIN = 0x1,
TCP_SYN = 0x2, TCP_SYN = 0x2,
TCP_RST = 0x4, TCP_RST = 0x4,
TCP_ACK = 0x10 TCP_PUSH = 0x8,
TCP_ACK = 0x10,
TCP_URG = 0x20,
}; };
struct grub_net_tcp_socket struct grub_net_tcp_socket
@ -460,10 +462,48 @@ grub_net_tcp_open (char *server,
grub_err_t grub_err_t
grub_net_send_tcp_packet (const grub_net_tcp_socket_t socket, grub_net_send_tcp_packet (const grub_net_tcp_socket_t socket,
struct grub_net_buff *nb) struct grub_net_buff *nb, int push)
{ {
struct tcphdr *tcph; struct tcphdr *tcph;
grub_err_t err; grub_err_t err;
grub_ssize_t fraglen;
fraglen = (socket->inf->card->mtu - GRUB_NET_OUR_IPV4_HEADER_SIZE
- sizeof (*tcph));
while (nb->tail - nb->data > fraglen)
{
struct grub_net_buff *nb2;
nb2 = grub_netbuff_alloc (fraglen + sizeof (*tcph)
+ GRUB_NET_OUR_IPV4_HEADER_SIZE
+ GRUB_NET_MAX_LINK_HEADER_SIZE);
if (!nb2)
return grub_errno;
err = grub_netbuff_reserve (nb2, GRUB_NET_MAX_LINK_HEADER_SIZE
+ GRUB_NET_OUR_IPV4_HEADER_SIZE);
if (err)
return err;
err = grub_netbuff_put (nb2, sizeof (*tcph));
if (err)
return err;
tcph = (struct tcphdr *) nb2->data;
tcph->ack = grub_cpu_to_be32 (0);
tcph->flags = grub_cpu_to_be16 ((5 << 12));
tcph->window = grub_cpu_to_be16 (socket->my_window);
tcph->urgent = 0;
err = grub_netbuff_put (nb2, fraglen);
if (err)
return err;
grub_memcpy (tcph + 1, nb->data, fraglen);
err = grub_netbuff_pull (nb, fraglen);
if (err)
return err;
err = tcp_send (nb2, socket);
if (err)
return err;
}
err = grub_netbuff_push (nb, sizeof (*tcph)); err = grub_netbuff_push (nb, sizeof (*tcph));
if (err) if (err)
@ -471,7 +511,7 @@ grub_net_send_tcp_packet (const grub_net_tcp_socket_t socket,
tcph = (struct tcphdr *) nb->data; tcph = (struct tcphdr *) nb->data;
tcph->ack = grub_cpu_to_be32 (0); tcph->ack = grub_cpu_to_be32 (0);
tcph->flags = grub_cpu_to_be16 ((5 << 12)); tcph->flags = grub_cpu_to_be16 ((5 << 12) | (push ? TCP_PUSH : 0));
tcph->window = grub_cpu_to_be16 (socket->my_window); tcph->window = grub_cpu_to_be16 (socket->my_window);
tcph->urgent = 0; tcph->urgent = 0;
return tcp_send (nb, socket); return tcp_send (nb, socket);

View file

@ -36,7 +36,8 @@ grub_net_tcp_open (char *server,
grub_err_t grub_err_t
grub_net_send_tcp_packet (const grub_net_tcp_socket_t socket, grub_net_send_tcp_packet (const grub_net_tcp_socket_t socket,
struct grub_net_buff *nb); struct grub_net_buff *nb,
int push);
void void
grub_net_tcp_close (grub_net_tcp_socket_t sock); grub_net_tcp_close (grub_net_tcp_socket_t sock);