HelenOS sources
This source file includes following definitions.
- tcp_segment_new
- tcp_segment_delete
- tcp_segment_dup
- tcp_segment_make_ctrl
- tcp_segment_make_rst
- tcp_segment_make_data
- tcp_segment_trim
- tcp_segment_text_copy
- tcp_segment_text_size
- tcp_segment_dump
#include <io/log.h>
#include <mem.h>
#include <stdlib.h>
#include "segment.h"
#include "seq_no.h"
#include "tcp_type.h"
static tcp_segment_t *tcp_segment_new(void)
{
return calloc(1, sizeof(tcp_segment_t));
}
void tcp_segment_delete(tcp_segment_t *seg)
{
free(seg->dfptr);
free(seg);
}
tcp_segment_t *tcp_segment_dup(tcp_segment_t *seg)
{
tcp_segment_t *scopy;
size_t tsize;
scopy = tcp_segment_new();
if (scopy == NULL)
return NULL;
scopy->ctrl = seg->ctrl;
scopy->seq = seg->seq;
scopy->ack = seg->ack;
scopy->len = seg->len;
scopy->wnd = seg->wnd;
scopy->up = seg->up;
tsize = tcp_segment_text_size(seg);
scopy->data = calloc(tsize, 1);
if (scopy->data == NULL) {
free(scopy);
return NULL;
}
memcpy(scopy->data, seg->data, tsize);
scopy->dfptr = scopy->data;
return scopy;
}
tcp_segment_t *tcp_segment_make_ctrl(tcp_control_t ctrl)
{
tcp_segment_t *seg;
seg = tcp_segment_new();
if (seg == NULL)
return NULL;
seg->ctrl = ctrl;
seg->len = seq_no_control_len(ctrl);
return seg;
}
tcp_segment_t *tcp_segment_make_rst(tcp_segment_t *seg)
{
tcp_segment_t *rseg;
rseg = tcp_segment_new();
if (rseg == NULL)
return NULL;
if ((seg->ctrl & CTL_ACK) == 0) {
rseg->ctrl = CTL_RST | CTL_ACK;
rseg->seq = 0;
rseg->ack = seg->seq + seg->len;
} else {
rseg->ctrl = CTL_RST;
rseg->seq = seg->ack;
}
return rseg;
}
tcp_segment_t *tcp_segment_make_data(tcp_control_t ctrl, void *data,
size_t size)
{
tcp_segment_t *seg;
seg = tcp_segment_new();
if (seg == NULL)
return NULL;
seg->ctrl = ctrl;
seg->len = seq_no_control_len(ctrl) + size;
seg->dfptr = seg->data = malloc(size);
if (seg->dfptr == NULL) {
free(seg);
return NULL;
}
memcpy(seg->data, data, size);
return seg;
}
void tcp_segment_trim(tcp_segment_t *seg, uint32_t left, uint32_t right)
{
uint32_t t_size;
assert(left + right <= seg->len);
if (left == seg->len) {
seg->seq = seg->seq + seg->len;
seg->len = 0;
return;
}
if (right == seg->len) {
seg->len = 0;
return;
}
t_size = tcp_segment_text_size(seg);
if (left > 0 && (seg->ctrl & CTL_SYN) != 0) {
seg->ctrl &= ~CTL_SYN;
seg->seq++;
seg->len--;
left--;
}
if (right > 0 && (seg->ctrl & CTL_FIN) != 0) {
seg->ctrl &= ~CTL_FIN;
seg->len--;
right--;
}
if (left > 0 || right > 0) {
assert(left + right <= t_size);
seg->data += left;
seg->len -= left + right;
}
}
void tcp_segment_text_copy(tcp_segment_t *seg, void *buf, size_t size)
{
assert(size <= tcp_segment_text_size(seg));
memcpy(buf, seg->data, size);
}
size_t tcp_segment_text_size(tcp_segment_t *seg)
{
return seg->len - seq_no_control_len(seg->ctrl);
}
void tcp_segment_dump(tcp_segment_t *seg)
{
log_msg(LOG_DEFAULT, LVL_DEBUG2, "Segment dump:");
log_msg(LOG_DEFAULT, LVL_DEBUG2, " - ctrl = %u", (unsigned)seg->ctrl);
log_msg(LOG_DEFAULT, LVL_DEBUG2, " - seq = %" PRIu32, seg->seq);
log_msg(LOG_DEFAULT, LVL_DEBUG2, " - ack = %" PRIu32, seg->ack);
log_msg(LOG_DEFAULT, LVL_DEBUG2, " - len = %" PRIu32, seg->len);
log_msg(LOG_DEFAULT, LVL_DEBUG2, " - wnd = %" PRIu32, seg->wnd);
log_msg(LOG_DEFAULT, LVL_DEBUG2, " - up = %" PRIu32, seg->up);
}
HelenOS homepage, sources at GitHub