Introduction
This section will borrow heavily from "Gray Hat Hacking, The Ethical Hacker's Handbook", by Regaldo, et. al, McGraw Hill, 4th. Edition.
Gray Hat Hacking (Amazon)
Note that there is a 5th Edition available at the time of this writing.
We will also make use of the classic discussion on Buffer Overflows by Aleph One.Aleph One's Classic on Buffer Overflows.
We will also use tips and tricks from the following:
Open Security Training's course on Introduction to Exploits 1
Open Security Training
"The Shellcoder's Handboook", by Anley et. al, Wiley, 2nd Edition
The Shellcoder's Handbook (Amazon)
In this section, we will discuss trying to inject shellcode into a vulnerable program from the command line, investigate errors, and perform debugging of these errors with the Gnu DeBugger (GDB).
Smashing the Stack of a Vulnerable Program and Causing a Buffer Overflow
Introduction to Buffer Overflows and Preparing a 32-bit Ubuntu Virtual Machine
The following image was taken from the following presentation:
Stack-Based Buffer Overflows Attacker
By: Laurence Davis
Stack-Based Buffer Overflows
By overfilling the function's local variables with data, one is able to overwrite the saved EIP (return pointer in the figure). This is a vulnerability in the way the kernel and C compiler handles function calls, because shellcode can be inserted onto the stack and the saved return address may be overwritten to point to the shellcode. However, as seen in the section on Shellcoding, modern kernels will not allow execution of data on the stack. So even though this vulnerability has for the most part been patched, we will still learn it because fundamentally, it is the basis for many such vulnerabilities, found even in modern kernels.
We will now investigate exploiting this vulnerability with a simple vulnerable C test program called meet.c shown below.
Brief synopsis of meet.c
In the program meet.c, we include string.h in order to make use of the vulnerable strcpy command. The format of the strcpy command is as follows:
char *strcpy(char *dest, const char *src);
From the man page for strcpy:
The strcpy() function copies the string pointed to by src, including the terminating null byte ('\0'), to the buffer pointed to by dest. The strings may not overlap, and the destination string dest must be large enough to receive the copy. Beware of buffer overruns!
The program's main function reads in two arguments, which are stored in the argv array of strings. They are argv[1] and argv[2] for the first and second arguments, respectively.
The main function calls a function called greeting. Greeting has a local variable that is 400 bytes long called name. This local variable acts like an input buffer. In order to aid in understanding the memory layout of this program, I have added three diagnostic statements that print out the memory addresses of the local variable name, as well as the two function arguments, temp1 and temp2.
Now this is where things get interesting. For educational purposes, the VERY vulnerable strcpy function is called from within the function called greeting. What strcpy will do is to copy the argument temp2 into the buffer name, WITHOUT any bounds checking. This means that if the argument temp2 is carefully crafted, the buffer name can be overflowed. When it is overflowed, it will overwrite adjacent data, which includes the return address to the calling function main!
Normally used, the function called greeting then prints out the string Hello, followed by the first argument, and the contents of the buffer called name. Control is then returned back to the main function, which prints out the string, Bye, followed by the first and second arguments from the command line. We will now investigate attacking the aforementioned built-in vulnerability in this program. But first, we must set up the environment.
Disabling Address Space Layout Randomization (ASLR)
As mentioned previously, modern Linux kernels use several strategies to overcome vulnerabilities such as buffer overflows. One of these strategies is known as Address Space Layout Randomization (ASLR). Essentially, the kernel randomizes the process's address space, which includes the stack, thereby precluding the ability to brute force overwriting of the stored return address on the stack. Every attempt will require injection of a new malicious address that points back to the shellcode. This is extremely difficult to guess, if not impossible.
Another strategy is to simply not allow execution of data on the stack. Since the buffer and hence the injected shellcode resides entirely on the stack, execution of the shellcode will not be allowed by the kernel, and the process will crash.
To get around such protections, for pedagogical reasons, we will disable both ASLR and allow execution of data on the stack. This will require either recompiling the C program with executable stack or enabling executable stack at the kernel level. In order to disable ASLR, a bash shell may be opened with the following command:
$ setarch i386 -R /bin/bashor by disabling ASLR at the kernel level. To minimize variables, it is better to do this at the kernel level; however, this is not a good idea on your main system for security reasons. Therefore, we will spin up a 32-bit Ubuntu virtual machine and disable these protections at the kernel level, as shown in the image below:
As can be seen from the screenshot above, it is not directly possible to disable non-executable stack or data execution protections, also called NX. This must be done at the UEFI or BIOS level. It is however, possible to disable ASLR by using the command:
$ echo "0"> /proc/sys/kernel/randomize_va_spaceIn order test that the process' address space is not randomized, we issue the following command a few times and observe that the address space is constant between issuing the command:
$ cat /proc/self/maps
[.... memory layout table ....]
$ cat /proc/self/maps
[.... unchanged memory layout table ....]
$ cat /proc/self/maps
[.... unchanged memory layout table ....]
The following screenshot shows these commands in the 32-bit Ubuntu VM:
As can be seen from the above screenshot, the address space layout is not randomized. Each invocation of the cat /proc/self/maps command produces the same results. Of particular interest is that the stack's address remains constant at:
bffdf000-c0000000 rw-p 00000000 00:00 0 [stack]Notice that the stack has permissions of rw, but not exectute.
In order to overcome the inability to disable non-executable (NX) stack or data segments at the kernel level, we will have to remember to issue special directives to the compiler when compiling vulnerable programs. These compiler directives are:
gcc ...-zexecstack -fno-stack-protector...
The directive -zexecstack tells the compiler to enable an executable stack, while the directive -fno-stack-protector tells the compiler to disable stack corruption protections.
We are now ready to attempt to overflow the buffer of the vulnerable program from the command line.
Smashing the Stack of a Vulnerable Program and Causing a Buffer Overflow - Overflowing the Buffer of the Vulnerable Program meet.c
Compiling meet.c with NX disabled, with debugging information and static compilation
As described in the previous section, it is first necessary to compile meet.c with executable stack protections off. We will also include lots of debugging information, and we will compile the program with the -static flag, so that all of the called system libraries will be included in the executable. Having all of the called system libraries included tends to aid debugging, since the GNU Debugger (GDB) will not have to jump around memory as much. Finally, we will force 32-bit compilation. Since we will be running the executable on a 32-bit Virtual Machine (VM), this might be a moot point, but we will do it anyway to minimize differences in executable operation among different systems.
To compile meet.c, we issue the following command:
$ gcc -m32 -static -ggdb3 -zexecstack -fno-stack-protector -mpreferred-stack-boundary=2 meet.c -o meetThe results of this command are shown in the image below:
The command we used to compile meet.c had the following arguments:
| Argument | Meaning |
|---|---|
| -m32 | Compile into 32-bit mode. |
| -static | Compile the program statically, with all libraries included within the executable. |
| -ggdb3 | Include maximum debugging information. |
| -zexecstack | Allow an executable stack. Basically one part in overiding NX. |
| -fno-stack-protector | Disable stack corruption protections. Second part in overiding NX. |
| -mpreferred-stack-boundary=2 | Sets the size of each entry in the stack to 2^2=4 bytes long. This makes it easier four our data alignment purposes, since we will be dealing with 32-bit or 4 byte memory locations. |
Running the executable meet normally
We run the program meet normally with the arguments Mr Mark as follows:
$ ./meet Mr Mark
After issuing the command, we get the following output:
As can be seen from the above screen capture, the program prints out the memory addresses of the buffer we will overflow, which is the 400 byte buffer called name. It also prints out the memory addresses of the two arguments, temp1 and temp2. The astute observer will notice that these addresses are actually within the stack segment! Notice also that temp2 is exactly 4 bytes away from temp1.
The program then prints out the string Hello, followed by the program arguments. Finally, the program prints out the string Bye, followed by the program arguments.
Fuzzing the inputs to the executable meet
To find the size of the buffer, we will increase the number of bytes input into the second argument until the program begins to crash. Actually, we could have tried the first argument, but we would have found that the first argument is very resilient, since it is not actually taking part in the vulnerable strcpy command. This could have been surmised from reverse engineering the binary, if the source code was not available. Below we show what happens even when we inject 500 "A"'s into the first argument. In the second image, we will attempt to insert 2000 "A"'s and see what happens.
In the figure above, we first try 10 "A"'s and then 500 "A"'s, and nothing seems to break. Again, this is because only the second argument participates in the vulnerable strcpy command. To make absolutely sure, in the figure below, we inject 2000 "A"'s into the first argument of the executable meet.
In the figure above, nothing seems to break. We therefore focus on the second argument. Our goal is to find the size of the vulnerable buffer, so we start low and work our way up until we encounter a segmentation fault. This fault will indicate that our input has overwritten the return address of the the main function within the executable meet.
Still no segmentation faults. We continue increasing the number of "A"'s in the figure below.
We can see that we have found the segmentation fault after injecting 400 "A"'s into the second argument. 398 and 399 did not do it. From this we can surmise that the first argument "Mr" took two bytes and the second argument took 400 bytes, and this was enough to overwrite the main function's return address. Since the saved base pointer took four bytes and the saved return address took an additional four bytes, we have probably overwritten the saved base pointer, at which the main function used this corrupted base pointer for its stack frame operations. But since we have corrupted the saved base pointer, the program tried to access an invalid part of memory, and hence we obtained the segmentation fault.
From this we can surmise that the vulnerable buffer size is about 400 bytes. Let us fire up the Gnu DeBugger on the segmentation fault and see what happened. Before we do this, we install the PEDA extension for GDB to make life easier. This can be found at:
Python Exploit Development Assistance
We can see from GDB that the exact instruction that caused the segmentation fault was found at the address main+35:
The instruction attempted to load into EDX the contents of the memory address pointed to by EAX. We can observe that the contents of the registers was:
Looking specifically at EAX, it contained 0x41414149. 0x41 is the ASCII code for the capital A. We can see that when the CPU tried to access the contents of the memory location pointed to by EAX, we got the segmentation fault. This is because the memory address 0x41414149 is outside of the program's allowable access segments.
What appears to have happened is that the return address was not overwritten, because the program was able to return to main. However, it appears that argc and argv where overwritten by the buffer overflow. Recall that argc contains the number of arguments, including the command itself. In our case, argc would have been 2, since it starts at 0.
argv[ ] is an array of strings. Each string in argv are the arguments, where argv[0] is the command itself. In our case, argv[1] would have been "Mr" and argv[2] would have been 400 "A"'s. What we are really after is to overwrite EIP. To do that, we will have to add an additional 8 "A"s, which equals a total of 8 bytes. 4 of those bytes will overwrite the saved EBP, and the other 4 bytes will overwrite the saved EIP. We show the results of running meet with 408 "A"'s for the second argument in the screen shot below:
Now that we have found a way to overwrite EIP, we can basically get the processor to execute arbitrary code within the processes memory segment. If we could insert shellcode into the second argument, and then overwrite the return address to point to the start of the shellcode, then we will cause the process to spawn a shell. If this process was running under root privileges, then the shell will be a root shell, where we can basically control the entire system. Let us try to do this from the command line.
Inserting Shellcode into a Vulnerable Processs from the Command Line to Obtain a Command Shell
In this section, our goal is to try to insert shellcode into the vulnerable executable meet. We will then do the same thing in GDB to see exactly what happens.
We will approah this section by showing a successful attack of a vulnerable program from the command line, and then dissect every aspect of how this was achieved. In order to show how dramatic such an attack can be, we will escalate the privileges of the vulnerable program to that of super user (SUID). This will cause the vulnerable program to drop out of normal execution and into a command shell with root privileges.
By issuing the command:
$ sudo chmod u+s meetwe give the executable meet the privileges to execute at the root level.
NOTE!
We then inject our attack payload into the second parameter, because as discussed previously, the first parameter is not vulnerable to this attack. The attack and results are shown below:
SUCCESS!
By issuing the command:
$ sudo ./meet mr "$(perl -e 'print "\x90"x200'; cat sc; perl -e 'print "\x90"x27' ;perl -e 'print "\x18\xf2\xff\xbf"x38')"
we were able to overflow a buffer within the executable meet, and overwrite the return address. By doing so, we hijacked the instruction pointer EIP to execute our arbitrary code. In this case, our arbitrary code was shellcode, which provides a command shell. Since the executable meet ran at the root privilege level, once the shell is spawned, any command entered runs at the root privilege level.
We will now break down the attack string in great detail.
Breaking Down the Attack String in Detail
Use of the "$(cmd; cmd; cmd; cmd)" format
The attack string used the format:
"$(cmd; cmd; cmd; cmd)"
The shell command format $() replaces the unweildy backtick " ` " format, making an entered command much easier to read and understand. Individual commands within the parentheses can be separated by a semicolon. The quotation marks on the outside, i.e. "$()" tell the command shell to treat everything within the quotes as a literal string. See below for examples:
As can be seen from the above screen shot, putting separated commands into quotes causes everything contained within the quotes to be treated as a single string. This is a good property for injecting shellcode from the command line into a vulnerable executable.
We will now examine using $() and "$()" on the command line.
As can be seen from the screenshot above, putting commands separated by a semicolon within $(), causes the the output of the commands to be substituted into their place and the output to be executed by the shell. In the case of the first command date, the output is Sun, for Sunday, and the shell tries to execute Sun, but this is not a valid Linux command, so the command shell throws an error.
Alternatively, putting multiple commands separated by a semicolon within "$()" causes all of the commands to be executed, and the outputs of all of the commands are substituted in, wherein the shell tries to execute the outputs as if they were an actual shell command. That is why the shell returns an error in the screenshot above.
We will now put these concepts together to craft an attack string.
Using "$()" to craft an attack string
We begin by using two shell commands:
perl -e 'perl command'
xxd filename
These commands can be broken down as follows:
| Command | Meaning |
|---|---|
| perl -e 'perl command' | Execute perl command contained within the single quotes |
| xxd filename | Creates a hex dump of a given file or standard input. |
We will craft an attack string using perl commands and pipe the output of the attack string into xxd, to see whether the hexadecimal values align properly in memory and do not contain any bad characters, such a null byte, i.e. \x00, or the linefeed character, i.e. \x0a. The null byte is bad because many string processing functions in C interpret the null byte as the end of the string. So if our attack string contains a null byte in the middle of it, then only a portion of the attack string will enter into the vulnerable function. This will cause the attack string to fail. Likewise, the linefeed character will cause the parsing units of the string manipulation functions to interpret the linefeed as a user hitting the enter key. This will again cause premature failure of the attack string.
Let us try a simple example, such as:
In the above screenshot, we use the echo command to take the entire output of the commands within the "$()" and echo it to the screen. However, since we are using the unix pipe, the output is instead piped to the xxd command, which displays the hexadecimal values of the characters. Notice that there is a problem right at the end. There is a 0x0a character, which is the linefeed that the echo command affixes to the end. To suppress this trailing linefeed, the -n switch is used with the echo command. In the second issuance of the echo command, the trailing linefeed is suppressed, and we get a nice collection of hexadecimal values to fill 64 spots.
We can now move forward with constructing the attack string.
Putting it all together
Recall that the attack string was:
$ sudo ./meet mr "$(perl -e 'print "\x90"x200'; cat sc; perl -e 'print "\x90"x27' ;perl -e 'print "\x18\xf2\xff\xbf"x38')"
We will focus on everything contained within the "$()" by piping it into xxd and seeing what we are actually putting into the vulnerable buffer.
From the above screenshot, we can see that the attack string contains a prologue of 0x90 characters. The 0x90 is the hexadecimal value of the opcode for No OPeration, or the NOP. Since the CPU can not distingush data from executable code, the CPU begins executing the data as if it were code. This prologue of NOP instructions is called a NOP sled. The NOP sled is used to make it easier by relieving the requirement to be absolutely exact with the return address at the end of the attack string. The CPU's instruction pointer needs to be made to fall anywhere within this NOP sled, so that it will begin sliding down the NOP sled and eventually hit the shellcode. We have highlighted the shellcode for clarity. The shellcode was developed within another section of this website and can be found here:
Shellcode Generation
How can we make the CPU's instruction pointer point to somewhere in the NOP sled? This is where real hacking skill comes in. After the NOP sled and shellcode, we need to overflow the rest of the buffer with the memory address of the buffer.
From where do we get this address? In our case, we have access to the source code and debugging information. Without the source code and debugging information, we would need to engage in reverse engineering of the executable. This is not impossible, but obviously much harder to do. For our purposes here, we will work on the easier case of knowing the exact memory address of the buffer we wish to overflow.
In our easier case, there are two ways of finding out the memory address of the buffer we wish to overflow.
- Modifiying the source code to print out the memory address of the buffer.
- Using the debugger GDB to find out the memory address of the buffer.
This may seem to easy to many of you, and indeed it is. So we will also explore trying to overflow the buffer when knowing only the location of the stack pointer.
Discovering the memory address of the buffer we wish to overflow
We now explore how to discover the memory address of the buffer we wish to overflow. Recall that when running the vulnerable executable meet with normal inputs, we obtain the following output:
We can see from the above screenshot that the memory address of the buffer that we want to overflow is:
The address of the name array is: 0xbfffee28
The memory address 0xbfffee28 is what we need to append to the end of the shellcode enough times so that this address will overwrite the saved EIP. By doing so, when the CPU reaches the ret assembly instruction as it leaves the called function greeting, it will load the instruction pointer with the memory address 0xbfffee28, and then begin execution of the instructions there. Those instructions are the NOP sled, followed by our shellcode!
Of course, it is not always that simple. This address needs to be four byte aligned and input into the attack string in reverse order, since memory in IA32 is written in Little-Endian format. So in the case of 0xbfffee28, we would write it as \x28\xee\xff\xbf. In order to align the address to 4 bytes, we will need to add some NOP instruction padding so that the address 0xbfffee28 does not sit in the next byte location in memory after the shellcode, but rather in a fresh new 32 bit (4 byte) location. Otherwise, this address will be a shifted version of itself when the CPU tries to read it off of the stack. In that case, the address may be read as 0xee28bfff or 0xffee28bf. I both of those cases, the program will most certainly crash with an out of bounds or illegal instruction segmentation fault.
Note that this address may change slightly with each execution of the program meet; therefore, some persistance is necessary when attacking from the command line. We will now explore using the debugger GDB for finding out the address of the buffer we want to overflow. Refer to the screenshot below:
We can see from the GEF User Interface (UI) to GDB that we are at the vulnerable strcpy function:
strcpy (name, temp2); // copy the function argumemt to name
By the C calling convention, arguments passed to a function are pushed onto the stack in reverse order. We can see from the screenshot that temp1 is at ESP+8, ESP+4 contains the memory address of temp2 and at ESP we have the memory address of the local variable name. In this case, the memory address is 0xbfffea58. Note that we are looking for the memory address of the local variable name, NOT what the register ESP (stack pointer) points to, but rather what is at the memory address that the ESP points to. In other words, ESP points to an address on the stack, 0xbfffea50, and at this memory address, there is stored another memory address which is 0xbfffea58. The contents of the memory location at the address 0xbfffea58 is the value 6, which is really just a random value, since the local variable name is uninitialized.
To confirm these statements, we observe the stack after the strcpy function returns.
We can see from the above screen shot that the passed argument temp2, at stack memory location 0xbfffea54, has been copied to stack location 0xbfffea50. These correspond to ESP + 4 and ESP respectively.
We also observe that the function strcpy returns a pointer to a character (i.e. a string), and by convention, this pointer is returned into the register EAX. From the Linux man page for strcpy:
char *strcpy(char *dest, const char *src);
We can observe from the above screenshot that the returned value into EAX is: 0xbfffea58, which is the memory address of the local variable name on the stack. This is the memory address of the buffer we need to overflow.
Calculating how many bytes we need to inject into the vulnerable buffer to overwrite the instruction pointer EIP.
So how many attack string bytes do we need to put onto the stack? We will need to fill up 400 bytes of the buffer called name. This is the local variable in the function greeting. Then we need 400 bytes for the argument passed to the function greeting called temp2, 4 bytes for the argument passed to the function greeting called temp1. Finally we need 4 bytes for the saved EBP. That is a total of 808 bytes. The next 4 bytes that we must overwrite is the saved instruction pointer EIP.
See the below screenshots for the state of execution just before the saved EIP is popped off of the stack, and execution is supposed to return back to the main function in the executable meet. Execution never returns to the main function, but instead the shellcode is executed.
State of execution just before the saved EIP is popped off of the stack, and execution is supposed to return back to the main function in the executable meet, according to the GEF UI for GDB.
We can see from the above screenshots, for both the PEDA GDB UI and the GEF GDB UI, that the memory address of the name local variable is: 0xbfffef3a. However, the address of the top of the stack is different. For GEF it is 0xbfffebec, and for PEDA it is 0xbfffec0c. This discrepancy was caused by the executable meet being started as two different processes, each with its own address space. One process was started for GEF, and another one for PEDA.
Therefore we should not be surprised that the top of the stack is different on each invocation of an executable, even with address randomization turned on. To make the calculation, we simply subtract the address of the top of the stack from the address of the buffer. In both cases, we obtain the following calculations:
| GDB UI Name | Memory Address of Buffer | Memory Address of Top of Stack | Difference in Hex [bytes] | Difference in Decimal [bytes] |
|---|---|---|---|---|
| GEF | 0xbfffef3a | 0xbfffebec | 0x34e | 846 |
| PEDA | 0xbfffef3a | 0xbfffec0c | 0x32e | 814 |
Stated mathematically, we have:
GEF 0xbfffef3a - 0xbfffebec = 0x34e bytes = 846 bytes
PEDA 0xbfffef3a - 0xbfffec0c = 0x32e bytes = 814 bytes
The astute reader will notice that we calculated the theoretical number of bytes needed to overwrite the saved EIP was 812 bytes. However, in both cases, GEF and PEDA, we have more than 812 bytes. The reason is that we are allowed to overwrite even through the top of the stack, as long as the saved EIP is overwritten with the address of the overflowed buffer, and this address is aligned correctly to 4 bytes. If it is misaligned, then instead of reading 0xbfffef3a from the top of the stack, the CPU might read a shifted version of this. If this happens, the CPU will jump to this shifted version of the address that we want, and will most likely halt on a segmentation fault.
In order to verify that the attack string arranges its return addresses correctly aligned to 4 bytes, we could do a number of things. Within GDB, we could simply issue the following command:
Referring to the screenshot above, we wanted to observe the contents of stack memory starting at ESP and going down by 812 bytes. Notice that since the stack grows downward, we need to do the opposite operation, and add 812 bytes, rather than subtract. To look at a byte, we need two hexadecimal digits; therefore, looking at 300 hexadecimal digits will show us 900 bytes. This will enable us to see our entire attack string in stack memory, with some margin. To accomplish this, we enter the following command:
(gdb) x/300x $esp+812
Notice from the above screenshot that there is a NULL byte just ahead of our NOP sled. Since we are aiming for the middle of the NOP sled, this leading NULL bytes is of little consquence. Now that we have discovered the address of the vulnerable buffer, and figured out how many bytes we need to inject into it for a successful buffer overflow, we will now look at how to discover the stack address from the command line.
Discovering the memory address of the stack
Variations in the top of the stack with multiple attack attempts from the command line
Before we can figure out the return address to place onto the stack so that we can successfuly overwrite the saved EIP, we need to know the current address of the stack. This is a little bit tricky, because every time the attack is attempted, the stack address changes a little bit, even with ASLR turned off. The reason is that Linux tries to reclaim memory after the failed attack completes, and other processes are always executing at the same time, so the stack address tends to shift around a bit, by about 500 to 1000 bytes.
While this is not a large range, it is enough to render the attack string useless, as it will probably crash with a segmentation fault, or the attack will simply be ignored. This all depends on which way the top of the stack has shifted in memory. However, command line attacks are still possible as the stack will most likely stay at the same location for a few attempted attacks.
In the next section, we will demonstrate a small C program that can print out the current memory address of the stack.
Discovering the memory address of the stack
A small program that displays the current state of the stack pointer
To discover the address of the stack segment in memory, we use the program listed below
The program uses inline assembly within C. By convention, a the return value of a C function returns is contained within EAX. By calling the function get_sp, the ESP register is copied to EAX and returned to the printf statement. In this way, we obtain what is contained within ESP, the top of the stack.
This returned value is printed out as a memory address via the 0x%x format string. The screenshot below will display the output of running this program a few times.
Now that we have the address of the stack, or ESP, we can now make the calculation to figure out the return address that we want to append to the end of our attack string. We use our trusty HP48G calculator emulator for this purpose.
Referring to the above calculator images: in (A) we have the address of the stack, 0xbfffee98 and 812 bytes that we will subtract; in (B) we have the same as in (A), but the 812 in decimal was converted to hex for clarity; and in (C) we have the result of the subtraction.
Lorem
Lorem
Lorem
Lorem
Lorem
Lorem
Lorem
Lorem
Lorem
Lorem
Lorem
Lorem
Lorem
Lorem
Lorem
Lorem
Lorem
Lorem
Lorem


