What are the possible return codes of bpf_filter(), in FreeBSD kernel? What does each return codes mean? - freebsd

What are the possible return codes of bpf_filter(), in FreeBSD kernel?
What does each return codes mean?
The man page (link) is not clear on this issue.
The bpf_filter() function executes the filter program starting at pc on
the packet pkt. The wirelen argument is the length of the original
packet and buflen is the amount of data present. The buflen value of 0
is special; it indicates that the pkt is actually a pointer to an mbuf
chain (struct mbuf *).
Return Values
The bpf_filter() function returns -1 (cast to an unsigned integer) if there is no filter. Otherwise, it returns the result of the filter program.
I am getting 65535 when there is a Match and 0 when there is no match. Not sure what is the meaning for the return value 65535.
Can someone please explain the return code of bpf_filter() in detailed?

The return value of bpf_filter() is the result of the filter program. The result being number of bytes of the packet being filtered to be copied to the buffer for the task (the filter return instruction value).
The value will be 0 if the packet does not match the filter.
If the packet matches the filter it will be the snapshot length (snaplen) that was defined in the pcap_open_ call.
The default value is 65535 bytes as the maximum size of a TCP packet is 64K (65535 bytes).

The function bpf_filter() takes a pointer to a struct containing the BPF instructions as an argument (pc on the man page) and runs these on the packets to filter them.
The bpf_filter() function returns -1 (cast to an unsigned integer) if
there is no filter.
We can check in the source code that when pc, the structure that should contain the BPF instructions, is null, then bpf_filter() immediately returns -1, cast to a u_int:
if (pc == 0)
/*
* No filter means accept all.
*/
return (u_int)-1;
[Edited] Internally, for a signed integer, -1 would be stored as “the maximal value for a integer, minus one”. With 32 bits, since the return value here is cast to an unsigned integer, that would be 2^32 - 1.
Since the return value here is cast to an unsigned integer, this is the value you obtain: 65535 equals to 2**16 - 1, so -1 cast to a unsigned 16 bit-long integer (a u_int). So I would tend to believe that when you see this 65535 value, you do not actually provide any BPF program to the function? Would that be consistant with you observations?
Now when there is a match:
Otherwise, it returns the result of the filter program.
The result value of bpf_filter() is the result retreived from the BPF program. So when you get a 0 return value, it means that:
Either your BPF program completed and returned 0.
Or possibly (even though this does not seem documented in the man page), an error was encountered while running the BPF program. Here is an example, also from the source:
case BPF_ALU|BPF_DIV|BPF_X:
if (X == 0)
return 0;
A /= X;
continue;
“In the case of an arithmetic division, if the denominator X is null, then make bpf_filter() return 0, else divide register A by register X and carry on to the next instruction”.
[Edited] (see comments) As you found out, the same applies for the 65535 value: it is the value you made your BPF program return.

Related

How can i specify parameter dependent on index value?

I'm trying to port code from DML 1.2 to DML 1.4. Here is part of code that i ported:
group rx_queue [i < NQUEUES] {
<...>
param desctype = i < 64 #? regs.SRRCTL12[i].DESCTYPE.val #: regs.SRRCTL2[i - 64].DESCTYPE.val; // error occurs here
<...>
}
Error says:
error: non-constant expression: cast(i, int64 ) < 64
How can i specify parameter dependent on index value?
I tried to use if...else instead ternary operator, but it says that conditional parameters are not allowed in DML.
Index parameters in DML are a slightly magical expressions; when used from within parameters, they can evaluate to either a constant or a variable depending on where the parameter is used from. Consider the following example:
group g[i < 5] {
param x = i * 4;
method m() {
log info: "%d", x;
log info: "%d", g[4 - i].x;
log info: "%d", g[2].x;
}
}
i becomes an implicit local variable within the m method, and in params, indices are a bit like implicit macro parameters. When the compiler encounters x in the first log statement, the param will expand to i * 4 right away. In the second log statement, the x param is taken from an object indexed with the expression 4 - i, so param expansion will instead insert (5 - i) * 4. In the third log statement, the x param is taken from a constant indexed object, so it expands to 2 * 4 which collapses into the constant 8.
Most uses of desctype will likely happen from contexts where indices are variable, and the #? expression requires a constant boolean as condition, so this will likely give an error as soon as anyone tries to use it.
I would normally advise you to switch from #? to ? in the definition of the desctype param, but that fails in this particular case: DMLC will report error: array index out of bounds on the i - 64 expression. This error is much more confusing, and happens because DMLC automatically evaluates every parameter once with all zero indices, to smoke out misspelled identifiers; this will include evaluation of SRRCTL2[i-64] which collapses into SRRCTL2[-64] which annoys DMLC.
This is arguably a compiler bug; DMLC should probably be more tolerant in this corner. (Note that even if we would remove the zero-indexed validation step from the compiler, your parameter would still give the same error message if it ever would be explicitly referenced with a constant index, like log info: "%d", rx_queue[0].desctype).
The reason why you didn't get an error in DML 1.2 is that DML 1.2 had a single ternary operator ? that unified 1.4's ? and #?; when evaluated with a constant condition the dead branch would be disregarded without checking for errors. This had some strange effects in other situations, but made your particular use case work.
My concrete advise would be to replace the param with a method; this makes all index variables unconditionally non-constant which avoids the problem:
method desctype() -> (uint64) {
return i < 64 ? regs.SRRCTL12[i].DESCTYPE.val : regs.SRRCTL2[i - 64].DESCTYPE.val;
}

What does the int value returned from compareTo function in Kotlin really mean?

