aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam/packet_parser.h
diff options
context:
space:
mode:
Diffstat (limited to 'erts/emulator/beam/packet_parser.h')
-rw-r--r--erts/emulator/beam/packet_parser.h181
1 files changed, 181 insertions, 0 deletions
diff --git a/erts/emulator/beam/packet_parser.h b/erts/emulator/beam/packet_parser.h
new file mode 100644
index 0000000000..1c3a9aa3da
--- /dev/null
+++ b/erts/emulator/beam/packet_parser.h
@@ -0,0 +1,181 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 2008-2009. All Rights Reserved.
+ *
+ * The contents of this file are subject to the Erlang Public License,
+ * Version 1.1, (the "License"); you may not use this file except in
+ * compliance with the License. You should have received a copy of the
+ * Erlang Public License along with this software. If not, it can be
+ * retrieved online at http://www.erlang.org/.
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * %CopyrightEnd%
+ */
+
+/* A protocol decoder. Simple packet length extraction as well as packet
+ * body parsing with protocol specific callback interfaces (http and ssl).
+ */
+#ifndef __PACKET_PARSER_H__
+#define __PACKET_PARSER_H__
+
+#include <erl_driver.h>
+#include "sys.h"
+
+
+/* INET_LOPT_PACKET options */
+enum PacketParseType {
+ TCP_PB_RAW = 0,
+ TCP_PB_1 = 1,
+ TCP_PB_2 = 2,
+ TCP_PB_4 = 3,
+ TCP_PB_ASN1 = 4,
+ TCP_PB_RM = 5,
+ TCP_PB_CDR = 6,
+ TCP_PB_FCGI = 7,
+ TCP_PB_LINE_LF = 8,
+ TCP_PB_TPKT = 9,
+ TCP_PB_HTTP = 10,
+ TCP_PB_HTTPH = 11,
+ TCP_PB_SSL_TLS = 12,
+ TCP_PB_HTTP_BIN = 13,
+ TCP_PB_HTTPH_BIN = 14
+};
+
+typedef struct http_atom {
+ struct http_atom* next; /* next in bucket */
+ unsigned long h; /* stored hash value */
+ const char* name;
+ int len;
+ int index; /* index in table + bit-pos */
+ ErlDrvTermData atom; /* erlang atom rep */
+} http_atom_t;
+
+typedef struct {
+ enum {
+ URI_STAR, /* '*' */
+ URI_STRING, /* "string(s1)" */
+ URI_ABS_PATH,/* {abs_path, "path(s1)"} */
+ URI_SCHEME, /* {scheme, "scheme(s1)", "string(s2)"} */
+ URI_HTTP, /* {absoluteURI, http, "host(s1)", Port, "path(s2)"} */
+ URI_HTTPS /* {absoluteURI, https, ... */
+ } type;
+ const char* s1_ptr;
+ int s1_len;
+ const char* s2_ptr;
+ int s2_len;
+ int port; /* 0=undefined */
+}PacketHttpURI;
+
+typedef int HttpResponseMessageFn(void* arg, int major, int minor, int status,
+ const char* phrase, int phrase_len);
+typedef int HttpRequestMessageFn(void* arg, const http_atom_t* meth, const char* meth_ptr,
+ int meth_len, const PacketHttpURI*, int major, int minor);
+typedef int HttpEohMessageFn(void *arg);
+typedef int HttpHeaderMessageFn(void* arg, const http_atom_t* name, const char* name_ptr,
+ int name_len, const char* value_ptr, int value_len);
+typedef int HttpErrorMessageFn(void* arg, const char* buf, int len);
+typedef int SslTlsFn(void* arg, unsigned type, unsigned major, unsigned minor,
+ const char* data, int len, const char* prefix, int plen);
+
+typedef struct {
+ HttpResponseMessageFn* http_response;
+ HttpRequestMessageFn* http_request;
+ HttpEohMessageFn* http_eoh;
+ HttpHeaderMessageFn* http_header;
+ HttpErrorMessageFn* http_error;
+ SslTlsFn* ssl_tls;
+}PacketCallbacks;
+
+
+/* Called once at emulator start
+ */
+void packet_parser_init(void);
+
+/* Returns > 0 Total packet length.
+ * = 0 Length unknown, need more data.
+ * < 0 Error, invalid format.
+ */
+int packet_get_length(enum PacketParseType htype,
+ const char* ptr, unsigned n, /* Bytes read so far */
+ unsigned max_plen, /* Packet max length, 0=no limit */
+ unsigned trunc_len, /* Truncate (lines) if longer, 0=no limit */
+ int* statep); /* Internal protocol state */
+
+ERTS_GLB_INLINE
+void packet_get_body(enum PacketParseType htype,
+ const char** bufp, /* In: Packet header, Out: Packet body */
+ int* lenp); /* In: Packet length, Out: Body length */
+
+/* Returns 1 = Packet parsed and handled by callbacks.
+** 0 = No parsing support for this packet type
+** -1 = Error
+*/
+ERTS_GLB_INLINE
+int packet_parse(enum PacketParseType htype,
+ const char* buf, int len, /* Total packet */
+ int* statep, PacketCallbacks* pcb, void* arg);
+
+
+
+/* Internals for the inlines below: */
+
+#define FCGI_VERSION_1 1
+struct fcgi_head {
+ unsigned char version;
+ unsigned char type;
+ unsigned char requestIdB1;
+ unsigned char requestIdB0;
+ unsigned char contentLengthB1;
+ unsigned char contentLengthB0;
+ unsigned char paddingLength;
+ unsigned char reserved;
+ /* char data[] */
+ /* char padding[paddingLength] */
+};
+int packet_parse_http(const char*, int, int*, PacketCallbacks*, void*);
+int packet_parse_ssl(const char*, int, PacketCallbacks*, void*);
+
+
+#if ERTS_GLB_INLINE_INCL_FUNC_DEF
+ERTS_GLB_INLINE
+void packet_get_body(enum PacketParseType htype, const char** bufp, int* lenp)
+{
+ switch (htype) {
+ case TCP_PB_1: *bufp += 1; *lenp -= 1; break;
+ case TCP_PB_2: *bufp += 2; *lenp -= 2; break;
+ case TCP_PB_4: *bufp += 4; *lenp -= 4; break;
+ case TCP_PB_FCGI:
+ *lenp -= ((struct fcgi_head*)*bufp)->paddingLength;
+ break;
+ default:
+ ;/* Return other packets "as is" */
+ }
+}
+
+ERTS_GLB_INLINE
+int packet_parse(enum PacketParseType htype, const char* buf, int len,
+ int* statep, PacketCallbacks* pcb, void* arg)
+{
+ switch (htype) {
+ case TCP_PB_HTTP:
+ case TCP_PB_HTTPH:
+ case TCP_PB_HTTP_BIN:
+ case TCP_PB_HTTPH_BIN:
+ if (packet_parse_http(buf, len, statep, pcb, arg) < 0)
+ pcb->http_error(arg, buf, len);
+ return 1;
+ case TCP_PB_SSL_TLS:
+ return packet_parse_ssl(buf, len, pcb, arg);
+ default:;
+ }
+ return 0;
+}
+#endif /* ERTS_GLB_INLINE_INCL_FUNC_DEF */
+
+#endif /* !__PACKET_PARSER_H__ */
+