My vision is to change the world in terms of technology so that there could be peace and to minimise corruption


Determine your age, life expectancy and years left to live on different planets
Age on Earth: years.
Age on Mercury: years.
Age on Venus: years.
Age on Mars: years.
Age on Jupiter: years.
Life expectancy on Earth: years.
Life expectancy on Mercury: years.
Life expectancy on Venus: years.
Life expectancy on Mars: years.
Life expectancy on Jupiter: years.
You have years left on Earth.
You have years left on Mercury.
You have years left on Venus.
You have years left on Mars.
You have years left on Jupiter.


Maram Alroshoud
Front-end Ninja
Featured Work
Mockup to Article
Link to project
Animal Trading card
Link to project
My Portfolio
Link to project


Department of Education to offer Hawaiian courses to employees | Honolulu Star-Advertiser
The state Department of Education plans to offer free Hawaiian language courses to all of its employees, beginning in January. Read more
Mahalo for reading the Honolulu Star-Advertiser!
You're reading a premium story. Read the full story with our Print & Digital Subscription.
Already a subscriber? Log in now to continue reading this story.
Print subscriber but without online access? Activate your Digital Account now.


Pair Programming and Feedback
January 25, 2015
One of the core features of DBC is pair programming, a learning style in which two programmers collaborate on a project or challenge. One person drives -- writes code-- while the other navigates-- guides and reviews the code. During Phase 0, most of, if not all, of our pairing sessions are done remotely via Skype, Google+ and Google Hangouts. In addition to working on a challenge together, the real challenge, I felt, laid in communicating clearly and effectively since we wouldn't be able to rely on body cues or simply pointing to the line of code we were referencing.
At the start of Phase 0, I can honestly say that I did not look forward to pairing. I had spent the last few months learning to program mostly independently and though I didn't mind working with someone else, I preferred going it alone. But mostly, I was filled with doubts about myself and my skill. What if I was totally lost and couldn't express myself clearly? Would my pair feel like I was dragging them down? Normally, I would pore over research until I got the solution, but would that be okay here? Would they look down on me because I didn't know? Moreover, after each session we would have to submit anonymous feedback for our pairs. Ah, now we'd be graded by our peers too? Sigh, I felt very self-conscious.
But my fears weren't realized. These pairing sessions turned out to be one of the highlights of Phase 0. Sure we couldn't work together in person and sometimes our skill level was uneven, but it was a time when we could be open and ask each other questions and revel in our collaborative successes. Sometimes, I would completely overthink an approach, but my pair would come up with something brilliant and even better. I loved the fresh perspective I would get. Even when my pair wasn't sure of a concept, it was an opportunity to ground out the weaknesses and holes I had. Best of all, I made some great friends and felt okay to be vulnerable.
After my first couple pairing sessions, I was eager to get my feedback. Was I too anal about a concept? Did I come off too aggressively? We had to submit feedback through DBC's Feedbackinator. It would take a few days to receive our own because they underwent a peer review process to see if they were actionable, specific and kind. Kind has an element of truth that distinguishes itself from niceness.
In preparation for this blog post, I went through all of my feedback charting the positive and critical ones. I was taken aback by how genuinely nice some of the feedback were. However, the critical pieces were the ones I agreed on. I knew my faults already. I can be a little impatient, tend to rush without fully explaining every detail of my approach, and fall silent when at an impasse. Reading these made me nod my head in agreement. Perhaps if I didn't schedule some of my sessions before work, I wouldn't feel so rushed? They make me want to improve myself and my approach. Good communication. Patience. These are attributes that are vital to my career as well as building strong relationships.
Writing feedback proved to be a tougher than reading them. Making sure that what I critiqued was actionable and specific took more thought. I check out how others perceive my feedback through Meta Feedback. Sometimes people felt it wasn't specific or actionable enough; other times, they were. However, the more feedback I give, the easier it's becoming. I look forward to pairing more often with my peers to see how much we all grow from this experience.


