Re: Fan Management Framework
Hi Marcus, Sounds interesting! I don't know if you've seen it, but I did a similar patchset back in the day, alas for the common PC desktops with the lm(4) sensors; http://sensors.cnst.su/fanctl/ . However, there hasn't been as much interest in fan control on OpenBSD as I had initially expected when I got into the sensors in the mid-noughties; and nowadays with cloud computing and cheap laptops, netbooks and embedded ARM with automatic fan control and passive cooling, there are easier options for Quiet Computing than using a desktop with an lm(4) chip and active cooling. I also got the impression that fan control is incompatible with OpenBSD philosophy where system stability and ease-of-use is preferred to having lots of configuration options, especially those where you can allegedly shoot yourself in the foot, so, per my understanding, sadly, noone else was particularly interested in having a generic fan control interface merged into the tree. On a more practical point, there's a variation between the different devices on how to set fan control; for example, the asmc(4) patch you have lets you set a min/max RPM, some wbsio(4)/lm(4) chips let you set a target fan-speed and/or target temperature cruise (personally, I think the target temperature cruise makes the most sense for fan control), other lm(4) chips only let you set PWM duty cycle directly (thus any form of cruise would then have to be implemented in software, which would be less reliable and much more prone to overheating should any of the software components crash), and ThinkPad ACPI simply has levels between 0 and 7 or "8". I've implemented access to most of these hardware fan control features of wbsio(4) / lm(4) in my patch just on top of the sensors framework -- http://sensors.cnst.su/fanctl/ -- and I think it should be pretty intuitive to use and understand if you do care about lm(4)-based fan control. However, these variations in control options are probably the reason why many third-party tools like SpeedFan on Windows have only implemented the most basic PWM duty cycle support for each chip on a hardware level, and instead rely on having the software perform the monitoring/control loop for things like temperature cruise, even where the underlying chips are capable of doing it themselves autonomously (after first being programmed by the software), because this way the user interface and experience is more clear and consistent across the board (at the cost of reduced reliability if SpeedFan app or Windows OS crash). I'd imagine these variations, together with fan control being deemed optional by many developers, make it a somewhat hard sell for integration in base, which is kind of sad, because all those autonomous temperature cruise options in Winbond's lm(4) chips are pretty neat, and something that I'd wish modern laptops would actually offer in any way (as most of today's laptops -- including Apple MacBook macOS ones -- are completely unusable on the lap due to the terrible thermal profiles and a seeming lack of temperature-based control options for their active cooling components). Cheers, Constantine. On Fri, 27 Nov 2020 at 09:08, Marcus Glocker wrote: > > Hi, > > I recently decided to replace MacOSX on my iMac11,3 27" with OpenBSD. > During the MacOSX times I had to replace the broken HDD with a new SSD. > The new SSD didn't offer pins to attach the sensor cable back, which > was previously attached to the HDD, so I left it loose. This caused > the HDD fan to spin up to maximum over time. On MacOSX there are some > fan control programs with which I could control the fan speed. I > almost forgot about that "fix" over time, but installing OpenBSD on > that machine remembered me of it - You can't overhear it :-) > > That made me play around with asmc(4), where I noticed you can not > only read the fan properties, but also set them. I initially was > thinking to make sysctl(8) able to set fan speeds, but what I could > see is that the fan framework there seems to be designed to read > only. Instead of poking around further in sysctl(8), I had the idea > to create a small fan(4) framework layer, which can be controlled > through a device by using a fanctl(8) user-land program. > > I don't know if there are other fan sensor controllers which would > allow fan properties control. If yes, they potentially could attach > to the same fan framework. If not, the fan framework probably doesn't > make much sense only to be used by asmc(4). > > Some example: > > ... > asmc0 at acpi0: SMC_ (smc-piketon) addr 0x300/0x20: rev 1.59f559, 297 > keys > fan0 at asmc0 > ... > > bigmac# sysctl | grep fan > hw.sensors.asmc0.fan0=998 RPM (ODD, right mid rear) > hw.sensors.asmc0.fan1=3677 RPM (HDD, center mid rear) > hw.sensors.asmc0.fan2=939 RPM (CPU, left lower rear) > > bigmac# ./fanctl > driver=asmc0 > fan0.id=ODD, right mid rear > fan0.a
Re: ipmi(4): ipmi_poll_thread(): tsleep(9) -> tsleep_nsec(9)
Not sure if you've seen it, but ipmi(4) has been disabled for over 12 years, because it's broken on some machines, so, this code is not necessarily guaranteed to be correct as-is. http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/arch/i386/conf/GENERIC#rev1.632 http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/arch/amd64/conf/GENERIC#rev1.238 C. On Wed, 2 Dec 2020 at 12:36, Scott Cheloha wrote: > Hi, > > ipmi(4) is one of the few remaining callers of tsleep(9). I want to > convert it to use tsleep_nsec(9) but I need some clarification on what > the code in question is doing. > > In ipmi_poll_thread() we initialize all the sensors in a loop. > Between each get_sdr() call we tsleep(9) for 1 tick. > > So, I wonder: > > 1. Why do we sleep here? Is get_sdr() slow and we don't want to >hog the CPU? We block for a tick to let other stuff run? Or >is there some other reason? > > 2. Why are we spinning until tsleep(9) returns EWOULDBLOCK? Can >another thread interrupt the sleep with a wakeup(9)? > > marco@ added the tsleep(9) loop in this commit: > > > http://cvsweb.openbsd.org/src/sys/dev/ipmi.c?rev=1.59&content-type=text/x-cvsweb-markup > > Any ideas? > > My guess is that the attached diff will work fine but if we could > remove the loop while we're here that would simplify the code. > > Index: ipmi.c > === > RCS file: /cvs/src/sys/dev/ipmi.c,v > retrieving revision 1.112 > diff -u -p -r1.112 ipmi.c > --- ipmi.c 29 Mar 2020 09:31:10 - 1.112 > +++ ipmi.c 2 Dec 2020 20:31:57 - > @@ -1497,7 +1497,8 @@ ipmi_poll_thread(void *arg) > printf("%s: no SDRs IPMI disabled\n", DEVNAME(sc)); > goto done; > } > - while (tsleep(sc, PWAIT, "ipmirun", 1) != EWOULDBLOCK) > + while (tsleep_nsec(sc, PWAIT, "ipmirun", > + MSEC_TO_NSEC(1)) != EWOULDBLOCK) > continue; > } > > >
Re: sensors hiding with pledge
Wouldn't this break sensorsd? (It's already been converted to use pledge.) C. On Mon, 21 Jan 2019 at 20:19, Ted Unangst wrote: > > We recently had a thread about adding more sensors, but then the browser will > use them to spy on us, and everybody was sad. We allow hw.sensors even for > pledge processes because ntpd needs to read the time. However, ntpd only needs > to read the time. > > This diff zeroes out sensors other than timedeltas. Maybe some others can be > added as needed, but that seemed a good place to start. I didn't want to > change the code too much (i.e. hide the existence of sensors entirely) so it > just changes them all to 0 valued plain integer sensors. > > Thoughts? > > Index: kern_sysctl.c > === > RCS file: /cvs/src/sys/kern/kern_sysctl.c,v > retrieving revision 1.353 > diff -u -p -r1.353 kern_sysctl.c > --- kern_sysctl.c 19 Jan 2019 01:53:44 - 1.353 > +++ kern_sysctl.c 22 Jan 2019 02:01:30 - > @@ -137,7 +137,7 @@ int sysctl_proc_nobroadcastkill(int *, u > struct proc *); > int sysctl_proc_vmmap(int *, u_int, void *, size_t *, struct proc *); > int sysctl_intrcnt(int *, u_int, void *, size_t *); > -int sysctl_sensors(int *, u_int, void *, size_t *, void *, size_t); > +int sysctl_sensors(int *, u_int, void *, size_t *, void *, size_t, struct > proc *); > int sysctl_cptime2(int *, u_int, void *, size_t *, void *, size_t); > #if NAUDIO > 0 > int sysctl_audio(int *, u_int, void *, size_t *, void *, size_t); > @@ -735,7 +735,7 @@ hw_sysctl(int *name, u_int namelen, void > #ifndefSMALL_KERNEL > case HW_SENSORS: > return (sysctl_sensors(name + 1, namelen - 1, oldp, oldlenp, > - newp, newlen)); > + newp, newlen, p)); > case HW_SETPERF: > return (sysctl_hwsetperf(oldp, oldlenp, newp, newlen)); > case HW_PERFPOLICY: > @@ -2302,7 +2302,7 @@ sysctl_intrcnt(int *name, u_int namelen, > > int > sysctl_sensors(int *name, u_int namelen, void *oldp, size_t *oldlenp, > -void *newp, size_t newlen) > +void *newp, size_t newlen, struct proc *p) > { > struct ksensor *ks; > struct sensor *us; > @@ -2350,6 +2350,22 @@ sysctl_sensors(int *name, u_int namelen, > us->status = ks->status; > us->numt = ks->numt; > us->flags = ks->flags; > + > + /* not all sensors exposed to pledged processes */ > + if (p->p_p->ps_flags & PS_PLEDGE) { > + switch (us->type) { > + case SENSOR_TIMEDELTA: > + break; > + default: > + memset(us->desc, 0, sizeof(us->desc)); > + memset(&us->tv, 0, sizeof(us->tv)); > + us->value = 0; > + us->type = SENSOR_INTEGER; > + us->status = SENSOR_S_UNKNOWN; > + us->flags = SENSOR_FUNKNOWN; > + break; > + } > + } > > ret = sysctl_rdstruct(oldp, oldlenp, newp, us, > sizeof(struct sensor)); >
Re: Removing PF
On 2019-W14-1 19:12 -0700, Jordan Geoghegan wrote: > Realistically, we need to move to the one true firewall-- iptables! > Ideally, OpenBSD needs a firewall thats 'web scale' that can be > administered from a PHP web based frontend that uses JSON message > passing for clustering and failover. Don't forget about sharding -- we should probably use MongoDB for a pfsync(4) replacement. C.
sysctl hw.sensors lm(4) fan-controlling prototype/hack
1.14 +++ sys/dev/ic/lm78var.h8 May 2009 18:47:09 - @@ -118,17 +118,17 @@ /* Config bits */ #define WB_CONFIG_VMR9 0x01 /* Reference voltage (mV) */ #define WB_VREF3600 #define WB_W83627EHF_VREF 2048 -#define WB_MAX_SENSORS 19 +#define WB_MAX_SENSORS 96 struct lm_softc; struct lm_sensor { char *desc; enum sensor_type type; u_int8_t bank; u_int8_t reg; Index: sys/dev/ic/lm78.c === RCS file: /cvs/src/sys/dev/ic/lm78.c,v retrieving revision 1.20 diff -u -d -p -8 -r1.20 lm78.c --- sys/dev/ic/lm78.c 25 Jun 2007 22:50:18 -0000 1.20 +++ sys/dev/ic/lm78.c 8 May 2009 18:47:10 - @@ -1,12 +1,13 @@ /* $OpenBSD: lm78.c,v 1.20 2007/06/25 22:50:18 cnst Exp $ */ /* * Copyright (c) 2005, 2006 Mark Kettenis + * Copyright (c) 2006, 2009 Constantine A. Murenin * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR @@ -21,16 +22,20 @@ #include #include #include #include #include #include +//#define LMFANCTLRAW +#define LMFANDUTYHINTS +/* or use `rm lm78.o; env DEBUG="-DLMFANCTLRAW -DLMFANDUTYHINTS" make lm78.o` */ + #if defined(LMDEBUG) #define DPRINTF(x) do { printf x; } while (0) #else #define DPRINTF(x) #endif /* * LM78-compatible chips can typically measure voltages up to 4.096 V. @@ -55,16 +60,24 @@ void lm_setup_sensors(struct lm_softc *, void lm_refresh(void *); void lm_refresh_sensor_data(struct lm_softc *); void lm_refresh_volt(struct lm_softc *, int); void lm_refresh_temp(struct lm_softc *, int); void lm_refresh_fanrpm(struct lm_softc *, int); void wb_refresh_sensor_data(struct lm_softc *); +void wb_refresh_raw_rw(struct lm_softc *, int); +void w83627hf_refresh_pwm_rw(struct lm_softc *, int); +void w83627ehf_refresh_fanvolt_rw(struct lm_softc *, int); +void w83627ehf_refresh_fanvolt_thermal_rw(struct lm_softc *, int); +void w83627ehf_refresh_indicator_rw(struct lm_softc *, int); +void w83627ehf_refresh_temptarget_rw(struct lm_softc *, int); +void w83627ehf_refresh_temptargettol_rw(struct lm_softc *, int); +void w83627thf_refresh_fanvolt_rw(struct lm_softc *, int); void wb_w83637hf_refresh_vcore(struct lm_softc *, int); void wb_refresh_nvolt(struct lm_softc *, int); void wb_w83627ehf_refresh_nvolt(struct lm_softc *, int); void wb_refresh_temp(struct lm_softc *, int); void wb_refresh_fanrpm(struct lm_softc *, int); void wb_w83792d_refresh_fanrpm(struct lm_softc *, int); void as_refresh_temp(struct lm_softc *, int); @@ -95,17 +108,23 @@ struct lm_sensor lm78_sensors[] = { /* Fans */ { "", SENSOR_FANRPM, 0, 0x28, lm_refresh_fanrpm }, { "", SENSOR_FANRPM, 0, 0x29, lm_refresh_fanrpm }, { "", SENSOR_FANRPM, 0, 0x2a, lm_refresh_fanrpm }, { NULL } }; + struct lm_sensor w83627hf_sensors[] = { + /* The W83627HG only support the manual PWM fan speed control. */ + { "PWM", SENSOR_PERCENT, 0, 0x5a, w83627hf_refresh_pwm_rw }, + { "PWM", SENSOR_PERCENT, 0, 0x5b, w83627hf_refresh_pwm_rw }, + { "PWM 0/1 Clock Freq", SENSOR_INTEGER, 0, 0x5c, wb_refresh_raw_rw }, + /* Voltage */ { "VCore A", SENSOR_VOLTS_DC, 0, 0x20, lm_refresh_volt, RFACT_NONE }, { "VCore B", SENSOR_VOLTS_DC, 0, 0x21, lm_refresh_volt, RFACT_NONE }, { "+3.3V", SENSOR_VOLTS_DC, 0, 0x22, lm_refresh_volt, RFACT_NONE }, { "+5V", SENSOR_VOLTS_DC, 0, 0x23, lm_refresh_volt, RFACT(34, 50) }, { "+12V", SENSOR_VOLTS_DC, 0, 0x24, lm_refresh_volt, RFACT(28, 10) }, { "-12V", SENSOR_VOLTS_DC, 0, 0x25, wb_refresh_nvolt, RFACT(232, 56) }, { "-5V", SENSOR_VOLTS_DC, 0, 0x26, wb_refresh_nvolt, RFACT(120, 56) }, @@ -128,93 +147,342 @@ struct lm_sensor w83627hf_sensors[] = { /* * The W83627EHF can measure voltages up to 2.048 V instead of the * traditional 4.096 V. For measuring positive voltages, this can be * accounted for by halving the resistor factor. Negative voltages * need special treatment, also because the reference voltage is 2.048 V * instead of the traditional 3.6 V. */ struct lm_sensor w83627ehf_sensors[] = { + /* Controlling parts: Duty Cycle */ + { "Sys Fan Volt Control", SENSOR_PERCENT, 0, 0x01, w83627ehf_refresh_fanvolt_rw }, + { "CPU Fan Volt Control", SENSOR_PERCENT, 0, 0x03, w83627ehf_refresh_fanvolt_rw }, +
hptd(4): HP 3D DriveGuard accelerometer support / lisa(4) through ACPI
pi/hp3d.c --- /dev/null 1 Jan 1970 00:00:00 - +++ dev/acpi/hp3d.c 29 Aug 2009 16:32:08 - @@ -0,0 +1,145 @@ +/* $OpenBSD: atk0110.c,v 1.1 2009/07/23 01:38:16 cnst Exp $*/ + +/* + * Copyright (c) 2009 Constantine A. Murenin + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +/* + * HP 3D DriveGuard accelerometer support. + */ + +struct hp3d_softc { + struct device sc_dev; + + struct acpi_softc *sc_acpi; + struct aml_node *sc_alrd; + + struct i2c_controller sc_ic; +}; + +inthp3d_match(struct device *, void *, void *); +void hp3d_attach(struct device *, struct device *, void *); + +inthp3d_i2c_acquire_bus(void *, int); +void hp3d_i2c_release_bus(void *, int); +inthp3d_i2c_exec(void *, i2c_op_t, i2c_addr_t, +const void *, size_t, void *, size_t, int); + +struct cfattach hptd_ca = { + sizeof(struct hp3d_softc), hp3d_match, hp3d_attach +}; + +struct cfdriver hptd_cd = { + NULL, "hptd", DV_DULL +}; + +static const char* hp3d_hids[] = { + ACPI_DEV_HPACEL, + NULL +}; + +int +hp3d_match(struct device *parent, void *match, void *aux) +{ + struct acpi_attach_args *aa = aux; + struct cfdata *cf = match; + + return acpi_matchhids(aa, hp3d_hids, cf->cf_driver->cd_name); +} + +void +hp3d_attach(struct device *parent, struct device *self, void *aux) +{ + struct hp3d_softc *sc = (struct hp3d_softc *)self; + struct acpi_attach_args *aa = aux; + struct i2c_attach_args ia; + + sc->sc_acpi = (struct acpi_softc *)parent; + sc->sc_alrd = aml_searchname(aa->aaa_node, "ALRD"); + if (sc->sc_alrd == NULL || sc->sc_alrd->value == NULL || + sc->sc_alrd->value->type != AML_OBJTYPE_METHOD) { + printf(": ALRD method node not found\n"); + return; + } + printf("\n"); + + sc->sc_ic.ic_cookie = sc; + sc->sc_ic.ic_acquire_bus = hp3d_i2c_acquire_bus; + sc->sc_ic.ic_release_bus = hp3d_i2c_release_bus; + sc->sc_ic.ic_exec = hp3d_i2c_exec; + + bzero(&ia, sizeof ia); + ia.ia_tag = &sc->sc_ic; + ia.ia_name = "hp3d"; + config_found(self, &ia, NULL); +} + +int +hp3d_i2c_acquire_bus(void *cookie, int flags) +{ + return 0; +} + +void +hp3d_i2c_release_bus(void *cookie, int flags) +{ +} + +int +hp3d_i2c_exec(void *cookie, i2c_op_t op, i2c_addr_t addr, +const void *cmdbuf, size_t cmdlen, void *buf, size_t len, int flags) +{ + struct hp3d_softc *sc = cookie; + int8_t c = *(int8_t *)cmdbuf; + uint8_t *b = buf; + struct aml_valuereq, res; + + if (op != I2C_OP_READ_WITH_STOP || cmdlen != 1 || len != 1) + return 1; + + req.type = AML_OBJTYPE_INTEGER; + req.v_integer = c; + if (aml_evalnode(sc->sc_acpi, sc->sc_alrd, 1, &req, &res)) { + dprintf("%s: ALRD %hhi evaluation failed\n", + DEVNAME(sc), c); + *b = 0; + aml_freevalue(&res); + return 1; + } + if (res.type != AML_OBJTYPE_INTEGER) { + dprintf("%s: ALRD %hhi: not an integer: type %i\n", + DEVNAME(sc), c, res.type); + *b = 0; + aml_freevalue(&res); + return 1; + } + *b = res.v_integer; + aml_freevalue(&res); + return 0; +} Index: dev/i2c/lis331dl.c === RCS file: /share/OpenBSD/cvs/src/sys/dev/i2c/lis331dl.c,v retrieving revision 1.1 diff -u -d -p -4 -r1.1 lis331dl.c --- dev/i2c/lis331dl.c 12 Aug 2009 14:51:20 - 1.1 +++ dev/i2c/lis331dl.c 29 Aug 2009 16:32:08 - @@ -72,9 +72,10 @@ int lisa_match(struct device *parent, void *match, void *aux) { struct i2c_attach_args *ia = aux; - if (strcmp(ia->ia_name, "lis331dl") == 0) + if (strcmp(ia-
Re: libtls documentation
On 20 February 2015 at 10:36, Greg Martin wrote: > Hi, > I just build libressl on Linux 3.13.0-44-generic. I haven't installed it > yet but it was a clean build. > > I'm interested in trying libssl but the only documentation I've found is > a single manpage (tls_int). Are there some example programs somewhere or > more comprehensive documentation? > > Thanks, > Greg Martin. Hello, Isn't tls_init(3) quite comprehensive as is? http://mdoc.su/o/tls_init.3 If want some concrete examples of how libressl and tls_init(3) can be used, you might want to check out the source code of OpenBSD -current. You can use BXR.SU OpenGrok to navigate such source code (updated daily). The most recent example of libressl and tls_init.3 use would perhaps be OpenNTPD. http://bxr.su/OpenBSD/usr.sbin/ntpd/constraint.c http://bxr.su/OpenBSD/usr.sbin/ntpd/ntp.c#ntp_main A brief search reveals that tls_init is also currently referenced, in no particular order, from httpd, ftp, spamd and syslogd: http://bxr.su/OpenBSD/usr.sbin/httpd/server.c http://bxr.su/OpenBSD/usr.bin/ftp/fetch.c http://bxr.su/OpenBSD/libexec/spamd/spamd.c http://bxr.su/OpenBSD/usr.sbin/syslogd/syslogd.c Cheers, Constantine.
Re: regarding OpenSSL License change
> Date: Wed, 22 Mar 2017 16:48:10 -0400 > From: lice...@openssl.org > To: dera...@cvs.openbsd.org > Subject: OpenSSL License change [...] > We are asking for your permission to change the licence for your > contribution. Please visit this link to respond; you will have a chance [...] > If we do not hear from you, we will assume that you have no objection. Is this for real?! Who do they think they are? Entirely absurd. People should not bother to respond to such nonsense, and then sue OpenSSL for obvious copyright infringement, and move for a summary judgement without a trial. C.
spamd: greyreader failed (Error 2) (was: Re: CVS: cvs.openbsd.org: src)
Hello, On OpenBSD 5.2 amd64, my spamd (which is used very selectively through pf(4)) seems to have died 20 days ago, after continuously running for many months, with the following final words in the logs: Sep 10 09:49:25 Cns spamd[5220]: 87.225.1.10: connected (1/1), lists: spamd-greytrap Sep 10 09:54:47 Cns spamd[29672]: greyreader failed (Error 2) There were minor changes to grey.c since 5.2. Back in 5.2, it would appear that at the end of grey.c#greyreader(), after the `grey` pipe is exhausted, greyreader() returns at the end of the function, and then grey.c#greywatcher() issues the error message, as above, unconditionally after greyreader() returns, and also exits. Whereas it remains to be seen what kind of bug I'm facing here (Google reveals I'm not alone), it would appear that changes introduced in 5.4-current would no longer cause spamd to report such situation, because the 0 that would still be returned at the end of greyreader() would no longer cause greywatcher() to produce the error message that I have received (it'll still quit, though). http://www.openbsd.org/cgi-bin/cvsweb/src/libexec/spamd/grey.c.diff?r1=1.52;r2=1.53;f=h http://www.openbsd.org/cgi-bin/cvsweb/src/libexec/spamd/grey.c.diff?r2=1.53&r1=1.52&f=u Basically, the below part of the recent commit seems to modify the behaviour that was not advertised to have been modified: @@ -979,7 +979,7 @@ greyreader(void) sync = 1; if (grey == NULL) { syslog_r(LOG_ERR, &sdata, "No greylist pipe stream!\n"); - exit(1); + return (-1); } /* grab trap suffixes */ @@ -1140,10 +1140,11 @@ greywatcher(void) */ close(pfdev); setproctitle("(%s update)", PATH_SPAMD_DB); - greyreader(); - syslog_r(LOG_ERR, &sdata, "greyreader failed (%m)"); - /* NOTREACHED */ - _exit(1); + if (greyreader() == -1) { + syslog_r(LOG_ERR, &sdata, "greyreader failed (%m)"); + _exit(1); + } + _exit(0); } http://bxr.su/o/libexec/spamd/grey.c#greywatcher Is it indeed intentional that "greyreader failed (Error 2)" will be produced no more as a result of the above change? Any ideas what caused greyreader to fail on my OpenBSD 5.2 in the first place? Cheers, Constantine. On 2013-W34-3 10:13 -0600, Todd C. Miller wrote: > CVSROOT: /cvs > Module name: src > Changes by: mill...@cvs.openbsd.org 2013/08/21 10:13:30 > > Modified files: > usr.sbin/spamdb: Makefile spamdb.c > libexec/spamd : Makefile grey.c grey.h > libexec/spamlogd: Makefile spamlogd.c > Added files: > libexec/spamd : gdcopy.c > > Log message: > Remove the use of time_t in the greylist db file and use int64_t instead > with backwards compatibility for records with 32-bit times. > OK deraadt@ beck@
Re: spamd: greyreader failed (Error 2) (was: Re: CVS: cvs.openbsd.org: src)
On 2013-W40-2 16:56 -0600, Todd C. Miller wrote: > On Mon, 30 Sep 2013 19:26:20 -0700, "Constantine A. Murenin" wrote: > > > Whereas it remains to be seen what kind of bug I'm facing here > > (Google reveals I'm not alone), it would appear that changes > > introduced in 5.4-current would no longer cause spamd to report > > such situation, because the 0 that would still be returned at the > > end of greyreader() would no longer cause greywatcher() to produce > > the error message that I have received (it'll still quit, though). > > Yes, that was an unrelated change that snuck in there. Personally, > I've only seen that error on shutdown, where it is spurious. If > you are getting a read error on the pipe it must mean that the spamd > on the other end died. Yes, I gather that's what it means -- the other end of the pipe is gone. However, there were no other messages reported. In my case, it was definitely not a shutdown-related error -- the system was not rebooted at that time, nor were any mail-related settings modified or any services restarted. I think it would make sense for this part to be reverted and for the error message to be brought back; otherwise, there'd pretty much not even be a record of when spamd actually stops working here. C.
spamlogd whitelists every logged rdr-to connection
Hi, I've started using spamlogd, and since then, every single connection attempt results in the host being whitelisted. I log some `rdr-to 127.0.0.1 port spamd` connection attempts into pflog, and it would seem like spamlogd filter (for port 25) is picking up the original dport, not the rewritten one (with hdr->dport containing original port, too). Not sure of the correct solution, but one of the options is to look at the hdr->rewritten field, and only act if it is false. This might impact someone who does pf rewrites for sendmail itself, but at least it's not going to let all the spam in for someone who simply logs stuff up. A patch is attached. Cheers, Constantine. Cns# tail /var/log/spamd Mar 6 08:12:53 Cns spamlogd[1082]: inbound 74.122.155.17 Mar 6 08:50:27 Cns spamd[5220]: 46.53.132.165: connected (1/0) Mar 6 08:50:27 Cns spamlogd[1082]: inbound 46.53.132.165 Mar 6 08:50:30 Cns spamd[5220]: 46.53.132.165: disconnected after 3 seconds. Mar 6 08:51:37 Cns spamd[5220]: 178.127.228.161: connected (1/0) Mar 6 08:51:37 Cns spamlogd[1082]: inbound 178.127.228.161 Mar 6 08:51:40 Cns spamd[5220]: 178.127.228.161: disconnected after 3 seconds. Mar 6 09:21:54 Cns spamlogd[1082]: inbound 46.241.252.81 Mar 6 09:21:55 Cns spamd[5220]: 46.241.252.81: connected (1/0) Mar 6 09:21:58 Cns spamd[5220]: 46.241.252.81: disconnected after 3 seconds. Cns# fgrep 46.241.252.81 /var/log/spamd Mar 6 09:21:54 Cns spamlogd[1082]: inbound 46.241.252.81 Mar 6 09:21:55 Cns spamd[5220]: 46.241.252.81: connected (1/0) Mar 6 09:21:58 Cns spamd[5220]: 46.241.252.81: disconnected after 3 seconds. Cns# tcpdump -o -n -e -ttt -r /var/log/pflog host 46.241.252.81 | tail tcpdump: WARNING: snaplen raised from 116 to 160 Mar 06 09:21:54.834606 rule 43/(match) pass in on re0: 46.241.252.81.3748 > 127.0.0.1.8025: S (src OS: Windows 2000 RFC1323, Windows XP RFC1323) 4277363076:4277363076(0) win 65535 (DF) Cns# fgrep 46.241.252.81 /var/log/maillog Cns# spamdb | fgrep 46.241.252.81 WHITE|46.241.252.81|||1362590514|1362590514|1365700914|1|0 Cns# date -r 1362590514 Wed Mar 6 09:21:54 PST 2013 Cns# uname -rms OpenBSD 5.2 amd64 (Logs were rorated several days ago, so, what you see is what's there.) Index: spamlogd.c === RCS file: /cvs/OpenBSD-CVS/src/libexec/spamlogd/spamlogd.c,v retrieving revision 1.21 diff -u -d -p -8 -r1.21 spamlogd.c --- spamlogd.c 18 Mar 2011 22:37:06 - 1.21 +++ spamlogd.c 6 Mar 2013 19:44:32 - @@ -174,20 +174,22 @@ logpkt_handler(u_char *user, const struc /* We're interested in passed packets */ if (hdr->action != PF_PASS) return; af = hdr->af; if (af == AF_INET) { ip = (const struct ip *)(sp + hdrlen); - if (hdr->dir == PF_IN) + if (hdr->dir == PF_IN) { + if (hdr->rewritten == 1) + return; inet_ntop(af, &ip->ip_src, ipstraddr, sizeof(ipstraddr)); - else if (hdr->dir == PF_OUT && !flag_inbound) + } else if (hdr->dir == PF_OUT && !flag_inbound) inet_ntop(af, &ip->ip_dst, ipstraddr, sizeof(ipstraddr)); } if (ipstraddr[0] != '\0') { if (hdr->dir == PF_IN) logmsg(LOG_DEBUG,"inbound %s", ipstraddr); else
Re: spamlogd whitelists every logged rdr-to connection
Bob, I agree, the hdr->rewritten approach is not good. I think the best approach here would be to not add any new entries on incoming connections in the first place, but only keep updating the existing ones (when the connection is incoming). In addition to not whitelisting greylisted or blocked connection that are logged, this would also prevent the case of double-whitelisting the connections that are logged and whitelisted through other rules, without any adverse side effects or unexpected behaviour. Patch attached inline. C. On 2013-W10-3 13:47 -0700, Bob Beck wrote: No constantine - the solution is to simply not use the "log" keyword on such traffic All of my boxen I run this on also rewite the traffic to (pool) of mailservers so this is not accurate. Simply don't log the traffic you don't want spamlogd to see. the *point* of spamlogd is to ensure all continuing valid connections *stay* whitelisted. On Wed, Mar 6, 2013 at 1:08 PM, Constantine A. Murenin wrote: > Hi, > > I've started using spamlogd, and since then, every single connection attempt > results in the host being whitelisted. > > I log some `rdr-to 127.0.0.1 port spamd` connection attempts into pflog, and > it would seem like spamlogd filter (for port 25) is picking up the original > dport, not the rewritten one (with hdr->dport containing original port, > too). > > Not sure of the correct solution, but one of the options is to look at the > hdr->rewritten field, and only act if it is false. This might impact > someone who does pf rewrites for sendmail itself, but at least it's not > going to let all the spam in for someone who simply logs stuff up. A patch > is attached. > > Cheers, > Constantine. Index: spamlogd.c === RCS file: /cvs/OpenBSD-CVS/src/libexec/spamlogd/spamlogd.c,v retrieving revision 1.21 diff -u -d -p -8 -r1.21 spamlogd.c --- spamlogd.c 18 Mar 2011 22:37:06 - 1.21 +++ spamlogd.c 6 Mar 2013 21:14:51 - @@ -75,17 +75,17 @@ pcap_t *hpcap = NULL; struct syslog_data sdata = SYSLOG_DATA_INIT; time_t whiteexp = WHITEEXP; extern char*__progname; void logmsg(int , const char *, ...); void sighandler_close(int); intinit_pcap(void); void logpkt_handler(u_char *, const struct pcap_pkthdr *, const u_char *); -intdbupdate(char *, char *); +intdbupdate(char *, char *, int); void usage(void); void logmsg(int pri, const char *msg, ...) { va_list ap; va_start(ap, msg); @@ -187,22 +187,22 @@ logpkt_handler(u_char *user, const struc sizeof(ipstraddr)); } if (ipstraddr[0] != '\0') { if (hdr->dir == PF_IN) logmsg(LOG_DEBUG,"inbound %s", ipstraddr); else logmsg(LOG_DEBUG,"outbound %s", ipstraddr); - dbupdate(PATH_SPAMD_DB, ipstraddr); + dbupdate(PATH_SPAMD_DB, ipstraddr, hdr->dir == PF_IN); } } int -dbupdate(char *dbname, char *ip) +dbupdate(char *dbname, char *ip, int updateonly) { HASHINFOhashinfo; DBT dbk, dbd; DB *db; struct gdatagd; time_t now; int r; struct in_addr ia; @@ -227,16 +227,20 @@ dbupdate(char *dbname, char *ip) /* add or update whitelist entry */ r = db->get(db, &dbk, &dbd, 0); if (r == -1) { logmsg(LOG_NOTICE, "db->get failed (%m)"); goto bad; } if (r) { + if (updateonly) { + logmsg(LOG_DEBUG,"ignoring %s", ip); + goto bad; + } /* new entry */ memset(&gd, 0, sizeof(gd)); gd.first = now; gd.bcount = 1; gd.pass = now; gd.expire = now + whiteexp; memset(&dbk, 0, sizeof(dbk)); dbk.size = strlen(ip);
Re: spamlogd whitelists every logged rdr-to connection
I'm simply logging greylisted connections; it's spamlogd that whitelists them just because they're logged. It doesn't make sense that logging greylisted or blacklisted connections would immediately turn them into being whitelisted by spamlogd. Same goes for logging connections that are already whitelisted through rules and tables other than . Why would you want them whitelisted several times? My second patch fixes these issues, without breaking valid setups. Yes, one could log stuff into different pflog interfaces, but I don't understand why pf.conf `pass in ... log ... port smtp ...` is effectively redefined to mean `add ` when spamlogd is running, even when connections are redirected to spamd for stuttering or greylisting. That's not something that seems reasonable, and an update-if-exists logic would make so much more sense. C. On 2013-W10-3 14:56 -0700, Bob Beck wrote: No constatine - that is not the best approach. if you are whitelisting grelisted connections or blacklisted connections that are blocked you have your pf.conf or spamlogd setup wrong. On Wed, Mar 6, 2013 at 2:54 PM, Constantine A. Murenin wrote: > Bob, I agree, the hdr->rewritten approach is not good. > > I think the best approach here would be to not add any new entries on > incoming connections in the first place, but only keep updating the existing > ones (when the connection is incoming). > > In addition to not whitelisting greylisted or blocked connection that are > logged, this would also prevent the case of double-whitelisting the > connections that are logged and whitelisted through other rules, without any > adverse side effects or unexpected behaviour. > > Patch attached inline. > > C. > > > On 2013-W10-3 13:47 -0700, Bob Beck wrote: >> >> No constantine - the solution is to simply not use the "log" keyword >> on such traffic >> >> All of my boxen I run this on also rewite the traffic to (pool) of >> mailservers so this is >> not accurate. >> >> Simply don't log the traffic you don't want spamlogd to see. the >> *point* of spamlogd >> is to ensure all continuing valid connections *stay* whitelisted. >> >> On Wed, Mar 6, 2013 at 1:08 PM, Constantine A. Murenin wrote: >> > Hi, >> > >> > I've started using spamlogd, and since then, every single connection >> > attempt >> > results in the host being whitelisted. >> > >> > I log some `rdr-to 127.0.0.1 port spamd` connection attempts into pflog, >> > and >> > it would seem like spamlogd filter (for port 25) is picking up the >> > original >> > dport, not the rewritten one (with hdr->dport containing original port, >> > too). >> > >> > Not sure of the correct solution, but one of the options is to look at >> > the >> > hdr->rewritten field, and only act if it is false. This might impact >> > someone who does pf rewrites for sendmail itself, but at least it's not >> > going to let all the spam in for someone who simply logs stuff up. A >> > patch >> > is attached. >> > >> > Cheers, >> > Constantine. > > > Index: spamlogd.c > === > RCS file: /cvs/OpenBSD-CVS/src/libexec/spamlogd/spamlogd.c,v > retrieving revision 1.21 > diff -u -d -p -8 -r1.21 spamlogd.c > --- spamlogd.c 18 Mar 2011 22:37:06 - 1.21 > +++ spamlogd.c 6 Mar 2013 21:14:51 - > @@ -75,17 +75,17 @@ pcap_t *hpcap = NULL; > struct syslog_data sdata = SYSLOG_DATA_INIT; > time_t whiteexp = WHITEEXP; > extern char*__progname; > > void logmsg(int , const char *, ...); > void sighandler_close(int); > intinit_pcap(void); > void logpkt_handler(u_char *, const struct pcap_pkthdr *, const u_char > *); > -intdbupdate(char *, char *); > +intdbupdate(char *, char *, int); > void usage(void); > > void > logmsg(int pri, const char *msg, ...) > { > va_list ap; > va_start(ap, msg); > > @@ -187,22 +187,22 @@ logpkt_handler(u_char *user, const struc > sizeof(ipstraddr)); > } > > if (ipstraddr[0] != '\0') { > if (hdr->dir == PF_IN) > logmsg(LOG_DEBUG,"inbound %s", ipstraddr); > else > logmsg(LOG_DEBUG,"outbound %s", ipstraddr); > - dbupdate(PATH_SPAMD_DB, ipstraddr); > + dbupdate(PATH_SPAMD_DB, ipstraddr, hdr->dir == PF_IN); >
Re: spamlogd whitelists every logged rdr-to connection
On 2013-W10-3 15:46 -0700, Bob Beck wrote: > > Yes, one could log stuff into different pflog interfaces, but I don't > > understand why pf.conf `pass in ... log ... port smtp ...` is effectively > > redefined to mean `add ` when spamlogd is running, > > http://www.openbsd.org/cgi-bin/man.cgi?query=spamlogd > > and RTFM for the first two sentences - and it's pretty darn clear. > > Those of us that whitelist blocks of addresses (and log them) like > this behaviour to track what mailservers we are seeing like the > current behavior. Point taken; this should be optional. Index: spamlogd.8 === RCS file: /cvs/OpenBSD-CVS/src/libexec/spamlogd/spamlogd.8,v retrieving revision 1.17 diff -u -d -p -8 -r1.17 spamlogd.8 --- spamlogd.8 4 Mar 2011 21:01:49 - 1.17 +++ spamlogd.8 7 Mar 2013 19:41:24 - @@ -17,17 +17,17 @@ .Dd $Mdocdate: March 4 2011 $ .Dt SPAMLOGD 8 .Os .Sh NAME .Nm spamlogd .Nd spamd whitelist updating daemon .Sh SYNOPSIS .Nm spamlogd -.Op Fl DI +.Op Fl DIU .Op Fl i Ar interface .Op Fl l Ar pflog_interface .Op Fl W Ar whiteexp .Op Fl Y Ar synctarget .Sh DESCRIPTION .Nm manipulates the .Xr spamd 8 @@ -73,16 +73,32 @@ target of outbound SMTP connections. Specify a network interface on which packets must arrive. The default is to watch for connections logged from all interfaces. .It Fl l Ar pflog_interface Specify a .Xr pflog 4 interface to listen for connection notifications. The default is to watch for connections logged on .Dq pflog0 . +.It Fl U +Specify that for inbound SMTP connections, +.Nm +is only to update existing +.Pa /var/db/spamd +entries, without adding any new ones. +By default +.Nm +will whitelist the source of all inbound SMTP connections that are logged. +This option is needed if connections redirected to +.Xr spamd 8 +are logged, +and no distinct +.Xr pflog 4 +interface is configured for +.Nm . .It Fl W Ar whiteexp Adjust the time for .Ar whiteexp in hours. The default is 864 hours (approximately 36 days); maximum is 2160 hours (approximately 90 days). .It Fl Y Ar synctarget Add a target to receive synchronisation messages; see Index: spamlogd.c === RCS file: /cvs/OpenBSD-CVS/src/libexec/spamlogd/spamlogd.c,v retrieving revision 1.21 diff -u -d -p -8 -r1.21 spamlogd.c --- spamlogd.c 18 Mar 2011 22:37:06 - 1.21 +++ spamlogd.c 7 Mar 2013 19:46:44 - @@ -63,29 +63,30 @@ int debug = 1; int greylist = 1; FILE *grey = NULL; u_short sync_port; int syncsend; u_int8_tflag_debug = 0; u_int8_tflag_inbound = 0; +u_int8_tflag_updateonly = 0; char *networkif = NULL; char *pflogif = "pflog0"; charerrbuf[PCAP_ERRBUF_SIZE]; pcap_t *hpcap = NULL; struct syslog_data sdata = SYSLOG_DATA_INIT; time_t whiteexp = WHITEEXP; extern char*__progname; void logmsg(int , const char *, ...); void sighandler_close(int); intinit_pcap(void); void logpkt_handler(u_char *, const struct pcap_pkthdr *, const u_char *); -intdbupdate(char *, char *); +intdbupdate(char *, char *, int); void usage(void); void logmsg(int pri, const char *msg, ...) { va_list ap; va_start(ap, msg); @@ -187,22 +188,22 @@ logpkt_handler(u_char *user, const struc sizeof(ipstraddr)); } if (ipstraddr[0] != '\0') { if (hdr->dir == PF_IN) logmsg(LOG_DEBUG,"inbound %s", ipstraddr); else logmsg(LOG_DEBUG,"outbound %s", ipstraddr); - dbupdate(PATH_SPAMD_DB, ipstraddr); + dbupdate(PATH_SPAMD_DB, ipstraddr, hdr->dir == PF_IN); } } int -dbupdate(char *dbname, char *ip) +dbupdate(char *dbname, char *ip, int inbound) { HASHINFOhashinfo; DBT dbk, dbd; DB *db; struct gdatagd; time_t now; int r; struct in_addr ia; @@ -227,16 +228,20 @@ dbupdate(char *dbname, char *ip) /* add or update whitelist entry */ r = db->get(db, &dbk, &dbd, 0); if (r == -1) { logmsg(LOG_NOTICE, "db->get failed (%m)"); goto bad; } if (r) { + if (inbound && flag_updateonly) { + logmsg(LOG_DEBUG,"ignoring %s", ip); + goto bad; + } /* new entry */ memset(&gd, 0, sizeof(gd)); gd.first = now; gd.bcount = 1; gd.pass = now; gd.expire = now + whiteexp; memset(&dbk, 0, sizeof(dbk)); dbk.size = strlen(ip); @@ -280,17 +285,17 @@ dbupdate(char *dbname, ch
Re: spamlogd whitelists every logged rdr-to connection
On 2013-W10-4 15:08 -0700, Bob Beck wrote: Show me your pf.conf please - I'd like to address your problem in the documentation or another way.. I don't like a knob like this. According to pf.conf(5), you can only log to one pflog(4) interface at a time, so, it's not exactly trivial to modify the rules, without modifying the rest of the workflow. BTW, don't laugh at these rules. They're highly effective, 99,9% of my incoming mail does not go through greylisting at all whatsoever, yet all spammers always end up talking to spamd. Some of these may seem redundant or a noop, they're mostly used for statistic purposes, just as you use spamlogd to whitelist already whitelisted netblocks, and see how much mail individual IPs send / receive. As for documentation, I think it's counterintuitive that `tcpdump` shows rewritten addresses / ports, yet spamlogd pcap(3) filter operates on the original ones. So, I know spamlogd(8) says what it says, but after running tcpdump on /var/log/pflog, it makes absolutely no sense that spamlogd would be whitelisting all of those connections that are redirected to spamd. (It also makes no sense how spamd -M works with the rules as they are below (although I'm very glad that it does, and works great at that).) I think this should not only be addressed in the documentation (for pcap-filter, spamd -M / spamlogd, pf.conf log/rdr-to / pflogd, tcpdump), but in the actual spamlogd code changes, too -- it should be smart enough to not automatically whitelist the connections that are rewritten to the default spamd port. Best regards, Constantine. # overall policy: # * always pass BSD, regardless of IP # * greylist all win, and non-a/r, and trap anyone pass in log on re0 proto tcp from any to any port smtp label "smtp any / other" pass in log on re0 proto tcp from any os "Windows .NET" to any port smtp label "smtp Windows .NET" pass in log on re0 proto tcp from any os Windows to any port smtp label "smtp Windows" \ rdr-to 127.0.0.1 port spamd pass in log on re0 proto tcp from any os Linux to any port smtp label "smtp Linux" pass in quick log on re0 proto tcp from any os FreeBSD to any port smtp label "smtp FreeBSD" pass in quick log on re0 proto tcp from any os NetBSD to any port smtp label "smtp NetBSD" pass in quick log on re0 proto tcp from any os OpenBSD to any port smtp label "smtp OpenBSD" pass in log on re0 proto tcp from any os unknown to any port smtp label "smtp unknown" # rules for spamd(8) block return in quick log proto tcp from any to any port 8025 table persist #table persist file "/etc/mail/nospamd" #pass in on egress proto tcp from any to any port smtp \ #rdr-to 127.0.0.1 port spamd pass in on egress proto tcp from {,,} to any port smtp \ rdr-to 127.0.0.1 port spamd pass in on egress proto tcp from any to spamd.mx.example.su port smtp \ rdr-to 127.0.0.1 port spamd #pass in on egress proto tcp from to any port smtp pass in log on egress proto tcp from to any port smtp pass out log on egress proto tcp to any port smtp On Thu, Mar 07, 2013 at 12:04:22PM -0800, Constantine A. Murenin wrote: > On 2013-W10-3 15:46 -0700, Bob Beck wrote: > > > Yes, one could log stuff into different pflog interfaces, but I don't > > > understand why pf.conf `pass in ... log ... port smtp ...` is effectively > > > redefined to mean `add ` when spamlogd is running, > > > > http://www.openbsd.org/cgi-bin/man.cgi?query=spamlogd > > > > and RTFM for the first two sentences - and it's pretty darn clear. > > > > Those of us that whitelist blocks of addresses (and log them) like > > this behaviour to track what mailservers we are seeing like the > > current behavior. > > Point taken; this should be optional. > Index: spamlogd.8 > === > RCS file: /cvs/OpenBSD-CVS/src/libexec/spamlogd/spamlogd.8,v > retrieving revision 1.17 > diff -u -d -p -8 -r1.17 spamlogd.8 > --- spamlogd.8 4 Mar 2011 21:01:49 - 1.17 > +++ spamlogd.8 7 Mar 2013 19:41:24 - > @@ -17,17 +17,17 @@ > .Dd $Mdocdate: March 4 2011 $ > .Dt SPAMLOGD 8 > .Os > .Sh NAME > .Nm spamlogd > .Nd spamd whitelist updating daemon > .Sh SYNOPSIS > .Nm spamlogd > -.Op Fl DI > +.Op Fl DIU > .Op Fl i Ar interface > .Op Fl l Ar pflog_interface > .Op Fl W Ar whiteexp > .Op Fl Y Ar synctarget > .Sh DESCRIPTION > .Nm > manipulates the > .Xr spamd 8 > @@ -73,16 +73,32 @@ target of outbound SMTP connections. > Specify a network interface on which packets must arrive. > The default is to watch for connections logged from all interfaces. > .It Fl l Ar pflog_interface >
Re: spamlogd whitelists every logged rdr-to connection
On 2013-W10-4 19:20 -0700, Bob Beck wrote: > I think this should not only be addressed in the documentation (for > pcap-filter, spamd -M / spamlogd, pf.conf log/rdr-to / pflogd, > tcpdump), but in the actual spamlogd code changes, too -- it should > be smart enough to not automatically whitelist the connections that > are rewritten to the default spamd port. Constantine, this statement of yours makes no sense. spamlogd only pays attention to connections to port 25. spamlogd listens on 8025. Unless you are doing something crazy in your pf.conf. Nothing crazier than what's in my prior message, just a few extra rules for gif0. I'm telling you, Bob, spamlogd whitelists those connections that go to spamd, to port 8025! No kidding! Yes, not 25, but 8025! This is a sample rule that causes the default spamlogd to immediately whitelist the spammer: pass in log on re0 proto tcp from any os Windows to any port smtp \ rdr-to 127.0.0.1 port spamd If you don't believe me, just try it out. Else, and although not related to pcap(3), how do you expect that spamd -M works, when the dst address gets rewritten to 127.0.0.1? I'm surprised I'm the first person with this problem; I presume a lot of prior people just thought they were crazy, and gave up. I have a vague recollection of encountering it back in 3.6 days or so. So, you do agree this is not something that should be happening, right? Cheers, Constantine.