When a DBI call fails, the error is not in $!. See the DBI docs.
There's an option to connect() that will have DBI provide more error information to you. See the DBI docs.
I don't see you issuing a disconnect, so perhaps it's possible to reuse $dbh, and avoid reconnecting from within print_form.
Arrange to print the Content-type: header before you might have to issue error message.
use CGI; and use the routines it provides to help you print the content header and HTML.
Are you sure you aren't off-by-one when indexing into @options ? I would think that the string for "Option 1" would be at $options[0], not $options[1].
You're embedding entirely too many "magic numbers" (including an IP address and background/font colors). That makes using and changing the script error-prone. Lift these values out into a set of configuration variables at the top of the script.