{% ckan_extends %} {% block footer_content %}
An open source project by the Natural History Museum's Biodiversity Informatics Group.
Source code available on Github.
Base tiles by MapQuest and © OpenStreetMap contributors.


The most current doucmentation for MT-SPA can be found at: http://www.everitz.com/sol/mt-spa/install.php You should be redirected automatically in 3 seconds.


|
SideCar
|
Multicast data reader of BugPlot messages. More...
#include </Users/howes/src/sidecar/Algorithms/BugCollector/BugPlotSubscriber.h>
Public Member Functions | |
| BugPlotReader (BugCollector &bugCollector) | |
| Constructor. More... | |
| bool | openAndInit (const Zeroconf::ServiceEntry::Ref &service) |
| Attempt to establish a multicast connection to the BugPlot publisher described by the given ServiceEntry object. More... | |
| int | close (u_long flags) |
| Unsubscribe from the BugPlot publisher. More... | |
| int | handle_input (ACE_HANDLE handle) |
| Event handler invoked when data is available on the subscription socket. More... | |
| ACE_HANDLE | get_handle () const |
| Obtain the socket descriptor for the connection. More... | |
| const std::string & | getServiceName () const |
| Obtain the name of the publisher we are subscribed to. More... | |
| void | sendHeartBeat (const char *msg="HI") const |
| Send a heartbeat message to the remote bug emitter to keep it sending data to us. More... | |
Multicast data reader of BugPlot messages.
Created by a BugPlotSubscriber instance whenever it detects a new BugPlot publisher. Forwards each incoming BugPlot message to the BugCollector algorithm it knows about via its BugCollector::process() method.
Definition at line 25 of file BugPlotSubscriber.h.
| BugPlotReader::BugPlotReader | ( | BugCollector & | bugCollector | ) |
Constructor.
Only performs simple initialization.
| bugCollector | the Bugcollector algorithm to forward BugPlot messages to |
Definition at line 21 of file BugPlotSubscriber.cc.
| int BugPlotReader::close | ( | u_long | flags | ) |
Unsubscribe from the BugPlot publisher.
| flags | ignored |
Definition at line 94 of file BugPlotSubscriber.cc.
References SideCar::Algorithms::Algorithm::getLog(), and sendHeartBeat().
| ACE_HANDLE BugPlotReader::get_handle | ( | ) | const |
Obtain the socket descriptor for the connection.
Definition at line 111 of file BugPlotSubscriber.cc.
References SideCar::IO::ReaderDevices::MulticastSocket::getDevice().
|
inline |
Obtain the name of the publisher we are subscribed to.
Definition at line 71 of file BugPlotSubscriber.h.
References sendHeartBeat().
| int BugPlotReader::handle_input | ( | ACE_HANDLE | handle | ) |
Event handler invoked when data is available on the subscription socket.
| handle | socket identifier |
Definition at line 67 of file BugPlotSubscriber.cc.
References SideCar::IO::DatagramReader::fetchInput(), SideCar::Algorithms::Algorithm::getLog(), SideCar::IO::Reader::getMessage(), SideCar::IO::Reader::isMessageAvailable(), LOGDEBUG, and SideCar::Algorithms::BugCollector::process().
| bool BugPlotReader::openAndInit | ( | const Zeroconf::ServiceEntry::Ref & | service | ) |
Attempt to establish a multicast connection to the BugPlot publisher described by the given ServiceEntry object.
| service | description of the BugPlot publisher to subscribe to |
Definition at line 30 of file BugPlotSubscriber.cc.
References SideCar::Zeroconf::ResolvedEntry::getHost(), SideCar::Algorithms::Algorithm::getLog(), SideCar::Zeroconf::ResolvedEntry::getPort(), SideCar::Zeroconf::ResolvedEntry::getTextEntry(), SideCar::IO::ReaderDevices::MulticastSocket::join(), LOGERROR, and sendHeartBeat().
Referenced by SideCar::Algorithms::BugCollectorUtils::BugPlotSubscriber::setPrefix().
| void BugPlotReader::sendHeartBeat | ( | const char * | msg = "HI" | ) | const |
Send a heartbeat message to the remote bug emitter to keep it sending data to us.
| msg | the message to send (either "HI" or "BYE") |
Definition at line 104 of file BugPlotSubscriber.cc.
Referenced by close(), getServiceName(), and openAndInit().


