Эти две структуры используются везде, где надо передать интернет-адрес. В памяти struct sockaddr_in располагается так же, как и struct sockaddr, и можно спокойно кастовать их туда и обратно без всякого вреда, кроме возможного конца света.
Шучу про конец света, конечно... если он наступит, когда ты скастуешь struct sockaddr_in* в struct sockaddr*, можешь быть уверен, что это просто совпадение и не стоит об этом беспокоиться.
Имея это ввиду, помни, что когда функция берет struct sockaddr*, можешь вместо него передать обкастованный struct sockaddr_in*.
Есть еще поле sin_zero, кое-кто говорит, что его нужно обнулять. А еще кое-кто об этом умалчивает (например, документация Linux), и по-видимому обнуление поля совсем необязательно. Впрочем, если тебе хочется, можешь обнулить его с помощью memset().
А вот структура in_addr отличается от системы к системе. Кое-где это union с разными #define'ами и всяким бредом. Но ты вполне можешь использовать только поле s_addr и быть спокойным.
С IPv4, который используется повсеместно в 2005 году, struct s_addr - 4-байтовое число, хранящее IP-адрес.