# # Grand Unified Makefile for Xen. # # Default is to install to local 'dist' directory. DISTDIR ?= $(CURDIR)/dist DESTDIR ?= $(DISTDIR)/install INSTALL := install INSTALL_DIR := $(INSTALL) -d -m0755 INSTALL_DATA := $(INSTALL) -m0644 INSTALL_PROG := $(INSTALL) -m0755 KERNELS ?= linux-2.6-xen0 linux-2.6-xenU # linux-2.4-xen0 linux-2.4-xenU netbsd-2.0-xenU # You may use wildcards in the above e.g. KERNELS=*2.4* XKERNELS := $(foreach kernel, $(KERNELS), $(patsubst buildconfigs/mk.%,%,$(wildcard buildconfigs/mk.$(kernel))) ) export DESTDIR # Export target architecture overrides to Xen and Linux sub-trees. ifneq ($(XEN_TARGET_ARCH),) SUBARCH := $(subst x86_32,i386,$(XEN_TARGET_ARCH)) export XEN_TARGET_ARCH SUBARCH endif # Default target must appear before any include lines all: dist include Config.mk include buildconfigs/Rules.mk ifeq ($(XEN_TARGET_X86_PAE),y) export pae=y endif .PHONY: all dist install xen kernels tools docs world clean mkpatches mrproper .PHONY: kbuild kdelete kclean # build and install everything into the standard system directories install: install-xen install-kernels install-tools install-docs build: kernels $(MAKE) -C xen build $(MAKE) -C tools build $(MAKE) -C docs build # build and install everything into local dist directory dist: xen kernels tools docs $(INSTALL_DIR) $(DISTDIR)/check $(INSTALL_DATA) ./COPYING $(DISTDIR) $(INSTALL_DATA) ./README $(DISTDIR) $(INSTALL_PROG) ./install.sh $(DISTDIR) $(INSTALL_PROG) tools/check/chk tools/check/check_* $(DISTDIR)/check xen: $(MAKE) -C xen install tools: $(MAKE) -C tools install kernels: for i in $(XKERNELS) ; do $(MAKE) $$i-build || exit 1; done docs: sh ./docs/check_pkgs && $(MAKE) -C docs install || true # Build all the various kernels and modules kbuild: kernels # Delete the kernel build trees entirely kdelete: for i in $(XKERNELS) ; do $(MAKE) $$i-delete ; done # Clean the kernel build trees kclean: for i in $(XKERNELS) ; do $(MAKE) $$i-clean ; done # Make patches from kernel sparse trees mkpatches: for i in $(ALLSPARSETREES) ; do $(MAKE) $$i-xen.patch; done # build xen, the tools, and a domain 0 plus unprivileged linux-xen images, # and place them in the install directory. 'make install' should then # copy them to the normal system directories world: $(MAKE) clean $(MAKE) kdelete $(MAKE) dist # clean doesn't do a kclean clean:: $(MAKE) -C xen clean $(MAKE) -C tools clean $(MAKE) -C docs clean # clean, but blow away kernel build tree plus tar balls mrproper: clean rm -rf dist patches/tmp for i in $(ALLKERNELS) ; do $(MAKE) $$i-delete ; done for i in $(ALLSPARSETREES) ; do $(MAKE) $$i-mrproper ; done install-logging: LOGGING=logging-0.4.9.2 install-logging: [ -f $(LOGGING).tar.gz ] || wget http://www.red-dove.com/$(LOGGING).tar.gz tar -zxf $(LOGGING).tar.gz cd $(LOGGING) && python setup.py install # handy target to upgrade iptables (use rpm or apt-get in preference) install-iptables: wget http://www.netfilter.org/files/iptables-1.2.11.tar.bz2 tar -jxf iptables-1.2.11.tar.bz2 $(MAKE) -C iptables-1.2.11 PREFIX= KERNEL_DIR=../linux-$(LINUX_VER)-xen0 install install-%: DESTDIR= install-%: % @: # do nothing help: @echo 'Installation targets:' @echo ' install - build and install everything' @echo ' install-xen - build and install the Xen hypervisor' @echo ' install-tools - build and install the control tools' @echo ' install-kernels - build and install guest kernels' @echo ' install-docs - build and install documentation' @echo '' @echo 'Building targets:' @echo ' dist - build and install everything into local dist directory' @echo ' world - clean everything, delete guest kernel build' @echo ' trees then make dist' @echo ' xen - build and install Xen hypervisor' @echo ' tools - build and install tools' @echo ' kernels - build and install guest kernels' @echo ' kbuild - synonym for make kernels' @echo ' docs - build and install docs' @echo '' @echo 'Cleaning targets:' @echo ' clean - clean the Xen, tools and docs (but not' @echo ' guest kernel) trees' @echo ' mrproper - clean plus delete kernel tarballs and kernel' @echo ' build trees' @echo ' kdelete - delete guest kernel build trees' @echo ' kclean - clean guest kernel build trees' @echo '' @echo 'Dependency installation targets:' @echo ' install-logging - install the Python Logging package' @echo ' install-iptables - install iptables tools' @echo '' @echo 'Miscellaneous targets:' @echo ' mkpatches - make patches against vanilla kernels from' @echo ' sparse trees' @echo ' uninstall - attempt to remove installed Xen tools (use' @echo ' with extreme care!)' # Use this target with extreme care! uninstall: DESTDIR= uninstall: D=$(DESTDIR) uninstall: [ -d $(D)/etc/xen ] && mv -f $(D)/etc/xen $(D)/etc/xen.old-`date +%s` rm -rf $(D)/etc/init.d/xend* rm -rf $(D)/usr/$(LIBDIR)/libxc* $(D)/usr/$(LIBDIR)/libxutil* rm -rf $(D)/usr/$(LIBDIR)/python/xen $(D)/usr/include/xen rm -rf $(D)/usr/$(LIBDIR)/share/xen $(D)/usr/$(LIBDIR)/libxenstore* rm -rf $(D)/var/run/xen* $(D)/var/lib/xen* rm -rf $(D)/usr/include/xcs_proto.h $(D)/usr/include/xc.h rm -rf $(D)/usr/include/xs_lib.h $(D)/usr/include/xs.h rm -rf $(D)/usr/sbin/xcs $(D)/usr/sbin/xcsdump $(D)/usr/sbin/xen* rm -rf $(D)/usr/sbin/netfix rm -rf $(D)/usr/sbin/xfrd $(D)/usr/sbin/xm rm -rf $(D)/usr/share/doc/xen $(D)/usr/man/man*/xentrace* rm -rf $(D)/usr/bin/xen* $(D)/usr/bin/miniterm rm -rf $(D)/boot/*xen* rm -rf $(D)/lib/modules/*xen* rm -rf $(D)/usr/bin/cpuperf-perfcntr $(D)/usr/bin/cpuperf-xen rm -rf $(D)/usr/bin/xc_shadow rm -rf $(D)/usr/share/xen $(D)/usr/libexec/xen rm -rf $(D)/usr/share/man/man1/xen* rm -rf $(D)/usr/share/man/man8/xen* rm -rf $(D)/usr/lib/xen rm -rf $(D)/etc/hotplug.d/xen-backend rm -rf $(D)/etc/hotplug/xen-backend.agent # Legacy targets for compatibility linux24: $(MAKE) 'KERNELS=linux-2.4*' kernels linux26: $(MAKE) 'KERNELS=linux-2.6*' kernels netbsd20: $(MAKE) netbsd-2.0-xenU-build 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318
from __future__ import absolute_import
import os
import struct
import io
import warnings
import six
from netlib import tcp
from netlib import strutils
from netlib import utils
from netlib import human
from netlib.websockets import protocol
MAX_16_BIT_INT = (1 << 16)
MAX_64_BIT_INT = (1 << 64)
DEFAULT = object()
OPCODE = utils.BiDi(
CONTINUE=0x00,
TEXT=0x01,
BINARY=0x02,
CLOSE=0x08,
PING=0x09,
PONG=0x0a
)
class FrameHeader(object):
def __init__(
self,
opcode=OPCODE.TEXT,
payload_length=0,
fin=False,
rsv1=False,
rsv2=False,
rsv3=False,
masking_key=DEFAULT,
mask=DEFAULT,
length_code=DEFAULT
):
if not 0 <= opcode < 2 ** 4:
raise ValueError("opcode must be 0-16")
self.opcode = opcode
self.payload_length = payload_length
self.fin = fin
self.rsv1 = rsv1
self.rsv2 = rsv2
self.rsv3 = rsv3
if length_code is DEFAULT:
self.length_code = self._make_length_code(self.payload_length)
else:
self.length_code = length_code
if mask is DEFAULT and masking_key is DEFAULT:
self.mask = False
self.masking_key = b""
elif mask is DEFAULT:
self.mask = 1
self.masking_key = masking_key
elif masking_key is DEFAULT:
self.mask = mask
self.masking_key = os.urandom(4)
else:
self.mask = mask
self.masking_key = masking_key
if self.masking_key and len(self.masking_key) != 4:
raise ValueError("Masking key must be 4 bytes.")
@classmethod
def _make_length_code(self, length):
"""
A websockets frame contains an initial length_code, and an optional
extended length code to represent the actual length if length code is
larger than 125
"""
if length <= 125:
return length
elif length >= 126 and length <= 65535:
return 126
else:
return 127
def __repr__(self):
vals = [
"ws frame:",
OPCODE.get_name(self.opcode, hex(self.opcode)).lower()
]
flags = []
for i in ["fin", "rsv1", "rsv2", "rsv3", "mask"]:
if getattr(self, i):
flags.append(i)
if flags:
vals.extend([":", "|".join(flags)])
if self.masking_key:
vals.append(":key=%s" % repr(self.masking_key))
if self.payload_length:
vals.append(" %s" % human.pretty_size(self.payload_length))
return "".join(vals)
def human_readable(self):
warnings.warn("FrameHeader.to_bytes is deprecated, use bytes(frame_header) instead.", DeprecationWarning)
return repr(self)
def __bytes__(self):
first_byte = utils.setbit(0, 7, self.fin)
first_byte = utils.setbit(first_byte, 6, self.rsv1)
first_byte = utils.setbit(first_byte, 5, self.rsv2)
first_byte = utils.setbit(first_byte, 4, self.rsv3)
first_byte = first_byte | self.opcode
second_byte = utils.setbit(self.length_code, 7, self.mask)
b = six.int2byte(first_byte) + six.int2byte(second_byte)
if self.payload_length < 126:
pass
elif self.payload_length < MAX_16_BIT_INT:
# '!H' pack as 16 bit unsigned short
# add 2 byte extended payload length
b += struct.pack('!H', self.payload_length)
elif self.payload_length < MAX_64_BIT_INT:
# '!Q' = pack as 64 bit unsigned long long
# add 8 bytes extended payload length
b += struct.pack('!Q', self.payload_length)
if self.masking_key:
b += self.masking_key
return b
if six.PY2:
__str__ = __bytes__
def to_bytes(self):
warnings.warn("FrameHeader.to_bytes is deprecated, use bytes(frame_header) instead.", DeprecationWarning)
return bytes(self)
@classmethod
def from_file(cls, fp):
"""
read a websockets frame header
"""
first_byte = six.byte2int(fp.safe_read(1))
second_byte = six.byte2int(fp.safe_read(1))
fin = utils.getbit(first_byte, 7)
rsv1 = utils.getbit(first_byte, 6)
rsv2 = utils.getbit(first_byte, 5)
rsv3 = utils.getbit(first_byte, 4)
# grab right-most 4 bits
opcode = first_byte & 15
mask_bit = utils.getbit(second_byte, 7)
# grab the next 7 bits
length_code = second_byte & 127
# payload_lengthy > 125 indicates you need to read more bytes
# to get the actual payload length
if length_code <= 125:
payload_length = length_code
elif length_code == 126:
payload_length, = struct.unpack("!H", fp.safe_read(2))
elif length_code == 127:
payload_length, = struct.unpack("!Q", fp.safe_read(8))
# masking key only present if mask bit set
if mask_bit == 1:
masking_key = fp.safe_read(4)
else:
masking_key = None
return cls(
fin=fin,
rsv1=rsv1,
rsv2=rsv2,
rsv3=rsv3,
opcode=opcode,
mask=mask_bit,
length_code=length_code,
payload_length=payload_length,
masking_key=masking_key,
)
def __eq__(self, other):
if isinstance(other, FrameHeader):
return bytes(self) == bytes(other)
return False
class Frame(object):
"""
Represents one websockets frame.
Constructor takes human readable forms of the frame components
from_bytes() is also avaliable.
WebSockets Frame as defined in RFC6455
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-------+-+-------------+-------------------------------+
|F|R|R|R| opcode|M| Payload len | Extended payload length |
|I|S|S|S| (4) |A| (7) | (16/64) |
|N|V|V|V| |S| | (if payload len==126/127) |
| |1|2|3| |K| | |
+-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
| Extended payload length continued, if payload len == 127 |
+ - - - - - - - - - - - - - - - +-------------------------------+
| |Masking-key, if MASK set to 1 |
+-------------------------------+-------------------------------+
| Masking-key (continued) | Payload Data |
+-------------------------------- - - - - - - - - - - - - - - - +
: Payload Data continued ... :
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
| Payload Data continued ... |
+---------------------------------------------------------------+
"""
def __init__(self, payload=b"", **kwargs):
self.payload = payload
kwargs["payload_length"] = kwargs.get("payload_length", len(payload))
self.header = FrameHeader(**kwargs)
@classmethod
def default(cls, message, from_client=False):
"""
Construct a basic websocket frame from some default values.
Creates a non-fragmented text frame.
"""
if from_client:
mask_bit = 1
masking_key = os.urandom(4)
else:
mask_bit = 0
masking_key = None
return cls(
message,
fin=1, # final frame
opcode=OPCODE.TEXT, # text
mask=mask_bit,
masking_key=masking_key,
)
@classmethod
def from_bytes(cls, bytestring):
"""
Construct a websocket frame from an in-memory bytestring
to construct a frame from a stream of bytes, use from_file() directly
"""
return cls.from_file(tcp.Reader(io.BytesIO(bytestring)))
def __repr__(self):
ret = repr(self.header)
if self.payload:
ret = ret + "\nPayload:\n" + strutils.bytes_to_escaped_str(self.payload)
return ret
def human_readable(self):
warnings.warn("Frame.to_bytes is deprecated, use bytes(frame) instead.", DeprecationWarning)
return repr(self)
def __bytes__(self):
"""
Serialize the frame to wire format. Returns a string.
"""
b = bytes(self.header)
if self.header.masking_key:
b += protocol.Masker(self.header.masking_key)(self.payload)
else:
b += self.payload
return b
if six.PY2:
__str__ = __bytes__
def to_bytes(self):
warnings.warn("FrameHeader.to_bytes is deprecated, use bytes(frame_header) instead.", DeprecationWarning)
return bytes(self)
def to_file(self, writer):
warnings.warn("Frame.to_file is deprecated, use wfile.write(bytes(frame)) instead.", DeprecationWarning)
writer.write(bytes(self))
writer.flush()
@classmethod
def from_file(cls, fp):
"""
read a websockets frame sent by a server or client
fp is a "file like" object that could be backed by a network
stream or a disk or an in memory stream reader
"""
header = FrameHeader.from_file(fp)
payload = fp.safe_read(header.payload_length)
if header.mask == 1 and header.masking_key:
payload = protocol.Masker(header.masking_key)(payload)
return cls(
payload,
fin=header.fin,
opcode=header.opcode,
mask=header.mask,
payload_length=header.payload_length,
masking_key=header.masking_key,
rsv1=header.rsv1,
rsv2=header.rsv2,
rsv3=header.rsv3,
length_code=header.length_code
)
def __eq__(self, other):
if isinstance(other, Frame):
return bytes(self) == bytes(other)
return False