Rocket science
Rocket science
See a miracle of the machine trying to learn how to control the rocket
Or try to fight against the gravity by your own


{% extends "base.html" %}
{% block title %}Download User Private SSH Key{% endblock title %}
{% block content %}
Download private SSH key for {{ curr_user.username }}
Your SSH key pair has been generated successfully. Your private SSH key is available for ONE time download only. Keep it safe as this key cannot be recovered if lost.


In a 6-3 decision, the Supreme Court sided with Dobbs, who was the head of the Mississippi Health Department in 2018. This decision is based on the idea that access to abortion is not a constitutional right because, in fact, there is no inherent right to privacy or personal autonomy in the Constitution. Now that precedent has been set that there is no constitutional right to privacy, many other U.S Supreme Court cases are subject to be re-examined that could result in a major set-back to the civil rights movement. These include, but certainly not limited to, legality of same-sex marriages, inter-racial marriages, and contraception.
in-context


com.example.geocomment
Class R.id
java.lang.Object
com.example.geocomment.R.id
- Enclosing class:
- R
public static final class R.id
- extends java.lang.Object
|
Constructor Summary |
R.id()
|
| Methods inherited from class java.lang.Object |
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
LinearLayout1
public static final int LinearLayout1
- See Also:
- Constant Field Values
action_new_picture
public static final int action_new_picture
- See Also:
- Constant Field Values
action_settings
public static final int action_settings
- See Also:
- Constant Field Values
add_text
public static final int add_text
- See Also:
- Constant Field Values
button1
public static final int button1
- See Also:
- Constant Field Values
button2
public static final int button2
- See Also:
- Constant Field Values
comment
public static final int comment
- See Also:
- Constant Field Values
commentBy
public static final int commentBy
- See Also:
- Constant Field Values
commentListView
public static final int commentListView
- See Also:
- Constant Field Values
comment_box
public static final int comment_box
- See Also:
- Constant Field Values
create_new_comment
public static final int create_new_comment
- See Also:
- Constant Field Values
date_added
public static final int date_added
- See Also:
- Constant Field Values
editText1
public static final int editText1
- See Also:
- Constant Field Values
imageView1
public static final int imageView1
- See Also:
- Constant Field Values
optionId
public static final int optionId
- See Also:
- Constant Field Values
pic_image_view
public static final int pic_image_view
- See Also:
- Constant Field Values
settings
public static final int settings
- See Also:
- Constant Field Values
sortList
public static final int sortList
- See Also:
- Constant Field Values
submit_comment
public static final int submit_comment
- See Also:
- Constant Field Values
textView1
public static final int textView1
- See Also:
- Constant Field Values
tvtitle
public static final int tvtitle
- See Also:
- Constant Field Values
R.id
public R.id()


MARCEdit
Tool Creator/Maintainer
Created and maintained by Terry Reese, currently a librarian at Ohio State University.
Abstract
MarcEdit allows for several use cases:
- Edit and transform metadata files from and to MARC records
- Converts MARC21 to eye-readable text format
- Validate MARC records
- Generate reports (e.g. count of field presence in a record set),
- Send metadata to an SQLite or MYSQL database and run queries
Documentation
| Site URL | Source Code URL | Documentation URL |
|---|---|---|
| http://marcedit.reeset.net/ | http://marcedit.reeset.net/downloads | http://marcedit.reeset.net/ |
Analysis
| Task | Metric | Completed successfully? |
|---|---|---|
| User can check for the presence of an element, attribute, or value | Completeness | |
| User can implement spell-checker technology for metadata values | Accuracy | |
| User can check for appropriate grammar and language syntax | Accuracy | |
| User can confirm that descriptive metadata accurately describes content | Accuracy | |
| User can check when/how metadata was created or changed via versioning tools | Provenance | |
| User can check when/how metadata was created or changed; the source of the metadata; the content standard, cataloging rules, or metadata application profile used by querying a specific element | Provenance | |
| User can confirm the values adhere to element datype formatting expectations (e.g. date formatting, time formatting, strings, numbers) | Accessibility | |
| User can determine what controlled vocabulary was used by querying an element attribute or tag subfield | ||
| User can dtermine correct element usage according to established profile definitions | ||
| User can check that data is well-formed in order to be correctly parsed by a machine | ||
| User can check for inaccurate character encodings | ||
| User can cluster, facet, or generate value sets to confirm that values meant to refer to like concepts or agents are consistently applied | ||
| User can perform reconciliation services to match element values against published entities | ||
| User can check for outdated, offensive, or biased terminology | Timeliness | |
| User can confirm that adequate information is available for locating or accessing a target object |
Analysis Notes
Some more explanatory text can go here.


Flooring Epoxy Resin
Epoxy flooring is made up of two main components – resins and hardeners. When these two components are combined, a chemical reaction takes place that forms a rigid epoxy material. This epoxy material bonds with the substrate. When it cures, it provides a strong, hard-wearing coating that protects concrete from both mechanical and chemical stress.The concrete is no longer porous, making it easy to clean.
Benefits of Epoxy Flooring
- Hard-wearing and durable – resistant to wear even in high traffic areas and industrial environments
- Attractive fashionable finish – epoxy comes in a range of different colours and finishes, which can be used by professional installers to create designs & patterns to match your style requirements.
- Non-dusting – can be applied over concrete floors to prevent issues with concrete dust in unsealed floors
- Damp Proof Membranes – for installation where a DPM has never been installed or has broken down over time
- Provides a smooth and even surface
- Easy to clean – low maintenance floor option
- Affordable – a cost effective flooring option. Click to find out more about the costs of epoxy flooring
- Highly resistant to chemicals – chemically resistant even to potent chemicals
- Heat and water-resistant
- Safe – anti-slip properties & resistant to extreme impact
Applications
Epoxy resin flooring can be used for both commercial and residential purposes. There are several key considerations when using it in different situations. It may be that you need a higher grade flooring in some industrial settings and that epoxy flooring isn’t suitable in all domestic settings.
- Commercial Uses
- Warehouses & Industrial Units
- Gyms
- Offices
- Residential Uses
- Garages
- Kitchens
- Basements
Epoxy Flooring Installation
1. Preparation
Floors Should Be Prepared
To install epoxy floor coating, you will need to prepare the surface of the room first. There are two suitable methods to do that, which are diamond-grinding and sanding. You can use a floor grinder that can polish concrete floors. For surfaces that are contaminated with any kind of liquid, you may need to apply chemical cleaning in order to remove the stains.
Remove Dust Particles
After grinding the surface, you will need to remove all of the dust that the floor grinder created. Sweep up the floor to gather most of the dirt and clear it away from the area. To extract the small dust particles remaining on the prepared ground, you will need to use an industrial vacuum. This must be done in order to apply less primer. If you leave a lot of particles on the surface, it will be trapped within the epoxy coat and will have less durability.
2. Base Coat
Apply Epoxy Primer
After removing most of the dust particles, it is time to prime the floor with the epoxy primer . It is highly recommended to administer this step because it can give your surface a longer life. It can give better adhesion to the main layer, which is the epoxy coating. The substrate will be sealed with priming, which results in the elimination of unnecessary gasses and bubbles.
Before applying the epoxy primer, make sure the room is well ventilated. To properly seal the surface, always coat two layers of the product. An electrical mixer is recommended in order to mix the two components of the application well.
We recommend using a DECOCOAT Primer if the concrete slab may be contaminated in any way. The primer is applied before the epoxy floor coating and helps ensure the main floor coating bonds well. On a clean floor you can use this as a primer. As this is a low viscous product, it has better penetration into the concrete. You can then use the DECOCOAT Top Coat Floor Coating to add the hard-wearing and high gloss finish.
3. Topcoat
Remember to mix the components properly because the result will define its durability. Weak and tacky coatings are the product of a poor fusion of contents.
Use a Roller for Product Application
To apply the epoxy coating on your floor, you should use a good quality roller that can last a long time. Poor quality ones tend to shed, which could damage the application. Re-coat the ground after 24 hours. If you see any cracks or holes after the first process, seal them up with the proper materials before the next coat. Surfaces that look uneven should be sanded first with the right tool.
Apply Final Coat
After reviewing the surface for issues like cracks and holes, you can now administer the final coat. Make sure to mix only one bucket at a time due to the epoxy floor coating’s short pot life.
A minimum of two coats is advisable for the best coverage and colour results. You should also use the correct primer if the surface is contaminated.
If your concrete is entirely free from oil and any other contaminates, you can use one coat of the standard epoxy and one coat of HB.
- DECOCOAT Primer – 50 microns
- DECOCOAT Top Coat - 2 to 3 mm


