Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
D
Dnsmasq
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Packages
Packages
List
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issues
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nanahira
Dnsmasq
Commits
91dccd09
Commit
91dccd09
authored
Mar 31, 2005
by
Simon Kelley
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
import of dnsmasq-2.22.tar.gz
parent
0a852541
Changes
13
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
350 additions
and
188 deletions
+350
-188
CHANGELOG
CHANGELOG
+22
-0
dnsmasq-rh.spec
dnsmasq-rh.spec
+1
-1
dnsmasq-suse.spec
dnsmasq-suse.spec
+1
-1
dnsmasq.8
dnsmasq.8
+15
-2
dnsmasq.conf.example
dnsmasq.conf.example
+7
-0
rpm/dnsmasq-SuSE.patch
rpm/dnsmasq-SuSE.patch
+1
-1
src/config.h
src/config.h
+2
-2
src/dhcp.c
src/dhcp.c
+6
-2
src/dnsmasq.h
src/dnsmasq.h
+2
-2
src/netlink.c
src/netlink.c
+1
-0
src/option.c
src/option.c
+208
-150
src/rfc1035.c
src/rfc1035.c
+2
-1
src/rfc2131.c
src/rfc2131.c
+82
-26
No files found.
CHANGELOG
View file @
91dccd09
...
@@ -1422,3 +1422,25 @@ version 2.21
...
@@ -1422,3 +1422,25 @@ version 2.21
Added wildcard matching for MAC addresses in dhcp-host
Added wildcard matching for MAC addresses in dhcp-host
options. A sensible suggestion by Nathaniel McCallum.
options. A sensible suggestion by Nathaniel McCallum.
version 2.22
Fixed build problems on (many) systems with older libc
headers where <linux/types.h> is required before
<linux/netlink.h>. Enabled HAVE_RTNETLINK under uclibc now
that this fix is in place.
Added support for encapsulated vendor-class-specific DHCP
options. Thanks to Eric Shattow for help with this.
Fix regression in 2.21 which broke commas in filenames and
corrupted argv. Thanks to Eric Scott for the bugreport.
Fixed stupid thinko which caused dnsmasq to wedge during
startup with certain MX-record options. Another 2.21 regression.
Fixed broken-ness when reading /etc/ethers. 2.21 broke
this too.
Fixed wedge with certain DHCP options. Yet another 2.21
regression. Rob Holland and Roy Marples chased this one
down.
dnsmasq-rh.spec
View file @
91dccd09
...
@@ -5,7 +5,7 @@
...
@@ -5,7 +5,7 @@
###############################################################################
###############################################################################
Name: dnsmasq
Name: dnsmasq
Version: 2.2
1
Version: 2.2
2
Release: 1
Release: 1
Copyright: GPL
Copyright: GPL
Group: System Environment/Daemons
Group: System Environment/Daemons
...
...
dnsmasq-suse.spec
View file @
91dccd09
...
@@ -5,7 +5,7 @@
...
@@ -5,7 +5,7 @@
###############################################################################
###############################################################################
Name: dnsmasq
Name: dnsmasq
Version: 2.2
1
Version: 2.2
2
Release: 1
Release: 1
Copyright: GPL
Copyright: GPL
Group: Productivity/Networking/DNS/Servers
Group: Productivity/Networking/DNS/Servers
...
...
dnsmasq.8
View file @
91dccd09
...
@@ -408,7 +408,7 @@ have exactly the same effect as
...
@@ -408,7 +408,7 @@ have exactly the same effect as
.B --dhcp-host
.B --dhcp-host
options containing the same information.
options containing the same information.
.TP
.TP
.B \-O, --dhcp-option=[<network-id>,[<network-id>,]]<opt>,[<value>[,<value>]]
.B \-O, --dhcp-option=[<network-id>,[<network-id>,]]
[vendor:<vendor-class>]
<opt>,[<value>[,<value>]]
Specfify different or extra options to DHCP clients. By default,
Specfify different or extra options to DHCP clients. By default,
dnsmasq sends some standard options to DHCP clients, the netmask and
dnsmasq sends some standard options to DHCP clients, the netmask and
broadcast address are set to the same as the host running dnsmasq, and
broadcast address are set to the same as the host running dnsmasq, and
...
@@ -426,10 +426,23 @@ machine running dnsmasq". Data types allowed are comma separated
...
@@ -426,10 +426,23 @@ machine running dnsmasq". Data types allowed are comma separated
dotted-quad IP addresses, a decimal number, colon-separated hex digits
dotted-quad IP addresses, a decimal number, colon-separated hex digits
and a text string. If the optional network-ids are given then
and a text string. If the optional network-ids are given then
this option is only sent when all the network-ids are matched.
this option is only sent when all the network-ids are matched.
Be careful: no checking is done that the correct type of data for the
Be careful: no checking is done that the correct type of data for the
option number is sent, it is quite possible to
option number is sent, it is quite possible to
persuade dnsmasq to generate illegal DHCP packets with injudicious use
persuade dnsmasq to generate illegal DHCP packets with injudicious use
of this flag.
of this flag. When the value is a decimal number, dnsmasq must determine how
large the data item is. It does this by examining the option number and/or the
value, but can be overriden by appending a single letter flag as follows:
b = one byte, s = two bytes, i = four bytes. This is mainly useful with
encapsulated vendor class options (see below) where dnsmasq cannot determine data size from the option number.
Encapsulated Vendor-class options may also be specified using
--dhcp-option: for instance
.B --dhcp-option=vendor:PXEClient,1,0.0.0.0
sends the vendor class "PXEClient" and the encapsulated vendor class-specific option "mftp-address=0.0.0.0" Only one vendor class is allowed for any
host, but multiple options are allowed, provided they all have
the same vendor class. The address 0.0.0.0 is not treated specially in
encapsulated vendor class options.
.TP
.TP
.B \-U, --dhcp-vendorclass=<network-id>,<vendor-class>
.B \-U, --dhcp-vendorclass=<network-id>,<vendor-class>
Map from a vendor-class string to a network id. Most DHCP clients provide a
Map from a vendor-class string to a network id. Most DHCP clients provide a
...
...
dnsmasq.conf.example
View file @
91dccd09
...
@@ -239,6 +239,13 @@ bogus-priv
...
@@ -239,6 +239,13 @@ bogus-priv
# probably doesn't support this......
# probably doesn't support this......
#dhcp-option=119,eng.apple.com,marketing.apple.com
#dhcp-option=119,eng.apple.com,marketing.apple.com
# Send encapsulated vendor-class specific options. The vendor-class
# is sent as DHCP option 60, and all the options marked with the
# vendor class are send encapsulated in DHCP option 43. The meaning of
# the options is defined by the vendor-class. This example sets the
# mtftp address to 0.0.0.0 for PXEClients
#dhcp-option=vendor:PXEClient,1,0.0.0.0
# Set the boot filename and tftpd server name and address
# Set the boot filename and tftpd server name and address
# for BOOTP. You will only need this is you want to
# for BOOTP. You will only need this is you want to
# boot machines over the network.
# boot machines over the network.
...
...
rpm/dnsmasq-SuSE.patch
View file @
91dccd09
...
@@ -20,7 +20,7 @@
...
@@ -20,7 +20,7 @@
#define IP6INTERFACES "/proc/net/if_inet6"
#define IP6INTERFACES "/proc/net/if_inet6"
#define UPTIME "/proc/uptime"
#define UPTIME "/proc/uptime"
#define DHCP_SERVER_PORT 67
#define DHCP_SERVER_PORT 67
@@ -1
87,7 +187
,7 @@
@@ -1
95,7 +195
,7 @@
/* platform independent options. */
/* platform independent options. */
#undef HAVE_BROKEN_RTC
#undef HAVE_BROKEN_RTC
...
...
src/config.h
View file @
91dccd09
...
@@ -12,7 +12,7 @@
...
@@ -12,7 +12,7 @@
/* Author's email: simon@thekelleys.org.uk */
/* Author's email: simon@thekelleys.org.uk */
#define VERSION "2.2
1
"
#define VERSION "2.2
2
"
#define FTABSIZ 150
/* max number of outstanding requests */
#define FTABSIZ 150
/* max number of outstanding requests */
#define MAX_PROCS 20
/* max no children for TCP requests */
#define MAX_PROCS 20
/* max no children for TCP requests */
...
@@ -207,7 +207,7 @@ NOTES:
...
@@ -207,7 +207,7 @@ NOTES:
#if defined(__uClinux__) || defined(__UCLIBC__)
#if defined(__uClinux__) || defined(__UCLIBC__)
#undef HAVE_LINUX_IPV6_PROC
#undef HAVE_LINUX_IPV6_PROC
#define HAVE_GETOPT_LONG
#define HAVE_GETOPT_LONG
#
undef HAVE_RTNETLINK
/* headers broken */
#
define HAVE_RTNETLINK
#undef HAVE_ARC4RANDOM
#undef HAVE_ARC4RANDOM
#define HAVE_RANDOM
#define HAVE_RANDOM
#define HAVE_DEV_URANDOM
#define HAVE_DEV_URANDOM
...
...
src/dhcp.c
View file @
91dccd09
...
@@ -206,8 +206,9 @@ void dhcp_packet(struct daemon *daemon, time_t now)
...
@@ -206,8 +206,9 @@ void dhcp_packet(struct daemon *daemon, time_t now)
return
;
return
;
}
}
/* unlinked contexts are marked by context->current == context */
for
(
context
=
daemon
->
dhcp
;
context
;
context
=
context
->
next
)
for
(
context
=
daemon
->
dhcp
;
context
;
context
=
context
->
next
)
context
->
current
=
NULL
;
context
->
current
=
context
;
#ifdef HAVE_RTNETLINK
#ifdef HAVE_RTNETLINK
if
(
!
netlink_process
(
daemon
,
iface_index
,
mess
->
giaddr
,
iface_addr
,
&
context
))
if
(
!
netlink_process
(
daemon
,
iface_index
,
mess
->
giaddr
,
iface_addr
,
&
context
))
...
@@ -381,7 +382,8 @@ struct dhcp_context *complete_context(struct daemon *daemon, struct in_addr loca
...
@@ -381,7 +382,8 @@ struct dhcp_context *complete_context(struct daemon *daemon, struct in_addr loca
if
(
is_same_net
(
local
,
context
->
start
,
context
->
netmask
)
&&
if
(
is_same_net
(
local
,
context
->
start
,
context
->
netmask
)
&&
is_same_net
(
local
,
context
->
end
,
context
->
netmask
))
is_same_net
(
local
,
context
->
end
,
context
->
netmask
))
{
{
if
(
!
context
->
current
)
/* link it onto the current chain if we've not seen it before */
if
(
context
->
current
==
context
)
{
{
context
->
router
=
local
;
context
->
router
=
local
;
context
->
local
=
local
;
context
->
local
=
local
;
...
@@ -684,6 +686,7 @@ void dhcp_read_ethers(struct daemon *daemon)
...
@@ -684,6 +686,7 @@ void dhcp_read_ethers(struct daemon *daemon)
{
{
for
(
config
=
configs
;
config
;
config
=
config
->
next
)
for
(
config
=
configs
;
config
;
config
=
config
->
next
)
if
((
config
->
flags
&
CONFIG_HWADDR
)
&&
if
((
config
->
flags
&
CONFIG_HWADDR
)
&&
config
->
wildcard_mask
==
0
&&
memcmp
(
config
->
hwaddr
,
hwaddr
,
ETHER_ADDR_LEN
)
==
0
)
memcmp
(
config
->
hwaddr
,
hwaddr
,
ETHER_ADDR_LEN
)
==
0
)
break
;
break
;
...
@@ -692,6 +695,7 @@ void dhcp_read_ethers(struct daemon *daemon)
...
@@ -692,6 +695,7 @@ void dhcp_read_ethers(struct daemon *daemon)
if
(
!
(
config
=
malloc
(
sizeof
(
struct
dhcp_config
))))
if
(
!
(
config
=
malloc
(
sizeof
(
struct
dhcp_config
))))
continue
;
continue
;
config
->
flags
=
0
;
config
->
flags
=
0
;
config
->
wildcard_mask
=
0
;
config
->
next
=
configs
;
config
->
next
=
configs
;
configs
=
config
;
configs
=
config
;
}
}
...
...
src/dnsmasq.h
View file @
91dccd09
...
@@ -321,7 +321,7 @@ struct dhcp_config {
...
@@ -321,7 +321,7 @@ struct dhcp_config {
struct
dhcp_opt
{
struct
dhcp_opt
{
int
opt
,
len
,
is_addr
;
int
opt
,
len
,
is_addr
;
unsigned
char
*
val
;
unsigned
char
*
val
,
*
vendor_class
;
struct
dhcp_netid
*
netid
;
struct
dhcp_netid
*
netid
;
struct
dhcp_opt
*
next
;
struct
dhcp_opt
*
next
;
};
};
...
@@ -403,7 +403,7 @@ struct daemon {
...
@@ -403,7 +403,7 @@ struct daemon {
struct
hostsfile
*
addn_hosts
;
struct
hostsfile
*
addn_hosts
;
struct
dhcp_context
*
dhcp
;
struct
dhcp_context
*
dhcp
;
struct
dhcp_config
*
dhcp_conf
;
struct
dhcp_config
*
dhcp_conf
;
struct
dhcp_opt
*
dhcp_opts
;
struct
dhcp_opt
*
dhcp_opts
,
*
vendor_opts
;
struct
dhcp_vendor
*
dhcp_vendors
;
struct
dhcp_vendor
*
dhcp_vendors
;
struct
dhcp_boot
*
boot_config
;
struct
dhcp_boot
*
boot_config
;
struct
dhcp_netid_list
*
dhcp_ignore
;
struct
dhcp_netid_list
*
dhcp_ignore
;
...
...
src/netlink.c
View file @
91dccd09
...
@@ -16,6 +16,7 @@
...
@@ -16,6 +16,7 @@
#ifdef HAVE_RTNETLINK
#ifdef HAVE_RTNETLINK
#include <linux/types.h>
#include <linux/netlink.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <linux/rtnetlink.h>
...
...
src/option.c
View file @
91dccd09
This diff is collapsed.
Click to expand it.
src/rfc1035.c
View file @
91dccd09
...
@@ -340,7 +340,8 @@ static unsigned char *skip_section(unsigned char *ansp, int count, HEADER *heade
...
@@ -340,7 +340,8 @@ static unsigned char *skip_section(unsigned char *ansp, int count, HEADER *heade
We ignore case in the names for the same reason. */
We ignore case in the names for the same reason. */
unsigned
int
questions_crc
(
HEADER
*
header
,
unsigned
int
plen
,
char
*
name
)
unsigned
int
questions_crc
(
HEADER
*
header
,
unsigned
int
plen
,
char
*
name
)
{
{
unsigned
int
q
,
crc
=
0xffffffff
;
int
q
;
unsigned
int
crc
=
0xffffffff
;
unsigned
char
*
p1
,
*
p
=
(
unsigned
char
*
)(
header
+
1
);
unsigned
char
*
p1
,
*
p
=
(
unsigned
char
*
)(
header
+
1
);
for
(
q
=
0
;
q
<
ntohs
(
header
->
qdcount
);
q
++
)
for
(
q
=
0
;
q
<
ntohs
(
header
->
qdcount
);
q
++
)
...
...
src/rfc2131.c
View file @
91dccd09
...
@@ -29,6 +29,7 @@
...
@@ -29,6 +29,7 @@
#define OPTION_HOSTNAME 12
#define OPTION_HOSTNAME 12
#define OPTION_DOMAINNAME 15
#define OPTION_DOMAINNAME 15
#define OPTION_BROADCAST 28
#define OPTION_BROADCAST 28
#define OPTION_VENDOR_CLASS_OPT 43
#define OPTION_REQUESTED_IP 50
#define OPTION_REQUESTED_IP 50
#define OPTION_LEASE_TIME 51
#define OPTION_LEASE_TIME 51
#define OPTION_OVERLOAD 52
#define OPTION_OVERLOAD 52
...
@@ -808,7 +809,6 @@ static int in_list(unsigned char *list, int opt)
...
@@ -808,7 +809,6 @@ static int in_list(unsigned char *list, int opt)
static
struct
dhcp_opt
*
option_find2
(
struct
dhcp_netid
*
netid
,
struct
dhcp_opt
*
opts
,
int
opt
)
static
struct
dhcp_opt
*
option_find2
(
struct
dhcp_netid
*
netid
,
struct
dhcp_opt
*
opts
,
int
opt
)
{
{
struct
dhcp_opt
*
tmp
;
struct
dhcp_opt
*
tmp
;
for
(
tmp
=
opts
;
tmp
;
tmp
=
tmp
->
next
)
for
(
tmp
=
opts
;
tmp
;
tmp
=
tmp
->
next
)
if
(
tmp
->
opt
==
opt
)
if
(
tmp
->
opt
==
opt
)
{
{
...
@@ -824,6 +824,40 @@ static struct dhcp_opt *option_find2(struct dhcp_netid *netid, struct dhcp_opt *
...
@@ -824,6 +824,40 @@ static struct dhcp_opt *option_find2(struct dhcp_netid *netid, struct dhcp_opt *
return
netid
?
option_find2
(
NULL
,
opts
,
opt
)
:
NULL
;
return
netid
?
option_find2
(
NULL
,
opts
,
opt
)
:
NULL
;
}
}
static
unsigned
char
*
do_opt
(
struct
dhcp_opt
*
opt
,
unsigned
char
*
p
,
unsigned
char
*
end
,
struct
in_addr
local
)
{
if
(
p
+
opt
->
len
+
3
>=
end
)
return
p
;
*
(
p
++
)
=
opt
->
opt
;
*
(
p
++
)
=
opt
->
len
;
if
(
opt
->
len
==
0
)
return
p
;
if
(
opt
->
is_addr
&&
!
opt
->
vendor_class
)
{
int
j
;
struct
in_addr
*
a
=
(
struct
in_addr
*
)
opt
->
val
;
for
(
j
=
0
;
j
<
opt
->
len
;
j
+=
INADDRSZ
,
a
++
)
{
/* zero means "self" (but not in vendorclass options.) */
if
(
a
->
s_addr
==
0
)
memcpy
(
p
,
&
local
,
INADDRSZ
);
else
memcpy
(
p
,
a
,
INADDRSZ
);
p
+=
INADDRSZ
;
}
}
else
{
memcpy
(
p
,
opt
->
val
,
opt
->
len
);
p
+=
opt
->
len
;
}
return
p
;
}
static
unsigned
char
*
do_req_options
(
struct
dhcp_context
*
context
,
static
unsigned
char
*
do_req_options
(
struct
dhcp_context
*
context
,
unsigned
char
*
p
,
unsigned
char
*
end
,
unsigned
char
*
p
,
unsigned
char
*
end
,
unsigned
char
*
req_options
,
unsigned
char
*
req_options
,
...
@@ -833,6 +867,7 @@ static unsigned char *do_req_options(struct dhcp_context *context,
...
@@ -833,6 +867,7 @@ static unsigned char *do_req_options(struct dhcp_context *context,
struct
in_addr
subnet_addr
)
struct
in_addr
subnet_addr
)
{
{
struct
dhcp_opt
*
opt
,
*
config_opts
=
daemon
->
dhcp_opts
;
struct
dhcp_opt
*
opt
,
*
config_opts
=
daemon
->
dhcp_opts
;
char
*
vendor_class
=
NULL
;
if
(
in_list
(
req_options
,
OPTION_MAXMESSAGE
))
if
(
in_list
(
req_options
,
OPTION_MAXMESSAGE
))
p
=
option_put
(
p
,
end
,
OPTION_MAXMESSAGE
,
2
,
end
-
(
unsigned
char
*
)
daemon
->
dhcp_packet
);
p
=
option_put
(
p
,
end
,
OPTION_MAXMESSAGE
,
2
,
end
-
(
unsigned
char
*
)
daemon
->
dhcp_packet
);
...
@@ -877,8 +912,7 @@ static unsigned char *do_req_options(struct dhcp_context *context,
...
@@ -877,8 +912,7 @@ static unsigned char *do_req_options(struct dhcp_context *context,
if
(
opt
->
opt
==
OPTION_HOSTNAME
||
if
(
opt
->
opt
==
OPTION_HOSTNAME
||
opt
->
opt
==
OPTION_MAXMESSAGE
||
opt
->
opt
==
OPTION_MAXMESSAGE
||
!
in_list
(
req_options
,
opt
->
opt
)
||
!
in_list
(
req_options
,
opt
->
opt
)
||
opt
!=
option_find2
(
netid
,
config_opts
,
opt
->
opt
)
||
opt
!=
option_find2
(
netid
,
config_opts
,
opt
->
opt
))
p
+
opt
->
len
+
3
>=
end
)
continue
;
continue
;
/* For the options we have default values on
/* For the options we have default values on
...
@@ -891,31 +925,53 @@ static unsigned char *do_req_options(struct dhcp_context *context,
...
@@ -891,31 +925,53 @@ static unsigned char *do_req_options(struct dhcp_context *context,
opt
->
opt
==
OPTION_DNSSERVER
))
opt
->
opt
==
OPTION_DNSSERVER
))
continue
;
continue
;
*
(
p
++
)
=
opt
->
opt
;
/* opt->val has terminating zero */
*
(
p
++
)
=
opt
->
len
;
if
(
opt
->
opt
==
OPTION_VENDOR_ID
)
if
(
opt
->
len
==
0
)
vendor_class
=
opt
->
val
;
continue
;
else
p
=
do_opt
(
opt
,
p
,
end
,
context
->
local
);
}
if
(
opt
->
is_addr
)
if
(
in_list
(
req_options
,
OPTION_VENDOR_ID
)
)
{
{
int
j
;
for
(
opt
=
daemon
->
vendor_opts
;
opt
;
opt
=
opt
->
next
)
struct
in_addr
*
a
=
(
struct
in_addr
*
)
opt
->
val
;
if
(
!
opt
->
netid
||
match_netid
(
opt
->
netid
,
netid
))
for
(
j
=
0
;
j
<
opt
->
len
;
j
+=
INADDRSZ
,
a
++
)
{
{
/* zero means "self" */
if
(
vendor_class
&&
strcmp
(
vendor_class
,
opt
->
vendor_class
)
!=
0
)
if
(
a
->
s_addr
==
0
)
syslog
(
LOG_WARNING
,
"More than one vendor class matches, using %s"
,
vendor_class
);
memcpy
(
p
,
&
context
->
local
,
INADDRSZ
);
else
else
memcpy
(
p
,
a
,
INADDRSZ
);
vendor_class
=
opt
->
vendor_class
;
p
+=
INADDRSZ
;
}
}
}
else
if
(
vendor_class
)
{
{
memcpy
(
p
,
opt
->
val
,
opt
->
len
);
p
=
option_put_string
(
p
,
end
,
OPTION_VENDOR_ID
,
vendor_class
);
p
+=
opt
->
len
;
if
(
in_list
(
req_options
,
OPTION_VENDOR_CLASS_OPT
))
{
unsigned
char
*
plen
,
*
oend
=
end
;
/* encapsulated options can only be 256 bytes,
even of the packet is larger */
if
(
p
+
256
<
end
)
oend
=
p
+
256
;
if
(
p
+
3
>=
oend
)
return
p
;
*
(
p
++
)
=
OPTION_VENDOR_CLASS_OPT
;
plen
=
p
++
;
/* fill in later */
for
(
opt
=
daemon
->
vendor_opts
;
opt
;
opt
=
opt
->
next
)
if
((
!
opt
->
netid
||
match_netid
(
opt
->
netid
,
netid
))
&&
strcmp
(
vendor_class
,
opt
->
vendor_class
)
==
0
)
p
=
do_opt
(
opt
,
p
,
oend
,
context
->
local
);
*
plen
=
p
-
plen
-
1
;
}
}
}
}
}
return
p
;
return
p
;
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment