1*a71a9546SAutomerger Merge WorkerU32 tests whether quantities of up to 4 bytes extracted from a packet have 2*a71a9546SAutomerger Merge Workerspecified values. The specification of what to extract is general enough to 3*a71a9546SAutomerger Merge Workerfind data at given offsets from tcp headers or payloads. 4*a71a9546SAutomerger Merge Worker.TP 5*a71a9546SAutomerger Merge Worker[\fB!\fP] \fB\-\-u32\fP \fItests\fP 6*a71a9546SAutomerger Merge WorkerThe argument amounts to a program in a small language described below. 7*a71a9546SAutomerger Merge Worker.IP 8*a71a9546SAutomerger Merge Workertests := location "=" value | tests "&&" location "=" value 9*a71a9546SAutomerger Merge Worker.IP 10*a71a9546SAutomerger Merge Workervalue := range | value "," range 11*a71a9546SAutomerger Merge Worker.IP 12*a71a9546SAutomerger Merge Workerrange := number | number ":" number 13*a71a9546SAutomerger Merge Worker.PP 14*a71a9546SAutomerger Merge Workera single number, \fIn\fP, is interpreted the same as \fIn:n\fP. \fIn:m\fP is 15*a71a9546SAutomerger Merge Workerinterpreted as the range of numbers \fB>=n\fP and \fB<=m\fP. 16*a71a9546SAutomerger Merge Worker.IP "" 4 17*a71a9546SAutomerger Merge Workerlocation := number | location operator number 18*a71a9546SAutomerger Merge Worker.IP "" 4 19*a71a9546SAutomerger Merge Workeroperator := "&" | "<<" | ">>" | "@" 20*a71a9546SAutomerger Merge Worker.PP 21*a71a9546SAutomerger Merge WorkerThe operators \fB&\fP, \fB<<\fP, \fB>>\fP and \fB&&\fP mean the same as in C. 22*a71a9546SAutomerger Merge WorkerThe \fB=\fP is really a set membership operator and the value syntax describes 23*a71a9546SAutomerger Merge Workera set. The \fB@\fP operator is what allows moving to the next header and is 24*a71a9546SAutomerger Merge Workerdescribed further below. 25*a71a9546SAutomerger Merge Worker.PP 26*a71a9546SAutomerger Merge WorkerThere are currently some artificial implementation limits on the size of the 27*a71a9546SAutomerger Merge Workertests: 28*a71a9546SAutomerger Merge Worker.IP " *" 29*a71a9546SAutomerger Merge Workerno more than 10 of "\fB=\fP" (and 9 "\fB&&\fP"s) in the u32 argument 30*a71a9546SAutomerger Merge Worker.IP " *" 31*a71a9546SAutomerger Merge Workerno more than 10 ranges (and 9 commas) per value 32*a71a9546SAutomerger Merge Worker.IP " *" 33*a71a9546SAutomerger Merge Workerno more than 10 numbers (and 9 operators) per location 34*a71a9546SAutomerger Merge Worker.PP 35*a71a9546SAutomerger Merge WorkerTo describe the meaning of location, imagine the following machine that 36*a71a9546SAutomerger Merge Workerinterprets it. There are three registers: 37*a71a9546SAutomerger Merge Worker.IP 38*a71a9546SAutomerger Merge WorkerA is of type \fBchar *\fP, initially the address of the IP header 39*a71a9546SAutomerger Merge Worker.IP 40*a71a9546SAutomerger Merge WorkerB and C are unsigned 32 bit integers, initially zero 41*a71a9546SAutomerger Merge Worker.PP 42*a71a9546SAutomerger Merge WorkerThe instructions are: 43*a71a9546SAutomerger Merge Worker.TP 44*a71a9546SAutomerger Merge Worker.B number 45*a71a9546SAutomerger Merge WorkerB = number; 46*a71a9546SAutomerger Merge Worker.IP 47*a71a9546SAutomerger Merge WorkerC = (*(A+B)<<24) + (*(A+B+1)<<16) + (*(A+B+2)<<8) + *(A+B+3) 48*a71a9546SAutomerger Merge Worker.TP 49*a71a9546SAutomerger Merge Worker.B &number 50*a71a9546SAutomerger Merge WorkerC = C & number 51*a71a9546SAutomerger Merge Worker.TP 52*a71a9546SAutomerger Merge Worker.B << number 53*a71a9546SAutomerger Merge WorkerC = C << number 54*a71a9546SAutomerger Merge Worker.TP 55*a71a9546SAutomerger Merge Worker.B >> number 56*a71a9546SAutomerger Merge WorkerC = C >> number 57*a71a9546SAutomerger Merge Worker.TP 58*a71a9546SAutomerger Merge Worker.B @number 59*a71a9546SAutomerger Merge WorkerA = A + C; then do the instruction number 60*a71a9546SAutomerger Merge Worker.PP 61*a71a9546SAutomerger Merge WorkerAny access of memory outside [skb\->data,skb\->end] causes the match to fail. 62*a71a9546SAutomerger Merge WorkerOtherwise the result of the computation is the final value of C. 63*a71a9546SAutomerger Merge Worker.PP 64*a71a9546SAutomerger Merge WorkerWhitespace is allowed but not required in the tests. However, the characters 65*a71a9546SAutomerger Merge Workerthat do occur there are likely to require shell quoting, so it is a good idea 66*a71a9546SAutomerger Merge Workerto enclose the arguments in quotes. 67*a71a9546SAutomerger Merge Worker.PP 68*a71a9546SAutomerger Merge WorkerExample: 69*a71a9546SAutomerger Merge Worker.IP 70*a71a9546SAutomerger Merge Workermatch IP packets with total length >= 256 71*a71a9546SAutomerger Merge Worker.IP 72*a71a9546SAutomerger Merge WorkerThe IP header contains a total length field in bytes 2-3. 73*a71a9546SAutomerger Merge Worker.IP 74*a71a9546SAutomerger Merge Worker\-\-u32 "\fB0 & 0xFFFF = 0x100:0xFFFF\fP" 75*a71a9546SAutomerger Merge Worker.IP 76*a71a9546SAutomerger Merge Workerread bytes 0-3 77*a71a9546SAutomerger Merge Worker.IP 78*a71a9546SAutomerger Merge WorkerAND that with 0xFFFF (giving bytes 2-3), and test whether that is in the range 79*a71a9546SAutomerger Merge Worker[0x100:0xFFFF] 80*a71a9546SAutomerger Merge Worker.PP 81*a71a9546SAutomerger Merge WorkerExample: (more realistic, hence more complicated) 82*a71a9546SAutomerger Merge Worker.IP 83*a71a9546SAutomerger Merge Workermatch ICMP packets with icmp type 0 84*a71a9546SAutomerger Merge Worker.IP 85*a71a9546SAutomerger Merge WorkerFirst test that it is an ICMP packet, true iff byte 9 (protocol) = 1 86*a71a9546SAutomerger Merge Worker.IP 87*a71a9546SAutomerger Merge Worker\-\-u32 "\fB6 & 0xFF = 1 &&\fP ... 88*a71a9546SAutomerger Merge Worker.IP 89*a71a9546SAutomerger Merge Workerread bytes 6-9, use \fB&\fP to throw away bytes 6-8 and compare the result to 90*a71a9546SAutomerger Merge Worker1. Next test that it is not a fragment. (If so, it might be part of such a 91*a71a9546SAutomerger Merge Workerpacket but we cannot always tell.) N.B.: This test is generally needed if you 92*a71a9546SAutomerger Merge Workerwant to match anything beyond the IP header. The last 6 bits of byte 6 and all 93*a71a9546SAutomerger Merge Workerof byte 7 are 0 iff this is a complete packet (not a fragment). Alternatively, 94*a71a9546SAutomerger Merge Workeryou can allow first fragments by only testing the last 5 bits of byte 6. 95*a71a9546SAutomerger Merge Worker.IP 96*a71a9546SAutomerger Merge Worker ... \fB4 & 0x3FFF = 0 &&\fP ... 97*a71a9546SAutomerger Merge Worker.IP 98*a71a9546SAutomerger Merge WorkerLast test: the first byte past the IP header (the type) is 0. This is where we 99*a71a9546SAutomerger Merge Workerhave to use the @syntax. The length of the IP header (IHL) in 32 bit words is 100*a71a9546SAutomerger Merge Workerstored in the right half of byte 0 of the IP header itself. 101*a71a9546SAutomerger Merge Worker.IP 102*a71a9546SAutomerger Merge Worker ... \fB0 >> 22 & 0x3C @ 0 >> 24 = 0\fP" 103*a71a9546SAutomerger Merge Worker.IP 104*a71a9546SAutomerger Merge WorkerThe first 0 means read bytes 0-3, \fB>>22\fP means shift that 22 bits to the 105*a71a9546SAutomerger Merge Workerright. Shifting 24 bits would give the first byte, so only 22 bits is four 106*a71a9546SAutomerger Merge Workertimes that plus a few more bits. \fB&3C\fP then eliminates the two extra bits 107*a71a9546SAutomerger Merge Workeron the right and the first four bits of the first byte. For instance, if IHL=5, 108*a71a9546SAutomerger Merge Workerthen the IP header is 20 (4 x 5) bytes long. In this case, bytes 0-1 are (in 109*a71a9546SAutomerger Merge Workerbinary) xxxx0101 yyzzzzzz, \fB>>22\fP gives the 10 bit value xxxx0101yy and 110*a71a9546SAutomerger Merge Worker\fB&3C\fP gives 010100. \fB@\fP means to use this number as a new offset into 111*a71a9546SAutomerger Merge Workerthe packet, and read four bytes starting from there. This is the first 4 bytes 112*a71a9546SAutomerger Merge Workerof the ICMP payload, of which byte 0 is the ICMP type. Therefore, we simply 113*a71a9546SAutomerger Merge Workershift the value 24 to the right to throw out all but the first byte and compare 114*a71a9546SAutomerger Merge Workerthe result with 0. 115*a71a9546SAutomerger Merge Worker.PP 116*a71a9546SAutomerger Merge WorkerExample: 117*a71a9546SAutomerger Merge Worker.IP 118*a71a9546SAutomerger Merge WorkerTCP payload bytes 8-12 is any of 1, 2, 5 or 8 119*a71a9546SAutomerger Merge Worker.IP 120*a71a9546SAutomerger Merge WorkerFirst we test that the packet is a tcp packet (similar to ICMP). 121*a71a9546SAutomerger Merge Worker.IP 122*a71a9546SAutomerger Merge Worker\-\-u32 "\fB6 & 0xFF = 6 &&\fP ... 123*a71a9546SAutomerger Merge Worker.IP 124*a71a9546SAutomerger Merge WorkerNext, test that it is not a fragment (same as above). 125*a71a9546SAutomerger Merge Worker.IP 126*a71a9546SAutomerger Merge Worker ... \fB0 >> 22 & 0x3C @ 12 >> 26 & 0x3C @ 8 = 1,2,5,8\fP" 127*a71a9546SAutomerger Merge Worker.IP 128*a71a9546SAutomerger Merge Worker\fB0>>22&3C\fP as above computes the number of bytes in the IP header. \fB@\fP 129*a71a9546SAutomerger Merge Workermakes this the new offset into the packet, which is the start of the TCP 130*a71a9546SAutomerger Merge Workerheader. The length of the TCP header (again in 32 bit words) is the left half 131*a71a9546SAutomerger Merge Workerof byte 12 of the TCP header. The \fB12>>26&3C\fP computes this length in bytes 132*a71a9546SAutomerger Merge Worker(similar to the IP header before). "@" makes this the new offset, which is the 133*a71a9546SAutomerger Merge Workerstart of the TCP payload. Finally, 8 reads bytes 8-12 of the payload and 134*a71a9546SAutomerger Merge Worker\fB=\fP checks whether the result is any of 1, 2, 5 or 8. 135