First load of laundry on a new continent and we already have two unmatched socks. 😡 7/26/2018, 4:54:22 AM Favs: 2 Retweets: 0 link
Apparently one sock had been appropriated to hold shells from the beach. Naturally. 🐚 7/26/2018, 11:17:41 AM Favs: 1 Retweets: 0 link


new ModelPanel(PanelName) → {PJP.ModelPanel}
Provide a panel for viewing system models. Currently, this panel displays
bond graph of different system model in the form of interactive SVG diagram. Interactions with
the SVG is implemented in SVGController.
Parameters:
| Name | Type | Description |
|---|---|---|
PanelName |
String | Id of the target element to create the PJP.ModelPanel on. |
- Source:
Returns:
- Type
- PJP.ModelPanel
Methods
enableSVGController(panelName)
Create and enable SVGController on the provided panelName, if no element with the id is found,
try after loadHTMLComplete is completed.
Parameters:
| Name | Type | Description |
|---|---|---|
panelName |
String | Id of the target element to create the PJP.SVGController on. |
- Source:
openModel(svgName)
Display model with the provided name, this function also updates the "run simulation" link.
Parameters:
| Name | Type | Description |
|---|---|---|
svgName |
String | name of the svg. |
- Source:
(async, inner) initialise()
Initialise loading of the page, this is called when
the PJP.ModelPanel is created.
- Source:


JavaScript needs to be enabled for the viewer to work!
DICOM Whole Slide Image Viewer
Studies
Series
Images


Awesome King List
Awesome King List
A bunch of people creating open source software. Star+Fork a project and get involved!
Want to help? Send us a message or help us with the open issues
A bunch of people creating open source software. Star+Fork a project and get involved!
Want to help? Send us a message or help us with the open issues


{% extends "real_base.html" %} {% load i18n %} {% block content %}
An Error had ocurred while we were trying to send the recommendation message to your friend.
Just for a hint for you we put the error here: {{ErrorMessage}}
{% endblock %}


In this level, you can see an example of Bob sending Alice an encryption key in order to protect their messages. However, their simple protocol is vulnerable to a man-in-the-middle attack.
Eve has control over a router between Alice and Bob. She can see all messages that pass through this router and she can spoof messages from either Alice or Bob.
To beat this level, you need to trick Alice into encrypting her messages using a key Eve knows: 31337. You must also trick Bob into thinking he is having a conversation with Alice as normal! See if you can figure out how to trick them both without them discovering your presence between them.
Hint: there is an example of how the encryption protocol works at the top of the field. Use the
button to see what the values of the packet headers are in the protocol.


This demo is exactly the same as the previous Demo : a REST client looking for new Tweets about Android.
The only difference is that we don't store the Tweets in cache using JSON, but we use ORM Lite to store them in a SQLite Database.
All mapping and table creations are handled automatically by RoboSpice.


A Dictionary is a generic class of C# that is used to represent the collection of (key, value) pairs.
Dictionary class is present in System.Collections.Generic namespace
When creating a Dictionary
Keys in the dictionary must be unique and cannot be null.
Dictionary provides fast lookups for values using keys.
Dictionary has three properties- Count, Key and Values.
It is faster than HashTable.
It will generate error if we try to use a key that is not exist in the collection.
It is a generic type so we can use any type of data.
When creating a Dictionary
The moment we create key it asks for type of key. Since Dictionary is generic so it can be any datatype.
For Example:
The following coding snippet adds items to the dictionary
For Example:
We can also limit the size of the dictinary. The following code snippet creates a dictionary where the key type is int and value type is string and total number of items it can hold is 3.
For Example:
The Dictionary is a Collection. We can use the foreach loop to go through all the items and read them using the key and value properties.
For Example:
The Count property gets the number of key/value pairs in Dictionary.
The following Code snippet displays the number of items in Dictionary.
For Example:
To Count the number of key/value pairs in Dictionary with user defined criteria, we will use Overloaded Count() function.
For Example:
The keys property gets a collection containing the keys in the Dictionary.
For Example:
Searching a Element by using the key. If the Element is present it will return the value.
For Example:
Incase, If the given key doesn't present in the Dictionary it will through an Exception. So, this exception is solved by TryGetValue().
In TryGetValue() function we will pass two parameters. One is In Parameter and other is out Parameter.
The In Parameter is the key we want to search. The out parameter is the value associated with the key.
The return type is Boolean. If the key is found, It will return True and the Value is passed through out parameter or else it will return false.
For Example:
The Remove method removes an item with the specified key from the Collection.
For Example:
The List is converted to Dictionary by using the ToDictionary extension. Here,the ToDictionary extension is used from System.Linq to set keys and values with a lambda. ToDictionary converts a collection into a Dictionary. It works on IEnumerable collections such as arrays and Lists.
For Example:


We live in a world of mobile chaos, where companies are forced to manage a growing diversity of portable devices, ensure seamless access to enterprise apps and enforce unified security policies. BYOD is the new reality; business users expect the freedom to work wherever, whenever and from whatever device they like. If your systems aren’t up to task, mobile chaos ensues.
Sound familiar? If so, you’ve come to the right place for help. “Embracing Mobile Chaos” is all about regaining control over your mobile infrastructure. This site features a multitude of videos, downloads and resources to help you along the way. There are also opportunities to connect with your peers via Twitter directly on the site. And don’t miss your chance to win a BlackBerry PlayBook--we’re giving one away every week! Read on for details.
What does mobile chaos mean to you? Have you suffered a terrible experience while trying to gain control over the mobile technology and devices in your organization? We would like to reward you for your pain and suffering.
Share your mobile chaos story with us today for a chance to win a free BlackBerry PlayBook. Each week Brian Madden will review the entries and create a new video based on the winning story.
What does mobile chaos mean to you? Have you suffered a terrible experience while trying to gain control over the mobile technology and devices in your organization? We’d like to reward you for your pain and suffering. Share your mobile chaos story with us today for a chance to win a free Blackberry Playbook. Each week Brian Madden will review the entries and create a new video based on the winning story.


--- layout: page weight: 0 title: Categories navigation: show: true ---
Categories help organize your email analytics by enabling you to tag emails by type.
Just as you can view the statistics on all your activity under the 'Statistics' tab, you can go a step further and view the statistics on a particular category.
The events that can be associated with category include:
The actual statistics included vary depending upon the set of enabled Apps. Emails sent, bounces and spam reports will always get tracked. Unsubscribes, Clicks, and Opens require that the associated App is enabled.
{% warning %} Categories must be in 7bit encoding using the US-ASCII character set. {% endwarning %} {% info %} Currently, there is no limit to the number of categories you can track. {% endinfo %} {% info %} Categories should be used to group messages together. If you need to attach unique data or identifiers to a message, use Unique Arguments instead. {% endinfo %} {% anchor h2 %} Example {% endanchor %}You can use SendGrid's SMTPAPI to add these categories to your email. The following should be added to the email's header:
{% codeblock lang:json %}{ "category": "Example Category" } {% endcodeblock %}In this example, SendGrid would associate statistics for the email containing that header with the category Example Category.
You can assign multiple categories per message, up to 10:
{% codeblock lang:json %}{ "category": [ "dogs", "animals", "pets", "mammals" ] } {% endcodeblock %}


|
cds
1.2.0
|
Implementation of opt::sizeclass_selector option. More...
#include <cds/memory/michael/allocator.h>
Public Types | |
| typedef unsigned int | sizeclass_index |
| Type of size-class index. |
Static Public Member Functions | |
| static sizeclass_index | size () |
| Returns size-class count. | |
| static size_t | page_size (size_t nPageType) |
Returns page size in bytes for given page type nPageType . | |
| static size_t | pageTypeCount () |
| Returns count of page size-class. | |
| static sizeclass_index | find (size_t nSize) |
Returns size-class index for nSize . | |
| static const size_class * | at (sizeclass_index nIndex) |
Gets details::size_class struct for size-class index nIndex . |
Static Public Attributes | |
| static const sizeclass_index | c_nNoSizeClass = (unsigned int) (0 - 1) |
| "No size class" index |
Implementation of opt::sizeclass_selector option.
Default size-class selector can manage memory blocks up to 64K.
|
inlinestatic |
Returns size-class index for nSize
.
For large blocks that cannot be allocated by Michael's allocator the function must return -1.
|
inlinestatic |
Returns count of page size-class.
This class supports pages of two types: 64K page for small objects and 1M page for other objects.


When & Where
SRCCON 2018 takes place June 28 & 29, 2018, at the McNamara Alumni Center on the University of Minnesota campus in Minneapolis. You can also check out how our schedule works.
Lodging
Our conference rate at the The Graduate Hotel has expired, but you can call<PHONE_NUMBER> to inquire about any rooms that might still be available.
Other hotels not far from the conference venue include:
Days Hotel
.3 miles away
2407 University Ave SE
Minneapolis, MN 55414 US
(612) 623-3999
University Inn
1 mile away
925 4th Street SE
Minneapolis, MN, 55414, United States
(612) 746-1300
Courtyard Marriott Downtown
1.2 miles away
1500 Washington Ave S
Minneapolis, MN 55454
(612) 333-4646
Aloft Minneapolis Hotel
3 miles away
900 Washington Avenue South
Minneapolis, Minnesota, 55415
(612) 455-8400
Room share
Have a room and looking for a roommate? Don’t have a room and looking for someone who does? Add your info to the room share list.
Childcare
We offer free, on-site childcare throughout the full SRCCON schedule (including Thursday evening) at the adjoining Graduate Hotel. The caregivers act as employees of KiddieCorp (not contractors) and are recruited from local licensed daycare centers, elementary schools, preschools, and collegiate departments of early childhood education. Learn more about our free childcare now.
Transit
The Minneapolis METRO system is an easy way to get around the city. You can ride light rail from the airport to the conference hotel for $2: Follow the light rail signs to the airport tram, which will take you right to the light rail station. Take the northbound (“Downtown Minneapolis”) Blue Line to the U.S. Bank Stadium station, then cross to the other track to transfer to the eastbound Green Line. Take the Green Line two stops to East Bank. You’ll be looking right at The Graduate Hotel. The McNamara Alumni Center conference venue is another block past the hotel, on SE Oak Street.
Parking
Transit in Minneapolis is great, but if you’ll be driving, there’s a lot right near the McNamara Alumni Center. Parking is $12/day.
Travel from outside the U.S.
For folks who are coming in from outside the U.S., we recommend the EFF’s guide to protecting your data at the U.S. border for details on what to consider at the border crossing. If you need any further help or have any questions, please email us.
Food, Evenings, and More
We want you to be happy and well-fed at SRCCON, so we’re providing breakfast and lunch on both days, as well as a delicious dinner Thursday night. We’ll also have tea, coffee, and snacks—healthy and sugary—throughout the day, so stick around and enjoy the company of your fellow attendees.
We’ll have a slate of activities on Thursday evening, and you can learn more about the many ways to participate in SRCCON, before, during, and after the event!


