Skip to content

Commit 9480465

Browse files
committed
pf: Remove dead code in pf_pull_hdr().
pf_pull_hdr() allows to pass an action pointer parameter as output value. This is never used, all callers pass a NULL argument. Remove ACTION_SET() entirely. The logic (fragoff >= len) in pf_pull_hdr() does not work since revision 1.4. Before it was used to drop short TCP or UDP fragments that contained only part of the header. Current code in pf_pull_hdr() drops the packets anyway, so always set reason PFRES_FRAG. OK kn@ sashan@ Obtained from: OpenBSD, bluhm <[email protected]>, 46650f23db Sponsored by: Rubicon Communications, LLC ("Netgate")
1 parent c3d5387 commit 9480465

File tree

4 files changed

+42
-48
lines changed

4 files changed

+42
-48
lines changed

sys/net/pfvar.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2423,7 +2423,7 @@ int pf_multihome_scan_init(int, int, struct pf_pdesc *);
24232423
int pf_multihome_scan_asconf(int, int, struct pf_pdesc *);
24242424

24252425
u_int32_t pf_new_isn(struct pf_kstate *);
2426-
void *pf_pull_hdr(const struct mbuf *, int, void *, int, u_short *, u_short *,
2426+
void *pf_pull_hdr(const struct mbuf *, int, void *, int, u_short *,
24272427
sa_family_t);
24282428
void pf_change_a(void *, u_int16_t *, u_int32_t, u_int8_t);
24292429
void pf_change_proto_a(struct mbuf *, void *, u_int16_t *, u_int32_t,

sys/netpfil/pf/pf.c

Lines changed: 34 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1676,7 +1676,7 @@ pf_state_key_addr_setup(struct pf_pdesc *pd,
16761676
if (multi)
16771677
return (-1);
16781678
if (!pf_pull_hdr(pd->m, pd->off, &nd, sizeof(nd), NULL,
1679-
NULL, pd->af))
1679+
pd->af))
16801680
return (-1);
16811681
target = (struct pf_addr *)&nd.nd_ns_target;
16821682
daddr = target;
@@ -1685,7 +1685,7 @@ pf_state_key_addr_setup(struct pf_pdesc *pd,
16851685
if (multi)
16861686
return (-1);
16871687
if (!pf_pull_hdr(pd->m, pd->off, &nd, sizeof(nd), NULL,
1688-
NULL, pd->af))
1688+
pd->af))
16891689
return (-1);
16901690
target = (struct pf_addr *)&nd.nd_ns_target;
16911691
saddr = target;
@@ -4044,7 +4044,7 @@ pf_modulate_sack(struct pf_pdesc *pd, struct tcphdr *th,
40444044
optsoff = pd->off + sizeof(struct tcphdr);
40454045
#define TCPOLEN_MINSACK (TCPOLEN_SACK + 2)
40464046
if (olen < TCPOLEN_MINSACK ||
4047-
!pf_pull_hdr(pd->m, optsoff, opts, olen, NULL, NULL, pd->af))
4047+
!pf_pull_hdr(pd->m, optsoff, opts, olen, NULL, pd->af))
40484048
return (0);
40494049

40504050
eoh = opts + olen;
@@ -5107,7 +5107,7 @@ pf_get_wscale(struct pf_pdesc *pd)
51075107

51085108
olen = (pd->hdr.tcp.th_off << 2) - sizeof(struct tcphdr);
51095109
if (olen < TCPOLEN_WINDOW || !pf_pull_hdr(pd->m,
5110-
pd->off + sizeof(struct tcphdr), opts, olen, NULL, NULL, pd->af))
5110+
pd->off + sizeof(struct tcphdr), opts, olen, NULL, pd->af))
51115111
return (0);
51125112

51135113
opt = opts;
@@ -5132,7 +5132,7 @@ pf_get_mss(struct pf_pdesc *pd)
51325132

51335133
olen = (pd->hdr.tcp.th_off << 2) - sizeof(struct tcphdr);
51345134
if (olen < TCPOLEN_MAXSEG || !pf_pull_hdr(pd->m,
5135-
pd->off + sizeof(struct tcphdr), opts, olen, NULL, NULL, pd->af))
5135+
pd->off + sizeof(struct tcphdr), opts, olen, NULL, pd->af))
51365136
return (0);
51375137

51385138
opt = opts;
@@ -7660,7 +7660,7 @@ pf_multihome_scan(int start, int len, struct pf_pdesc *pd, int op)
76607660
while (off < len) {
76617661
struct sctp_paramhdr h;
76627662

7663-
if (!pf_pull_hdr(pd->m, start + off, &h, sizeof(h), NULL, NULL,
7663+
if (!pf_pull_hdr(pd->m, start + off, &h, sizeof(h), NULL,
76647664
pd->af))
76657665
return (PF_DROP);
76667666

@@ -7680,7 +7680,7 @@ pf_multihome_scan(int start, int len, struct pf_pdesc *pd, int op)
76807680
return (PF_DROP);
76817681

76827682
if (!pf_pull_hdr(pd->m, start + off + sizeof(h), &t, sizeof(t),
7683-
NULL, NULL, pd->af))
7683+
NULL, pd->af))
76847684
return (PF_DROP);
76857685

76867686
if (in_nullhost(t))
@@ -7724,7 +7724,7 @@ pf_multihome_scan(int start, int len, struct pf_pdesc *pd, int op)
77247724
return (PF_DROP);
77257725

77267726
if (!pf_pull_hdr(pd->m, start + off + sizeof(h), &t, sizeof(t),
7727-
NULL, NULL, pd->af))
7727+
NULL, pd->af))
77287728
return (PF_DROP);
77297729
if (memcmp(&t, &pd->src->v6, sizeof(t)) == 0)
77307730
break;
@@ -7754,7 +7754,7 @@ pf_multihome_scan(int start, int len, struct pf_pdesc *pd, int op)
77547754
struct sctp_asconf_paramhdr ah;
77557755

77567756
if (!pf_pull_hdr(pd->m, start + off, &ah, sizeof(ah),
7757-
NULL, NULL, pd->af))
7757+
NULL, pd->af))
77587758
return (PF_DROP);
77597759

