static gboolean relay_length (CockpitHttpStream *self, CockpitChannel *channel, GByteArray *buffer) { GBytes *message = NULL; gsize block; g_assert (self->response_length >= 0); if (self->response_length == 0) { /* All done, yay */ g_debug ("%s: received enough bytes", self->name); cockpit_channel_close (channel, NULL); g_assert (self->state == FINISHED); } else if (buffer->len == 0) { /* Not enough data? */ return FALSE; } else { block = MIN (buffer->len, self->response_length); self->response_length -= block; message = cockpit_pipe_consume (buffer, 0, block, 0); relay_data (channel, message); g_bytes_unref (message); } return TRUE; }
void read_real_data(struct params *p, struct ieee80211_frame *wh, int len) { char dst[6]; int rc; char *ptr = (char*) (wh+1); /* stuff not for this net */ if (memcmp(wh->i_addr1, p->mac, 6) != 0) return; /* relay data */ if (memcmp(wh->i_addr3, p->mac, 6) != 0) relay_data(p, wh, len); memcpy(dst, wh->i_addr3, 6); if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) { if (!p->wep_len) { printf("Got wep but i aint wep\n"); return; } if (wep_decrypt(wh, len, p->wep_key, p->wep_len) == -1){ printf("Can't decrypt\n"); return; } ptr += 4; len -= 8; } /* ether header */ ptr += 8 - 2; ptr -= 6; memcpy(ptr, wh->i_addr2, 6); ptr -= 6; memcpy(ptr, dst, 6); len -= sizeof(*wh); len -= 8; len += 14; /* send to tap */ rc = write(p->tap, ptr, len); if (rc == -1) err(1, "write()"); if (rc != len) { printf("Wrote %d/%d\n", rc, len); exit(1); } }
static gboolean relay_all (CockpitHttpStream *self, CockpitChannel *channel, GByteArray *buffer) { GBytes *message; if (buffer->len == 0) { /* Not enough data? */ return FALSE; } message = cockpit_pipe_consume (buffer, 0, buffer->len, 0); relay_data (channel, message); g_bytes_unref (message); return TRUE; }
static gboolean relay_chunked (CockpitHttpStream *self, CockpitChannel *channel, GByteArray *buffer) { GBytes *message; const gchar *data; const gchar *pos; guint64 size; gsize length; gsize beg; gchar *end; data = (const gchar *)buffer->data; length = buffer->len; pos = memchr (data, '\r', length); if (pos == NULL) return FALSE; /* want more data */ beg = (pos + 2) - data; if (length < beg) { /* have to have a least the ending chars */ return FALSE; /* want more data */ } size = g_ascii_strtoull (data, &end, 16); if (pos[1] != '\n' || end != pos) { cockpit_channel_fail (channel, "protocol-error", "%s: received invalid HTTP chunk", self->name); } else if (size > G_MAXSSIZE) { cockpit_channel_fail (channel, "protocol-error", "%s: received extremely large HTTP chunk", self->name); } else if (length < beg + size + 2) { return FALSE; /* want more data */ } else if (data[beg + size] != '\r' || data[beg + size + 1] != '\n') { cockpit_channel_fail (channel, "protocol-error", "%s: received invalid HTTP chunk data", self->name); } else if (size == 0) { /* All done, yay */ g_debug ("%s: received last chunk", self->name); cockpit_pipe_skip (buffer, beg + 2); cockpit_channel_close (channel, NULL); g_assert (self->state == FINISHED); } else { message = cockpit_pipe_consume (buffer, beg, size, 2); relay_data (channel, message); g_bytes_unref (message); return TRUE; } return TRUE; }