ORDER BY state_id DESC LIMIT 0, 5
return recorder.query_states(query, (entity_id, ))
def get_significant_states(start_time, end_time=None, entity_id=None):
Return the last 5 states for entity_id.
entity_id = entity_id.lower()
states = recorder.get_model("States")
return recorder.execute(
recorder.query("States").filter(
(states.entity_id == entity_id) &
(states.last_changed == states.last_updated)


Former lifeguards save Swiss woman from drowning
by Canny MaphangaA 62-year-old woman from Switzerland was saved from a drowning at Cape Vidal on Wednesday, the National Sea Rescue Institute (NSRI) revealed in a statement on Wednesday.
"At 14:42, the NSRI St Lucia duty crew were activated following reports of a drowning in progress at Cape Vidal. NSRI rescue swimmers and paramedics responded," spokesperson Craig Lambinon explained.
However, the woman had been rescued by two former lifeguards, according to bystanders.
"After being caught in rip currents while swimming, [she] was treated by NSRI St Lucia medics and by paramedics and transported to hospital in a stable condition by a Netcare 911 ambulance as a precaution for observation for non-fatal drowning symptoms," Lambinon said.
The woman was accompanied by her husband to the hospital.
The NSRI commended those who had assisted her, Lambinon said.


Function
| Static Public Summary | ||
| public |
accountMeta(data: object, config: object): object Returns meta data from Steem account data |
|
| public |
formatImage(data: string | object): string Extract the first image or potentially featured image for a post |
|
| public |
formatPayout(post: object, fix: number): number Formats a Steem post's payout, does not discriminate for pending or completed posts. Values are for SBD |
|
| public |
Formats a Steem account's reputation |
|
| public |
formatVests(account: object): number Formats a Steem account's vests |
|
| public |
Formats a Steem post's active votes
Will sort out removed votes, and order by weight
Will trim return array to specified or default |
|
| public |
formatVotingPower(account: object): number Formats a Steem account's voting power using the manarbar data |
|
| public |
Returns meta data from Steem post or account data |
|
| public |
Parses a Steem post object or array of Steem post body strings or objects |
|
| public |
Parses a Steem post object or body string |
|
| public |
async parsePosts(content: array, options: object): array Parses multiple Steem post objects or body strings |
|
| public |
Returns meta data from Steem post data |
|
| public |
Returns an object of sorted Steem votes by upvotes, downvotes and removedvotes |
|
| public |
validateAccount(username: string): string | boolean Validates a Steem account username |
|
| public |
Returns stats about a Steem votes object |
Static Public
public accountMeta(data: object, config: object): object source
import {accountMeta} from 'steem-utils/lib/meta.js'
Returns meta data from Steem account data
Example:
let accountMetaData = accountMeta(accountData)
console.log(accountMetaData)
`
// profile
name: "...",
about: "...",
avatar: "..."
username: "...",
location: "...",
reputation: "...",
// details
id: "...",
created: "...",
proxy: "...",
post_count: "...",
voting_power: "...",
can_vote: "...",
mined: "...",
recovery_account: "...",
last_account_recovery: "...",
reset_account: "...",
comment_count: "...",
lifetime_vote_count: "..."
blockstack: "...",
pending_claimed_accounts: "...",
// wallet
steem: "...",
sbd: "...",
savings: "..."
`
public formatImage(data: string | object): string source
import {formatImage} from 'steem-utils/lib/format.js'
Extract the first image or potentially featured image for a post
Return:
| string | Returns the URL of first image for a post, meant to be used to extract featured images |
Example:
let post_featured_image_url = formatImage(postData.body || postData)
public formatPayout(post: object, fix: number): number source
import {formatPayout} from 'steem-utils/lib/format.js'
Formats a Steem post's payout, does not discriminate for pending or completed posts. Values are for SBD
Example:
let payout = formatPayout(postData)
public formatRep(reputation: string): number source
import {formatRep} from 'steem-utils/lib/format.js'
Formats a Steem account's reputation
Params:
| Name | Type | Attribute | Description |
| reputation | string | Steem reputation value |
Example:
let rep = formatRep(accountData.reputation)
let rep = formatRep(post.author_reputation)
console.log(accountData.reputation, rep)
`"23049917997434", 64`
public formatVests(account: object): number source
import {formatVests} from 'steem-utils/lib/format.js'
Formats a Steem account's vests
Params:
| Name | Type | Attribute | Description |
| account | object | Steem account's data, not username |
Example:
let vests = formatVests(accountData)
public formatVotes(raw: string[] | object, count: string, downvoted: string): object source
import {formatVotes} from 'steem-utils/lib/format.js'
Formats a Steem post's active votes
Will sort out removed votes, and order by weight
Will trim return array to specified or default count
voterCount
Example:
let votes = formatVotes(postData.active_votes || postData)
console.log(votes.votes)
`
["+ therising", "+ upmewhale", "+ appreciator", "+ smartsteem", "+ rocky1", "+ buildawhale",
"+ promobot", "+ jerrybanfield", "+ upmyvote""+ postpromoter", "...and 1741 others"]
`
public formatVotingPower(account: object): number source
import {formatVotingPower} from 'steem-utils/lib/format.js'
Formats a Steem account's voting power using the manarbar data
Params:
| Name | Type | Attribute | Description |
| account | object | Steem account data, not account username |
Example:
let votingPower = formatVotingPower(accountData)
public meta(data: object, config: object): object source
Returns meta data from Steem post or account data
Return:
| object | Returns object which contains meta data about the input account or post data.
For |
Example:
let metaData = meta(accountData || postData)
console.log(metaData)
public parse(content: content, config: object): object source
Parses a Steem post object or array of Steem post body strings or objects
Params:
| Name | Type | Attribute | Description |
| content | content | Steem post data |
|
| config | object | config for meta. The default is rendererDefaults |
Return:
| object | Returns object which contains meta data about the input post data See parsePost for how single items are handled See parsePosts for how items in array are handled |
public parsePost(content: object | string, options: object): object | string source
import {parsePost} from 'steem-utils/lib/parse.js'
Parses a Steem post object or body string
Example:
let parsed = parse(postData, {meta: {all: true}})
console.log(parsed)
`
image: "...",
summary: "...",
rep: "...",
votes: "...",
payout: "...",
paid: "...",
html: "...",
... // all other post object data variables remain untouched
` *
let parsed = parse(postData)
console.log(parsed)
`
html: "...",
... // all other post object data variables remain untouched
`
let parsed = parse(postData.body)
console.log(parsed)
`
"...",
`
public async parsePosts(content: array, options: object): array source
import {parsePosts} from 'steem-utils/lib/parse.js'
Parses multiple Steem post objects or body strings
Params:
| Name | Type | Attribute | Description |
| content | array | Array of Steem post data objects or body strings |
|
| options | object | config for meta. The default is rendererDefaults |
Return:
| array | Returns array of objects or strings of parsed body based on config options. See parsePost for how each single item in the array in handled |
Example:
let parsed = await parse(postsData)
public postMeta(data: object, config: object): object source
import {postMeta} from 'steem-utils/lib/meta.js'
Returns meta data from Steem post data
Example:
let postMetaData = postMeta(postData)
console.log(postMetaData)
`
title: "...",
summary: "..."
payout: "...",
image: "...",
created: "...",
comments_count: "...",
votes_count: "..."
`
public sortVotes(votes: object | array): object source
import {sortVotes} from 'steem-utils/lib/sort.js'
Returns an object of sorted Steem votes by upvotes, downvotes and removedvotes
Params:
| Name | Type | Attribute | Description |
| votes | object | array | Steem post data object or active_votes array |
Example:
let sort = sortVotes(postData || postData.active_votes)
console.log(sort)
`
{upVotes: [...], downVotes: [...], removedVotes: [...]}
`
public validateAccount(username: string): string | boolean source
import {validateAccount} from 'steem-utils/lib/validate.js'
Validates a Steem account username
Params:
| Name | Type | Attribute | Description |
| username | string | Steem account username |
Example:
let valid = validateAccount('la$tkiller')
console.log(valid)
`
Invalid account
`
let valid = validateAccount('lastkiller')
console.log(valid)
`
true
`
public voteStats(votes: object | array): object source
import {voteStats} from 'steem-utils/lib/stats.js'
Returns stats about a Steem votes object
Params:
| Name | Type | Attribute | Description |
| votes | object | array | Steem post data object or active_votes array |
Example:
let stats = voteStats(postData || postData.active_votes)
console.log(stats)
`
{total: "...", upVotes: "...", downVotes: "...", removedVotes: "..."}
`


Your web browser must have JavaScript enabled in order for this application to display correctly.
Latency
Count


Your personal data is very valuable. Unfortunately you have less and less control over this data. Especially data about your health. There are a number of large worldwide initiatives that suggest the idea to store this type of data in the cloud. Not just of individuals, but on a national and even on European level. Meaning all citizens. You don't have much choice. Hospitals, researchers, insurance companies and tech companies making the choice for you.
I believe users need a choice. Maybe you don't want your data in a cloud. Maybe you want your data close and under your direct control. Allowing you to share want you think is ok. A free, open and controllable box, compatible with those large initiatives, but where the user is in control of his/her own data. I like to call this box the Digital Personal Locker. In this talk I'll explain what it is, why it's necessary and how you can join the initiative. I also will show the technical design and hope for critical discussion with you about this! Feedback about what's missing or plain wrong is very very welcome.
Right now I'm gathering the people that are already doing something similar. Think about the Freedombox, the WhiteBox and connecting these people with organisations like the SIDN, the Dutch Tech Center for Life Sciences, NLnet and a group of people who don't want their data stored in Philips - SalesForce eHealth cloud (yes you read that correctly, your health data in a US based cloud of a marketing company!).
Hope to see you at the presentation and please give feedback and be critical. We need to do this right, open and secure.
CIA - Confidentiality - Integrity - Availability


Touch Events: Multi-touch tests
Touch this box with one finger, then another one...
...then drag to this box and lift your fingers.


This uses an asterisk to select all elements in the page.
* { text-transform: lowercase; } is used in this page.
Normal CSS selection includes these types:
Identifier selection is done by specifying an id attribute value, prefixed with a # symbol,
such as
#zLevelOne { background-color: red; z-index: 1; }
Class selection is done by specifying a class attribute value, prefixed with a dot,
such as
.stretch-words { word-spacing: 5mm; }
Element selection is done by specifying an element, with no prefix,
such as
body { font-family: Arial, Helvetica, Verdana, sans-serif; }
These technique work properly in Internet Explorer.
You can target CSS styling by specifying elements which are direct children of other element types.
This is text inside a span, inside a paragraph, inside a div.
The style rule div > p > span { font-style: italic; } is applied here.
You can also target styling to elements which are direct siblings of other elements.
For example, this is text inside an em, which is right next to a span in the source.
The style rule span + em { text-decoration: underline; } is applied here.
Notice that this rule also caught the emphasized "much" in the text at the top of the page, where the span and em are separated by other unmarked-up text.
You can target styling by limiting it to elements with certain attributes defined.
Here's a paragraph with a custom attribute called myAttribute. There is an in-page CSS style definition for it, as follows: p[myAttribute] { background-color: orange; }
Note that, at least in Firefox, you can even select based on the value of the attribute. For example, p[myAttribute="myValue"] works as expected. Further, using ~=, you can specify the existence of at least the given value, such as if you have a paragraph with mutliple classes declared, one of which is "targeted", you can use a selector like this p[class~=targeted]
Finally, you can also target styling to elements with a specific combination of classes.
This technique seems to work properly, at least for the most part, in Internet Explorer.
This paragraph has these three classes declared: "spinal tap rules"
The style rule p.spinal.tap.rules { text-tranform: uppercase; } is applied here.
Note that the order of the values is not important, and the target element can have more classes than are specified in the selector, as well.


---
layout: post
authors: ["Anelda van der Walt"]
title: "June 10-16, 2015: Software Carpentry is Saving Time, Lessons Version 5.4, Greg's Time, Our Project List, and a Lesson on Reproducible Research."
date: 2015-06-16
time: "19:00:00"
tags: ["Community"]
---
Highlights
-
Software Carpentry get more done in less time is the latest publication about
Software Carpentry and the impact it's having on research. It reports research done by Alexandra Simperler
and is available at arXiv.
-
Version 5.4 of our lessons is currently in the
pipeline and due for release in the middle of August.
Please join the discussions and participate in addressing new and existing issues to help us reach our next milestone.
-
Over the last few months a lot has improved in the way
Software Carpentry operates. Greg Wilson revisited some changes and the impact on how his time is spent six months after
election of the Steering Committee.
-
Do you want to know how you can help to move Software Carpentry forward?
Take a look at our project list or get in touch. There are loads of opportunities for people with a wide variety of skills.
Resources
Details
-
Software Engineering in Science is a
new book being compiled under the guidance of Jeffrey Carver. The call for chapters closed on 15 June and chapter invitations
should be sent out by 1 July.
-
Greg Wilson wrote a post about the pain caused by Norway — or rather,
what happens when you use the abbreviation 'no' in YAML.
-
Fan Young posted a comprehensive review of the
workshop at the National Cancer Institute.
She provides some tips that may be very helpful for others running workshops at government institutes.
-
Feedback is now also available from the
remote workshop ran in South Africa
in May. The post presents the experience from both the viewpoint of the remote instructor (Laurent Gatto)
and the local instructors (David Merand, Anelda van der Walt) and shows again that remote workshops can be run successfully.
-
A paper published in Nature in April underscores the uniqueness of
data analysis procedures.
-
Workshops were run at the National Institutes of Health and University of Melbourne.
-
Several workshops have been confirmed for the next few months.
Upcoming workshops can be viewed on our website.
Newly added workshops are indicated with "*".
-
June:
University of Cambridge,
Materials Physics Center - University of the Basque Country,
University of Connecticut,
University of Connecticut Storrs,
University of St Andrews,
NeSI - Otago Region Workshop,
Universidade Federal do Ceara,
Virginia Tech*,
California Institute of Technology,
Pennsylvania State University,
The Jackson Laboratory,
NeSI - Palmerston North Region Workshop,
Utrecht University,
Georgia Institute of Technology,
Johns Hopkins University,
University of Washington,
Women in Science and Engineering, University of Toronto*,
Yonsei University*
-
July:
The University of Queensland,
SciPy 2015,
West Vancouver Memorial Library,
The University of Queensland - AMOS sciences,
SAP Offices in Feltham,
University of Cape Town,
Hospital for Sick Children,
Curtin University,
Harvard University
Repository Activity
| Project | Issues | Pull Requests |
| Opened | Closed | Comments | Opened | Closed | Comments |
| shell-novice | 5 | 9 | 33 | 3 | 10 | |
| git-novice | 1 | | 17 | 4 | 4 | |
| hg-novice | 1 | | | 1 | | |
| sql-novice-survey | 1 | | 2 | 2 | 2 | |
| python-novice-inflammation | 1 | | 7 | 3 | | |
| r-novice-inflammation | 1 | | 1 | 3 | 1 | |
| matlab-novice-inflammation | 1 | | | 2 | | |
| slideshows | | | | | | |
| instructor-training | | | | | | |
| amy | 1 | 13 | 90 | 13 | 9 | 42 |
| site | 2 | | 6 | 6 | 5 | 1 |


I sometimes can fell stereotype threat, and it affacted my achievement. I believe everyone will meet stereotype threat in his life, and it sometimes didn't do a big deal, but sometimes affact achievements much.
I feel stereotype threat when I work with people who speak very fast.
For example, I am always silent when I talk with someone who speaks very fast. I feel I cannot catch him and cannot follow his topic well. However, actaully, I express myself worth than what I should be.
Another time is when I did a project in campus. The professor spoke very fast, and then I feel hard to say anything. Then I did the project worth than I should do.
Stereotype threat is always affacting us with our feeling. Even sometimes, we didn't realize it. I believe increase confidence or self-affirmation is important and necessary for reduce stereotype threat.
In DBC learning, it's really possible to meet stereotype threat. Therefore, I hope all of us can encourage ourselves self-affirmation to reduce stereotype threat so that we can performance like we shoule do.


[page:Object3D] →
[name]
A line or a series of lines.
Constructor
[name]( [page:Geometry geometry], [page:Material material], [page:Integer type] )
geometry — Vertices representing the line segment(s).
material — Material for the line. Default is [page:LineBasicMaterial LineBasicMaterial].
type — Connection type between vertices. Default is LineStrip.
If no material is supplied, a randomized line material will be created and assigned to the object.
Also, if no type is supplied, the default (LineStrip) will be used).
Properties
.[page:Geometry geometry]
Vertices representing the line segment(s).
.[page:Material material]
Material for the line.
.[page:Integer type]
Possible values: LineStrip or LinePieces. LineStrip will draw a series of segments connecting each point (first connected to the second, the second connected to the third, and so on and so forth); and LinePieces will draw a series of pairs of segments (first connected to the second, the third connected to the fourth, and so on and so forth).
In OpenGL terms, LineStrip is the classic GL_LINE_STRIP and LinePieces is the equivalent to GL_LINES.
Source
[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]


Created by Samuel Martins (02-17-2021) https://github.com/slunart https://www.linkedin.com/in/slmartins ———————————————————– Forti AP is monitored through FortiGate, so you need to apply this template to the Fortigate device. Originally based on template: “Fortigate SNMP SSLVPN/FortiAP Manged by Fortigate WiFi Controller template” created by Vadim Portnoy. Source: https://share.zabbix.com/network_devices/fortigate/fortigate-snmp-sslvpn-fortiap-manged-by-fortigate-wifi-controller-template My improvements: - More items monitored. - Items’ name shorted - Interval time of items modified - Trigged added - Graphics Prototype added
Template to monitor Fortinet APs. Forti AP is monitored through FortiGate, so you need to apply this template to the Fortigate device.
Originally based on template: “Fortigate SNMP SSLVPN/FortiAP Manged by Fortigate WiFi Controller template” created by Vadim Portnoy. Source: https://share.zabbix.com/network_devices/fortigate/fortigate-snmp-sslvpn-fortiap-manged-by-fortigate-wifi-controller-template
My improvements:
Important MIBs used to create this template:
Data Sheet FortiAP:
https://www.fortinet.com/content/dam/fortinet/assets/data-sheets/fortiap-series.pdf
Samuel Martins
There are no macros links in this template.
There are no template links in this template.
| Name | Description | Type | Key and additional info |
|---|---|---|---|
| Fortigate Wifi Access Points |
-
 | SNMP agent |
fgWcWtpSessionWtpId
Update: 30s
 |
| Name | Description | Type | Key and additional info |
|---|---|---|---|
| Name of this WTP $1 |
-
 | SNMP agent |
fgWcWtpConfigWtpName[{#SNMPVALUE}]
Update: 300s

LLD
 |
| Session Connection State of this WTP $1 |
-
 | SNMP agent |
fgWcWtpSessionConnectionState[{#SNMPVALUE}]
Update: 60s

LLD
 |
| Base Mac Address of this WTP $1 |
-
 | SNMP agent |
fgWcWtpSessionWtpBaseMacAddress[{#SNMPVALUE}]
Update: 1h

LLD
 |
| Number of bytes received by this WTP $1 |
-
 | SNMP agent |
fgWcWtpSessionWtpByteRxCount[{#SNMPVALUE}]
Update: 60s

LLD
 |
| Number of bytes transmitted by this WTP $1 |
-
 | SNMP agent |
fgWcWtpSessionWtpByteTxCount[{#SNMPVALUE}]
Update: 60s

LLD
 |
| CPU usage of a WTP (percentage) $1 |
-
 | SNMP agent |
fgWcWtpSessionWtpCpuUsage[{#SNMPVALUE}]
Update: 60s

LLD
 |
| Total physical memory (RAM) installed (KB) $1 |
-
 | SNMP agent |
fgWcWtpSessionWtpMemoryCapacity[{#SNMPVALUE}]
Update: 1h

LLD
 |
| Current memory usage of a WTP (percentage) $1 |
-
 | SNMP agent |
fgWcWtpSessionWtpMemoryUsage[{#SNMPVALUE}]
Update: 60s

LLD
 |
| Profile Name of this WTP $1 |
-
 | SNMP agent |
fgWcWtpSessionWtpProfileName[{#SNMPVALUE}]
Update: 1h

LLD
 |
| Number of clients currently connected to this WTP $1 |
-
 | SNMP agent |
fgWcWtpSessionWtpStationCount[{#SNMPVALUE}]
Update: 60s

LLD
 |
| Sw Version of this WTP $1 |
-
 | SNMP agent |
fgWcWtpSessionWtpSwVersion[{#SNMPVALUE}]
Update: 1h

LLD
 |
| Uptime of this WTP $1 |
-
 | SNMP agent |
fgWcWtpSessionWtpUpTime[{#SNMPVALUE}]
Update: 60s

LLD
 |
| Name | Description | Expression | Priority |
|---|---|---|---|
| The WTP {#SNMPVALUE} Session Connection State is not OnLine |
-
 |
Expression: {SNMP Fortigate Wifi Access Points:fgWcWtpSessionConnectionState[{#SNMPVALUE}].last(#3)}<>2

Recovery expression:
 | high |
| The WTP {#SNMPVALUE} Session Connection State is not OnLine (LLD) |
-
 |
Expression: {SNMP Fortigate Wifi Access Points:fgWcWtpSessionConnectionState[{#SNMPVALUE}].last(#3)}<>2

Recovery expression:
 | high |
Created by Samuel Martins (02-17-2021) https://github.com/slunart https://www.linkedin.com/in/slmartins ———————————————————– Forti AP is monitored through FortiGate, so you need to apply this template to the Fortigate device. Originally based on template: “Fortigate SNMP SSLVPN/FortiAP Manged by Fortigate WiFi Controller template” created by Vadim Portnoy. Source: https://share.zabbix.com/network_devices/fortigate/fortigate-snmp-sslvpn-fortiap-manged-by-fortigate-wifi-controller-template My improvements: - More items monitored. - Items’ name shorted - Interval time of items modified - Trigged added - Graphics Prototype added
Template to monitor Fortinet APs. Forti AP is monitored through FortiGate, so you need to apply this template to the Fortigate device.
Originally based on template: “Fortigate SNMP SSLVPN/FortiAP Manged by Fortigate WiFi Controller template” created by Vadim Portnoy. Source: https://share.zabbix.com/network_devices/fortigate/fortigate-snmp-sslvpn-fortiap-manged-by-fortigate-wifi-controller-template
My improvements:
Important MIBs used to create this template:
Data Sheet FortiAP:
https://www.fortinet.com/content/dam/fortinet/assets/data-sheets/fortiap-series.pdf
Samuel Martins
There are no macros links in this template.
There are no template links in this template.
| Name | Description | Type | Key and additional info |
|---|---|---|---|
| Fortigate Wifi Access Points |
-
 | SNMP agent |
fgWcWtpSessionWtpId
Update: 30s
 |
| Name | Description | Type | Key and additional info |
|---|---|---|---|
| Name of this WTP $1 |
-
 | SNMP agent |
fgWcWtpConfigWtpName[{#SNMPVALUE}]
Update: 300s

LLD
 |
| Session Connection State of this WTP $1 |
-
 | SNMP agent |
fgWcWtpSessionConnectionState[{#SNMPVALUE}]
Update: 60s

LLD
 |
| Base Mac Address of this WTP $1 |
-
 | SNMP agent |
fgWcWtpSessionWtpBaseMacAddress[{#SNMPVALUE}]
Update: 1h

LLD
 |
| Number of bytes received by this WTP $1 |
-
 | SNMP agent |
fgWcWtpSessionWtpByteRxCount[{#SNMPVALUE}]
Update: 60s

LLD
 |
| Number of bytes transmitted by this WTP $1 |
-
 | SNMP agent |
fgWcWtpSessionWtpByteTxCount[{#SNMPVALUE}]
Update: 60s

LLD
 |
| CPU usage of a WTP (percentage) $1 |
-
 | SNMP agent |
fgWcWtpSessionWtpCpuUsage[{#SNMPVALUE}]
Update: 60s

LLD
 |
| Total physical memory (RAM) installed (KB) $1 |
-
 | SNMP agent |
fgWcWtpSessionWtpMemoryCapacity[{#SNMPVALUE}]
Update: 1h

LLD
 |
| Current memory usage of a WTP (percentage) $1 |
-
 | SNMP agent |
fgWcWtpSessionWtpMemoryUsage[{#SNMPVALUE}]
Update: 60s

LLD
 |
| Profile Name of this WTP $1 |
-
 | SNMP agent |
fgWcWtpSessionWtpProfileName[{#SNMPVALUE}]
Update: 1h

LLD
 |
| Number of clients currently connected to this WTP $1 |
-
 | SNMP agent |
fgWcWtpSessionWtpStationCount[{#SNMPVALUE}]
Update: 60s

LLD
 |
| Sw Version of this WTP $1 |
-
 | SNMP agent |
fgWcWtpSessionWtpSwVersion[{#SNMPVALUE}]
Update: 1h

LLD
 |
| Uptime of this WTP $1 |
-
 | SNMP agent |
fgWcWtpSessionWtpUpTime[{#SNMPVALUE}]
Update: 60s

LLD
 |
| Name | Description | Expression | Priority |
|---|---|---|---|
| The WTP {#SNMPVALUE} Session Connection State is not OnLine |
-
 |
Expression: last(/SNMP Fortigate Wifi Access Points/fgWcWtpSessionConnectionState[{#SNMPVALUE}],#3)<>2

Recovery expression:
 | high |
| The WTP {#SNMPVALUE} Session Connection State is not OnLine (LLD) |
-
 |
Expression: last(/SNMP Fortigate Wifi Access Points/fgWcWtpSessionConnectionState[{#SNMPVALUE}],#3)<>2

Recovery expression:
 | high |
Created by Samuel Martins (02-17-2021) https://github.com/slunart https://www.linkedin.com/in/slmartins ———————————————————– Forti AP is monitored through FortiGate, so you need to apply this template to the Fortigate device. Originally based on template: “Fortigate SNMP SSLVPN/FortiAP Manged by Fortigate WiFi Controller template” created by Vadim Portnoy. Source: https://share.zabbix.com/network_devices/fortigate/fortigate-snmp-sslvpn-fortiap-manged-by-fortigate-wifi-controller-template My improvements: - More items monitored. - Items’ name shorted - Interval time of items modified - Trigged added - Graphics Prototype added
Template to monitor Fortinet APs. Forti AP is monitored through FortiGate, so you need to apply this template to the Fortigate device.
Originally based on template: “Fortigate SNMP SSLVPN/FortiAP Manged by Fortigate WiFi Controller template” created by Vadim Portnoy. Source: https://share.zabbix.com/network_devices/fortigate/fortigate-snmp-sslvpn-fortiap-manged-by-fortigate-wifi-controller-template
My improvements:
Important MIBs used to create this template:
Data Sheet FortiAP:
https://www.fortinet.com/content/dam/fortinet/assets/data-sheets/fortiap-series.pdf
Samuel Martins
There are no macros links in this template.
There are no template links in this template.
| Name | Description | Type | Key and additional info |
|---|---|---|---|
| Fortigate Wifi Access Points |
-
 | SNMP agent |
fgWcWtpSessionWtpId
Update: 30s
 |
| Name | Description | Type | Key and additional info |
|---|---|---|---|
| Name of this WTP $1 |
-
 | SNMP agent |
fgWcWtpConfigWtpName[{#SNMPVALUE}]
Update: 300s

LLD
 |
| Session Connection State of this WTP $1 |
-
 | SNMP agent |
fgWcWtpSessionConnectionState[{#SNMPVALUE}]
Update: 60s

LLD
 |
| Base Mac Address of this WTP $1 |
-
 | SNMP agent |
fgWcWtpSessionWtpBaseMacAddress[{#SNMPVALUE}]
Update: 1h

LLD
 |
| Number of bytes received by this WTP $1 |
-
 | SNMP agent |
fgWcWtpSessionWtpByteRxCount[{#SNMPVALUE}]
Update: 60s

LLD
 |
| Number of bytes transmitted by this WTP $1 |
-
 | SNMP agent |
fgWcWtpSessionWtpByteTxCount[{#SNMPVALUE}]
Update: 60s

LLD
 |
| CPU usage of a WTP (percentage) $1 |
-
 | SNMP agent |
fgWcWtpSessionWtpCpuUsage[{#SNMPVALUE}]
Update: 60s

LLD
 |
| Total physical memory (RAM) installed (KB) $1 |
-
 | SNMP agent |
fgWcWtpSessionWtpMemoryCapacity[{#SNMPVALUE}]
Update: 1h

LLD
 |
| Current memory usage of a WTP (percentage) $1 |
-
 | SNMP agent |
fgWcWtpSessionWtpMemoryUsage[{#SNMPVALUE}]
Update: 60s

LLD
 |
| Profile Name of this WTP $1 |
-
 | SNMP agent |
fgWcWtpSessionWtpProfileName[{#SNMPVALUE}]
Update: 1h

LLD
 |
| Number of clients currently connected to this WTP $1 |
-
 | SNMP agent |
fgWcWtpSessionWtpStationCount[{#SNMPVALUE}]
Update: 60s

LLD
 |
| Sw Version of this WTP $1 |
-
 | SNMP agent |
fgWcWtpSessionWtpSwVersion[{#SNMPVALUE}]
Update: 1h

LLD
 |
| Uptime of this WTP $1 |
-
 | SNMP agent |
fgWcWtpSessionWtpUpTime[{#SNMPVALUE}]
Update: 60s

LLD
 |
| Name | Description | Expression | Priority |
|---|---|---|---|
| The WTP {#SNMPVALUE} Session Connection State is not OnLine |
-
 |
Expression: last(/SNMP Fortigate Wifi Access Points/fgWcWtpSessionConnectionState[{#SNMPVALUE}],#3)<>2

Recovery expression:
 | high |
| The WTP {#SNMPVALUE} Session Connection State is not OnLine (LLD) |
-
 |
Expression: last(/SNMP Fortigate Wifi Access Points/fgWcWtpSessionConnectionState[{#SNMPVALUE}],#3)<>2

Recovery expression:
 | high |