77607760
ret = pf_multihome_scan(start + off + sizeof(ah),
@@ -7769,7 +7769,7 @@ pf_multihome_scan(int start, int len, struct pf_pdesc *pd, int op)
77697769
struct sctp_asconf_paramhdr ah;
77707770

77717771
if (!pf_pull_hdr(pd->m, start + off, &ah, sizeof(ah),
7772-
NULL, NULL, pd->af))
7772+
NULL, pd->af))
77737773
return (PF_DROP);
77747774
ret = pf_multihome_scan(start + off + sizeof(ah),
77757775
ntohs(ah.ph.param_length) - sizeof(ah), pd,
@@ -8051,7 +8051,7 @@ pf_test_state_icmp(struct pf_kstate **state, struct pf_pdesc *pd,
80518051
ipoff2 = pd->off + ICMP_MINLEN;
80528052

80538053
if (!pf_pull_hdr(pd->m, ipoff2, &h2, sizeof(h2),
8054-
NULL, reason, pd2.af)) {
8054+
reason, pd2.af)) {
80558055
DPFPRINTF(PF_DEBUG_MISC,
80568056
"pf: ICMP error message too short "
80578057
"(ip)");
@@ -8083,7 +8083,7 @@ pf_test_state_icmp(struct pf_kstate **state, struct pf_pdesc *pd,
80838083
ipoff2 = pd->off + sizeof(struct icmp6_hdr);
80848084

80858085
if (!pf_pull_hdr(pd->m, ipoff2, &h2_6, sizeof(h2_6),
8086-
NULL, reason, pd2.af)) {
8086+
reason, pd2.af)) {
80878087
DPFPRINTF(PF_DEBUG_MISC,
80888088
"pf: ICMP error message too short "
80898089
"(ip6)");
@@ -8136,7 +8136,7 @@ pf_test_state_icmp(struct pf_kstate **state, struct pf_pdesc *pd,
81368136
* expected. Don't access any TCP header fields after
81378137
* th_seq, an ackskew test is not possible.
81388138
*/
8139-
if (!pf_pull_hdr(pd->m, pd2.off, th, 8, NULL, reason,
8139+
if (!pf_pull_hdr(pd->m, pd2.off, th, 8, reason,
81408140
pd2.af)) {
81418141
DPFPRINTF(PF_DEBUG_MISC,
81428142
"pf: ICMP error message too short "
@@ -8332,7 +8332,7 @@ pf_test_state_icmp(struct pf_kstate **state, struct pf_pdesc *pd,
83328332
int action;
83338333

83348334
if (!pf_pull_hdr(pd->m, pd2.off, uh, sizeof(*uh),
8335-
NULL, reason, pd2.af)) {
8335+
reason, pd2.af)) {
83368336
DPFPRINTF(PF_DEBUG_MISC,
83378337
"pf: ICMP error message too short "
83388338
"(udp)");
@@ -8463,7 +8463,7 @@ pf_test_state_icmp(struct pf_kstate **state, struct pf_pdesc *pd,
84638463
int copyback = 0;
84648464
int action;
84658465

8466-
if (! pf_pull_hdr(pd->m, pd2.off, sh, sizeof(*sh), NULL, reason,
8466+
if (! pf_pull_hdr(pd->m, pd2.off, sh, sizeof(*sh), reason,
84678467
pd2.af)) {
84688468
DPFPRINTF(PF_DEBUG_MISC,
84698469
"pf: ICMP error message too short "
@@ -8619,7 +8619,7 @@ pf_test_state_icmp(struct pf_kstate **state, struct pf_pdesc *pd,
86198619
}
86208620

86218621
if (!pf_pull_hdr(pd->m, pd2.off, iih, ICMP_MINLEN,
8622-
NULL, reason, pd2.af)) {
8622+
reason, pd2.af)) {
86238623
DPFPRINTF(PF_DEBUG_MISC,
86248624
"pf: ICMP error message too short i"
86258625
"(icmp)");
@@ -8739,7 +8739,7 @@ pf_test_state_icmp(struct pf_kstate **state, struct pf_pdesc *pd,
87398739
}
87408740

87418741
if (!pf_pull_hdr(pd->m, pd2.off, iih,
8742-
sizeof(struct icmp6_hdr), NULL, reason, pd2.af)) {
8742+
sizeof(struct icmp6_hdr), reason, pd2.af)) {
87438743
DPFPRINTF(PF_DEBUG_MISC,
87448744
"pf: ICMP error message too short "
87458745
"(icmp6)");
@@ -8921,7 +8921,7 @@ pf_test_state_icmp(struct pf_kstate **state, struct pf_pdesc *pd,
89218921
*/
89228922
void *
89238923
pf_pull_hdr(const struct mbuf *m, int off, void *p, int len,
8924-
u_short *actionp, u_short *reasonp, sa_family_t af)
8924+
u_short *reasonp, sa_family_t af)
89258925
{
89268926
int iplen = 0;
89278927
switch (af) {
@@ -8931,12 +8931,7 @@ pf_pull_hdr(const struct mbuf *m, int off, void *p, int len,
89318931
u_int16_t fragoff = (ntohs(h->ip_off) & IP_OFFMASK) << 3;
89328932

89338933
if (fragoff) {
8934-
if (fragoff >= len)
8935-
ACTION_SET(actionp, PF_PASS);
8936-
else {
8937-
ACTION_SET(actionp, PF_DROP);
8938-
REASON_SET(reasonp, PFRES_FRAG);
8939-
}
8934+
REASON_SET(reasonp, PFRES_FRAG);
89408935
return (NULL);
89418936
}
89428937
iplen = ntohs(h->ip_len);
@@ -8953,7 +8948,6 @@ pf_pull_hdr(const struct mbuf *m, int off, void *p, int len,
89538948
#endif /* INET6 */
89548949
}
89558950
if (m->m_pkthdr.len < off + len || iplen < off + len) {
8956-
ACTION_SET(actionp, PF_DROP);
89578951
REASON_SET(reasonp, PFRES_SHORT);
89588952
return (NULL);
89598953
}
@@ -10052,7 +10046,7 @@ pf_walk_header(struct pf_pdesc *pd, struct ip *h, u_short *reason)
1005210046
end < pd->off + sizeof(ext))
1005310047
return (PF_PASS);
1005410048
if (!pf_pull_hdr(pd->m, pd->off, &ext, sizeof(ext),
10055-
NULL, reason, AF_INET)) {
10049+
reason, AF_INET)) {
1005610050
DPFPRINTF(PF_DEBUG_MISC, "IP short exthdr");
1005710051
return (PF_DROP);
1005810052
}
@@ -10078,15 +10072,15 @@ pf_walk_option6(struct pf_pdesc *pd, struct ip6_hdr *h, int off, int end,
1007810072

1007910073
while (off < end) {
1008010074
if (!pf_pull_hdr(pd->m, off, &opt.ip6o_type,
10081-
sizeof(opt.ip6o_type), NULL, reason, AF_INET6)) {
10075+
sizeof(opt.ip6o_type), reason, AF_INET6)) {
1008210076
DPFPRINTF(PF_DEBUG_MISC, "IPv6 short opt type");
1008310077
return (PF_DROP);
1008410078
}
1008510079
if (opt.ip6o_type == IP6OPT_PAD1) {
1008610080
off++;
1008710081
continue;
1008810082
}
10089-
if (!pf_pull_hdr(pd->m, off, &opt, sizeof(opt), NULL,
10083+
if (!pf_pull_hdr(pd->m, off, &opt, sizeof(opt),
1009010084
reason, AF_INET6)) {
1009110085
DPFPRINTF(PF_DEBUG_MISC, "IPv6 short opt");
1009210086
return (PF_DROP);
@@ -10111,7 +10105,7 @@ pf_walk_option6(struct pf_pdesc *pd, struct ip6_hdr *h, int off, int end,
1011110105
REASON_SET(reason, PFRES_IPOPTIONS);
1011210106
return (PF_DROP);
1011310107
}
10114-
if (!pf_pull_hdr(pd->m, off, &jumbo, sizeof(jumbo), NULL,
10108+
if (!pf_pull_hdr(pd->m, off, &jumbo, sizeof(jumbo),
1011510109
reason, AF_INET6)) {
1011610110
DPFPRINTF(PF_DEBUG_MISC, "IPv6 short jumbo");
1011710111
return (PF_DROP);
@@ -10160,7 +10154,7 @@ pf_walk_header6(struct pf_pdesc *pd, struct ip6_hdr *h, u_short *reason)
1016010154
break;
1016110155
case IPPROTO_HOPOPTS:
1016210156
if (!pf_pull_hdr(pd->m, pd->off, &ext, sizeof(ext),
10163-
NULL, reason, AF_INET6)) {
10157+
reason, AF_INET6)) {
1016410158
DPFPRINTF(PF_DEBUG_MISC, "IPv6 short exthdr");
1016510159
return (PF_DROP);
1016610160
}
@@ -10187,7 +10181,7 @@ pf_walk_header6(struct pf_pdesc *pd, struct ip6_hdr *h, u_short *reason)
1018710181
return (PF_DROP);
1018810182
}
1018910183
if (!pf_pull_hdr(pd->m, pd->off, &frag, sizeof(frag),
10190-
NULL, reason, AF_INET6)) {
10184+
reason, AF_INET6)) {
1019110185
DPFPRINTF(PF_DEBUG_MISC, "IPv6 short fragment");
1019210186
return (PF_DROP);
1019310187
}
@@ -10215,7 +10209,7 @@ pf_walk_header6(struct pf_pdesc *pd, struct ip6_hdr *h, u_short *reason)
1021510209
return (PF_PASS);
1021610210
}
1021710211
if (!pf_pull_hdr(pd->m, pd->off, &rthdr, sizeof(rthdr),
10218-
NULL, reason, AF_INET6)) {
10212+
reason, AF_INET6)) {
1021910213
DPFPRINTF(PF_DEBUG_MISC, "IPv6 short rthdr");
1022010214
return (PF_DROP);
1022110215
}
@@ -10236,7 +10230,7 @@ pf_walk_header6(struct pf_pdesc *pd, struct ip6_hdr *h, u_short *reason)
1023610230
case IPPROTO_AH:
1023710231
case IPPROTO_DSTOPTS:
1023810232
if (!pf_pull_hdr(pd->m, pd->off, &ext, sizeof(ext),
10239-
NULL, reason, AF_INET6)) {
10233+
reason, AF_INET6)) {
1024010234
DPFPRINTF(PF_DEBUG_MISC, "IPv6 short exthdr");
1024110235
return (PF_DROP);
1024210236
}
@@ -10269,7 +10263,7 @@ pf_walk_header6(struct pf_pdesc *pd, struct ip6_hdr *h, u_short *reason)
1026910263
return (PF_PASS);
1027010264
}
1027110265
if (!pf_pull_hdr(pd->m, pd->off, &icmp6, sizeof(icmp6),
10272-
NULL, reason, AF_INET6)) {
10266+
reason, AF_INET6)) {
1027310267
DPFPRINTF(PF_DEBUG_MISC,
1027410268
"IPv6 short icmp6hdr");
1027510269
return (PF_DROP);
@@ -10502,7 +10496,7 @@ pf_setup_pdesc(sa_family_t af, int dir, struct pf_pdesc *pd, struct mbuf **m0,
1050210496
case IPPROTO_TCP: {
1050310497
struct tcphdr *th = &pd->hdr.tcp;
1050410498

10505-
if (!pf_pull_hdr(pd->m, pd->off, th, sizeof(*th), action,
10499+
if (!pf_pull_hdr(pd->m, pd->off, th, sizeof(*th),
1050610500
reason, af)) {
1050710501
*action = PF_DROP;
1050810502
REASON_SET(reason, PFRES_SHORT);
@@ -10518,7 +10512,7 @@ pf_setup_pdesc(sa_family_t af, int dir, struct pf_pdesc *pd, struct mbuf **m0,
1051810512
case IPPROTO_UDP: {
1051910513
struct udphdr *uh = &pd->hdr.udp;
1052010514

10521-
if (!pf_pull_hdr(pd->m, pd->off, uh, sizeof(*uh), action,
10515+
if (!pf_pull_hdr(pd->m, pd->off, uh, sizeof(*uh),
1052210516
reason, af)) {
1052310517
*action = PF_DROP;
1052410518
REASON_SET(reason, PFRES_SHORT);
@@ -10539,7 +10533,7 @@ pf_setup_pdesc(sa_family_t af, int dir, struct pf_pdesc *pd, struct mbuf **m0,
1053910533
}
1054010534
case IPPROTO_SCTP: {
1054110535
if (!pf_pull_hdr(pd->m, pd->off, &pd->hdr.sctp, sizeof(pd->hdr.sctp),
10542-
action, reason, af)) {
10536+
reason, af)) {
1054310537
*action = PF_DROP;
1054410538
REASON_SET(reason, PFRES_SHORT);
1054510539
return (-1);
@@ -10569,7 +10563,7 @@ pf_setup_pdesc(sa_family_t af, int dir, struct pf_pdesc *pd, struct mbuf **m0,
1056910563
}
1057010564
case IPPROTO_ICMP: {
1057110565
if (!pf_pull_hdr(pd->m, pd->off, &pd->hdr.icmp, ICMP_MINLEN,
10572-
action, reason, af)) {
10566+
reason, af)) {
1057310567
*action = PF_DROP;
1057410568
REASON_SET(reason, PFRES_SHORT);
1057510569
return (-1);
@@ -10583,7 +10577,7 @@ pf_setup_pdesc(sa_family_t af, int dir, struct pf_pdesc *pd, struct mbuf **m0,
1058310577
size_t icmp_hlen = sizeof(struct icmp6_hdr);
1058410578

1058510579
if (!pf_pull_hdr(pd->m, pd->off, &pd->hdr.icmp6, icmp_hlen,
10586-
action, reason, af)) {
10580+
reason, af)) {
1058710581
*action = PF_DROP;
1058810582
REASON_SET(reason, PFRES_SHORT);
1058910583
return (-1);
@@ -10609,7 +10603,7 @@ pf_setup_pdesc(sa_family_t af, int dir, struct pf_pdesc *pd, struct mbuf **m0,
1060910603
}
1061010604
if (icmp_hlen > sizeof(struct icmp6_hdr) &&
1061110605
!pf_pull_hdr(pd->m, pd->off, &pd->hdr.icmp6, icmp_hlen,
10612-
action, reason, af)) {
10606+
reason, af)) {
1061310607
*action = PF_DROP;
1061410608
REASON_SET(reason, PFRES_SHORT);
1061510609
return (-1);

sys/netpfil/pf/pf_norm.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1354,7 +1354,7 @@ pf_normalize_ip6(int off, u_short *reason,
13541354
pf_rule_to_actions(r, &pd->act);
13551355
}
13561356

1357-
if (!pf_pull_hdr(pd->m, off, &frag, sizeof(frag), NULL, reason, AF_INET6))
1357+
if (!pf_pull_hdr(pd->m, off, &frag, sizeof(frag), reason, AF_INET6))
13581358
return (PF_DROP);
13591359

13601360
/* Offset now points to data portion. */
@@ -1542,7 +1542,7 @@ pf_normalize_tcp_init(struct pf_pdesc *pd, struct tcphdr *th,
15421542

15431543
olen = (th->th_off << 2) - sizeof(*th);
15441544
if (olen < TCPOLEN_TIMESTAMP || !pf_pull_hdr(pd->m,
1545-
pd->off + sizeof(*th), opts, olen, NULL, NULL, pd->af))
1545+
pd->off + sizeof(*th), opts, olen, NULL, pd->af))
15461546
return (0);
15471547

15481548
opt = opts;
@@ -1645,7 +1645,7 @@ pf_normalize_tcp_stateful(struct pf_pdesc *pd,
16451645
if (olen >= TCPOLEN_TIMESTAMP &&
16461646
((src->scrub && (src->scrub->pfss_flags & PFSS_TIMESTAMP)) ||
16471647
(dst->scrub && (dst->scrub->pfss_flags & PFSS_TIMESTAMP))) &&
1648-
pf_pull_hdr(pd->m, pd->off + sizeof(*th), opts, olen, NULL, NULL, pd->af)) {
1648+
pf_pull_hdr(pd->m, pd->off + sizeof(*th), opts, olen, NULL, pd->af)) {
16491649
/* Modulate the timestamps. Can be used for NAT detection, OS
16501650
* uptime determination or reboot detection.
16511651
*/
@@ -1975,7 +1975,7 @@ pf_normalize_mss(struct pf_pdesc *pd)
19751975
olen = (pd->hdr.tcp.th_off << 2) - sizeof(struct tcphdr);
19761976
optsoff = pd->off + sizeof(struct tcphdr);
19771977
if (olen < TCPOLEN_MAXSEG ||
1978-
!pf_pull_hdr(pd->m, optsoff, opts, olen, NULL, NULL, pd->af))
1978+
!pf_pull_hdr(pd->m, optsoff, opts, olen, NULL, pd->af))
19791979
return (0);
19801980

19811981
opt = opts;
@@ -2009,7 +2009,7 @@ pf_scan_sctp(struct pf_pdesc *pd)
20092009
int ret;
20102010

20112011
while (pd->off + chunk_off < pd->tot_len) {
2012-
if (!pf_pull_hdr(pd->m, pd->off + chunk_off, &ch, sizeof(ch), NULL,
2012+
if (!pf_pull_hdr(pd->m, pd->off + chunk_off, &ch, sizeof(ch),
20132013
NULL, pd->af))
20142014
return (PF_DROP);
20152015

@@ -2026,7 +2026,7 @@ pf_scan_sctp(struct pf_pdesc *pd)
20262026
struct sctp_init_chunk init;
20272027

20282028
if (!pf_pull_hdr(pd->m, pd->off + chunk_start, &init,
2029-
sizeof(init), NULL, NULL, pd->af))
2029+
sizeof(init), NULL, pd->af))
20302030
return (PF_DROP);
20312031

20322032
/*

sys/netpfil/pf/pf_osfp.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ pf_osfp_fingerprint(struct pf_pdesc *pd, const struct tcphdr *tcp)
8282
ip6 = mtod(pd->m, struct ip6_hdr *);
8383
break;
8484
}
85-
if (!pf_pull_hdr(pd->m, pd->off, hdr, tcp->th_off << 2, NULL, NULL,
85+
if (!pf_pull_hdr(pd->m, pd->off, hdr, tcp->th_off << 2, NULL,
8686
pd->af)) return (NULL);
8787

8888
return (pf_osfp_fingerprint_hdr(ip, ip6, (struct tcphdr *)hdr));

0 commit comments

Comments
 (0)