In the documentation of compareTo function, I read:
Returns zero if this object is equal to the specified other object, a
negative number if it's less than other, or a positive number if it's
greater than other.
What does this less than or greater than mean in the context of strings? Is -for example- Hello World less than a single character a?
val epicString = "Hello World"
println(epicString.compareTo("a")) //-25
Why -25 and not -10 or -1 (for example)?
Other examples:
val epicString = "Hello World"
println(epicString.compareTo("HelloWorld")) //-55
Is Hello World less than HelloWorld? Why?
Why it returns -55 and not -1, -2, -3, etc?
val epicString = "Hello World"
println(epicString.compareTo("Hello World")) //55
Is Hello World greater than Hello World? Why?
Why it returns 55 and not 1, 2, 3, etc?
I believe you're asking about the implementation of compareTo method for java.lang.String. Here is a source code for java 11:
public int compareTo(String anotherString) {
byte v1[] = value;
byte v2[] = anotherString.value;
if (coder() == anotherString.coder()) {
return isLatin1() ? StringLatin1.compareTo(v1, v2)
: StringUTF16.compareTo(v1, v2);
}
return isLatin1() ? StringLatin1.compareToUTF16(v1, v2)
: StringUTF16.compareToLatin1(v1, v2);
}
So we have a delegation to either StringLatin1 or StringUTF16 here, so we should look further:
Fortunately StringLatin1 and StringUTF16 have similar implementation when it comes to compare functionality:
Here is an implementation for StringLatin1 for example:
public static int compareTo(byte[] value, byte[] other) {
int len1 = value.length;
int len2 = other.length;
return compareTo(value, other, len1, len2);
}
public static int compareTo(byte[] value, byte[] other, int len1, int len2) {
int lim = Math.min(len1, len2);
for (int k = 0; k < lim; k++) {
if (value[k] != other[k]) {
return getChar(value, k) - getChar(other, k);
}
}
return len1 - len2;
}
As you see, it iterated over the characters of the shorter string and in case the charaters in the same index of two strings are different it returns the difference between them. If during the iterations it doesn't find any different (one string is prefix of another) it resorts to the comparison between the length of two strings.
In your case, there is a difference in the first iteration already...
So its the same as `"H".compareTo("a") --> -25".
The code of "H" is 72
The code of "a" is 97
So, 72 - 97 = -25
Short answer: The exact value doesn't have any meaning; only its sign does.
As the specification for compareTo() says, it returns a -ve number if the receiver is smaller than the other object, a +ve number if the receiver is larger, or 0 if the two are considered equal (for the purposes of this ordering).
The specification doesn't distinguish between different -ve numbers, nor between different +ve numbers — and so neither should you.  Some classes always return -1, 0, and 1, while others return different numbers, but that's just an implementation detail — and implementations vary.
Let's look at a very simple hypothetical example:
class Length(val metres: Int) : Comparable<Length> {
override fun compareTo(other: Length)
= metres - other.metres
}
This class has a single numerical property, so we can use that property to compare them.  One common way to do the comparison is simply to subtract the two lengths: that gives a number which is positive if the receiver is larger, negative if it's smaller, and zero of they're the same length — which is just what we need.
In this case, the value of compareTo() would happen to be the signed difference between the two lengths.
However, that method has a subtle bug: the subtraction could overflow, and give the wrong results if the difference is bigger than Int.MAX_VALUE.  (Obviously, to hit that you'd need to be working with astronomical distances, both positive and negative — but that's not implausible.  Rocket scientists write programs too!)
To fix it, you might change it to something like:
class Length(val metres: Int) : Comparable<Length> {
override fun compareTo(other: Length) = when {
metres > other.metres -> 1
metres < other.metres -> -1
else -> 0
}
}
That fixes the bug; it works for all possible lengths.
But notice that the actual return value has changed in most cases: now it only ever returns -1, 0, or 1, and no longer gives an indication of the actual difference in lengths.
If this was your class, then it would be safe to make this change because it still matches the specification.  Anyone who just looked at the sign of the result would see no change (apart from the bug fix).  Anyone using the exact value would find that their programs were now broken — but that's their own fault, because they shouldn't have been relying on that, because it was undocumented behaviour.
Exactly the same applies to the String class and its implementation.  While it might be interesting to poke around inside it and look at how it's written, the code you write should never rely on that sort of detail.  (It could change in a future version.  Or someone could apply your code to another object which didn't behave the same way.  Or you might want to expand your project to be cross-platform, and discover the hard way that the JavaScript implementation didn't behave exactly the same as the Java one.)
In the long run, life is much simpler if you don't assume anything more than the specification promises!

How does extensors M and R works CALLP on RPGLE?

I'm learning a little bit of RPGLE. But i don't have any reference of extensors M and R and how they work. I only found information about Extensor E. Please any help or any reference would be accepted!
The CALLP docs mention
For information on how operation extenders M and R are used, see
Precision Rules for Numeric Operations.
Following the link to the precision rules says
you can ensure that the decimal positions are kept by using the
"Result Decimal Positions" precision rule for the statement by coding
operation code extender (R).
Granted you have to dig down into the Default precision rules page to find out that
default and can be specified for an entire module (using control
specification keyword EXPROPTS(*MAXDIGITS) or for single free-form
expressions (using operation code extender M).
If you have the PDF version of the RPG manual, then there's an entry in the index.."operation extender" which takes you to the section about them in the "Calculation Specification - Traditional Syntax"
Operation Extender:
Entry Explanation
Blank No operation extension supplied
A Used on the DUMP operation to indicate that the operation is always performed regardless of the DEBUG option set on the H specification.
H Half adjust (round) result of numeric operation
N Record is read but not locked
Set pointer to *NULL after successful DEALLOC
P Pad the result field with blanks
D Pass operational descriptors on bound call
Date field
T Time field
Z Timestamp field
M Default precision rules
R "Result Decimal Position" precision rules
E Error handling
For CALLP, the M and R extenders affect how CONST and VALUE parameters are passed.
ctl-opt dftactgrp(*no);
callp(m) proc(2 / (7.0 / 10.0));
callp(r) proc(2 / (7.0 / 10.0));
return;
dcl-proc proc;
dcl-pi *n;
parm packed(10 : 9) const;
end-pi;
dsply (%char(parm));
end-proc;
This program displays
DSPLY 2.800000000
DSPLY 2.857142857

Using Boolean instead of 'if' 'else'

I have a function that takes a list of numbers and returns the average. In order to handle a list of zero length, the function uses AND such that if the list is empty then the function returns 0, else returns the average
def avg(*args):
count = len(args)
total = sum(args)
return count and total / count
i dont understand why this works. If length is non zero, how does python know to return total/count?
Like jonrsharpe wrote, return count and total / count is equivalent to return total / count if count != 0 else count.
Why does it work?
The reason why they are equivalent is because the and operator evaluates the first statement, which here is count, and only if this expression is not false, it evaluates the statement on the right. So everything else will only see the value of the statement on the right.
But it's important to note that if the statement on the left is false, the value of the left statement is returned. So in 0 and total / count, 0 is returned. And in False and total / count, False is returned instead.
The expression can also be a function, which implies that in something like file.write('spam') and file.flush(), one of these functions might not be executed; if the file.write() call fails, and will not run the second expression and file.flush() won't be called, hence the file won't be flushed.
So, this expression could have drastic effects when writing to a database for example. It might not be clear to some people that an 'if' 'else' statement was the intention. In those cases, consider using an 'if' 'else' statement instead.

Thrust custom binary predicate parallelization

I am implementing a custom binary predicate used by the thrust::max_element search algorithm. It also keeps track of a value of interest which the algorithm alone cannot yield. It looks something like this:
struct cmp_class{
cmp_class(int *val1){
this->val1 = val1;
}
bool operator()(int i, int j){
if (j < *val1) { *val1 = j; }
return i < j;
}
int *val1;
};
int val1 = ARRAY[0];
std::max_element(ARRAY, ARRAY+length, cmp(&val1));
.... use val1
My actual binary predicate is quite a bit more complex, but the example above captures the gist of it: I am passing a pointer to an integer to the binary predicate cmp, which then writes to that integer to keep track of some value (here the running minimum). Since max_element first calls cmp()(ARRAY[0],ARRAY[1]) and then cmp()(running maximum,ARRAY[i]), I only look at value j inside cmp and therefore initialize val1 = ARRAY[0] to ensure ARRAY[0] is taken into account.
If I do the above on the host, using std::max_element for example, this works fine. The values of val1 is what I expect given known data. However, using Thrust to execute this on the GPU, its value is off. I suspect this is due to the parallelization of thrust::max_element, which is recursively applied on sub arrays, the results of which form another array which thrust::max_element is run on, etc. Does this hold water?
In general, the binary predicates used for thrust reductions are expected to be commutative. I'm using "commutative" here to mean that the predicate result should be valid regardless of the order in which the arguments are presented.
At the initial stage of a thrust parallel reduction, the arguments are likely to be presented in an order you might expect (i.e. in the order of the vectors passed to the reduce function, or in the order that the values occur in a single vector.) However, later on in the parallel reduction process, the origin of the arguments may get mixed up, during the parallel-sweeping. Any binary comparison functor that assumes an ordering to the arguments is probably broken, for thrust parallel reductions.
In your case, the boolean result of your comparison functor should be valid regardless of the order of arguments presented, and in that respect it appears to be properly commutative.
However, regarding the custom storage functionality you have built-in around val1, it seems pretty clear that the results in val1 could be different depending on the order in which arguments are passed to the functor. Consider this simple max-finding sequence amongst a set values passed to the functor as (i,j) (assume val1 starts out at a large value):
values: 10 5 3 7 12
comparison pairs: (10,5) (10,3) (10,7) (10,12)
comparison result: 10 10 10 12
val1 storage: 5 3 3 3
Now suppose that we simply reverse the order that arguments are presented to the functor:
values: 10 5 3 7 12
comparison pairs: (5,10) (3,10) (7,10) (12,10)
comparison result: 10 10 10 12
val1 storage: 10 10 10 10
Another issue is that you have no atomic protection on val1 that I can see:
if (j < *val1) { *val1 = j; }
The above line of code may be OK in a serial realization. In a parallel multi-threaded algorithm, you have the possibility for multiple threads to be accessing (reading and writing) *val1 simultaneously, which will have undefined results.

Resources